npm supply-chain security audit
Audit the current repo for npm supply-chain security issues, present findings to the user, and apply fixes only after confirmation.
Step 1 – Detect the package manager
Check which package manager(s) are in use:
- -> npm
- -> Aube
- -> pnpm
- + -> Yarn Berry; without -> Yarn Classic
- or -> Bun
- field in confirms the PM and version
Use the
field to determine the version. If not present, run the PM's
command. The version is needed for checks that depend on minimum PM versions (e.g. pnpm 10+, pnpm 11+, npm 11.10+, Yarn Berry 4.10+, Bun 1.3+).
pnpm 11 ships several supply-chain protections on by default (
,
,
) and only reads pnpm-specific settings from
(or
~/.config/pnpm/config.yaml
), not from
. Many checks below differ between pnpm 10 and pnpm 11+.
If no lockfile exists, default to npm.
Step 2 – Audit
Work through the checks below. For each one, check the current state and record whether it passes or needs a fix. Do NOT make any changes yet.
2.1 Lockfile committed
If no lockfile exists (
,
,
,
,
,
), warn the user they should run their package manager's install command and commit the lockfile. Do NOT run install yourself.
2.2 Block lifecycle scripts
pnpm 10+ – blocks lifecycle scripts by default. Check that
does NOT set
dangerouslyAllowAllBuilds: true
. If it does, warn the user. pnpm 11+ additionally enables
by default, so installs error (rather than just warn) when a dependency wants to run a build script that isn't in the allowlist – verify it has not been disabled in
.
pnpm <= 9 – ensure
contains
.
Yarn Classic (v1) – ensure
contains
.
Yarn Berry (v2+) – ensure
contains:
Bun – blocks lifecycle scripts by default. No action needed.
Aube – blocks lifecycle scripts by default. Check that
does NOT set
dangerouslyAllowAllBuilds: true
. If it does, warn the user.
2.3 Build script allowlists
When lifecycle scripts are blocked, some packages legitimately need build scripts. Check the lockfile for packages that require builds:
- pnpm – look for entries with in
- npm – look for in
- Yarn Berry – look for or build-related metadata in
- Bun – check for packages with lifecycle scripts
Compare the list of packages that require builds against the current allowlist. Report any that are missing, but do NOT suggest adding them blindly – the user must verify each package is trusted before allowlisting it. Only well-known packages from reputable maintainers (e.g.
,
,
) should be considered.
The allowlist setting per package manager:
pnpm 11+ –
map in
. This replaces
,
onlyBuiltDependenciesFile
,
, and
, which are no longer supported:
yaml
allowBuilds:
esbuild: true
core-js: false
yaml
onlyBuiltDependencies:
- esbuild
json
"dependenciesMeta": {
"esbuild": { "built": true }
}
json
"trustedDependencies": ["esbuild"]
2.4 Release-age cooldown
Check if a release-age cooldown is configured. If not, recommend adding one. If already configured, note the current value. When presenting findings, advise the user that 3 days is a good minimum. Mention that 7 days provides stronger protection but slows down updates.
The setting per package manager:
npm 11.10+ –
in
(value in days):
pnpm 10.16+ –
in
(value in minutes):
pnpm 11+ – defaults to
(1 day). The repo is already protected, but recommend overriding to a stronger value (e.g.
for 3 days or
for 7 days). Also verify the default has not been disabled with
.
Also check if
contains a
setting – this is a common mistake. pnpm only reads this setting from
, not
(and pnpm 11+ does not read any pnpm-specific settings from
at all). If found, warn the user and suggest moving it to
.
Yarn Berry 4.10+ –
in
(value in minutes):
Bun 1.3+ –
in
(value in seconds):
toml
[install]
minimumReleaseAge = 259200
Aube – defaults to 1440 minutes (1 day).
in
(value in minutes):
2.5 Block exotic subdeps (pnpm / Aube)
pnpm 10 – ensure
contains:
pnpm 11+ / Aube – defaults to true. Verify it has not been explicitly disabled in
/
.
This prevents transitive dependencies from using git or tarball URLs.
2.6 Trust policy (pnpm / Aube)
pnpm / Aube – ensure
or
contains:
yaml
trustPolicy: no-downgrade
This blocks packages whose trust level has decreased.
2.7 Hardened mode (Yarn Berry only)
If using Yarn Berry, ensure
contains:
This validates the lockfile against the registry.
2.8 Dependency update cooldown (Renovate / Dependabot)
Check if the repo uses Renovate or Dependabot and whether a cooldown is configured.
Renovate – look for config in
,
,
,
,
,
, or a
key in
. Check if the
array includes any of the following (all of which include a 3-day npm cooldown):
"security:minimumReleaseAgeNpm"
"NitorCreations/renovate-config:recommended"
(the Nitor recommended preset extends )
Also check shared presets – if
references another custom preset (e.g.
"local>myorg/renovate-config"
), note that the cooldown may already be configured there and the user should verify.
If Renovate config exists but doesn't include any of the above presets, suggest adding
security:minimumReleaseAgeNpm
:
json
{ "extends": ["security:minimumReleaseAgeNpm"] }
Dependabot – look for
. Check if npm ecosystem entries have a
configured. If not, suggest adding:
yaml
cooldown:
default-days: 3
If neither Renovate nor Dependabot is configured, skip this check – don't add a dependency update tool unprompted.
Step 3 – Present findings
Present a summary of the audit results to the user:
- Start with a one-line summary count (e.g. "3 passing, 4 need fixes")
- List checks that already pass as bullet points (not numbered) – keep these brief
- List checks that need fixes, with the specific changes that would be made
- List any issues that require manual action (e.g. missing lockfile,
dangerouslyAllowAllBuilds
)
- When multiple fixes target the same file, show a combined preview of the full proposed file content at the end
- Do not use horizontal rules () – headings provide enough structure
IMPORTANT formatting rules – follow exactly:
- Use a numbered list for fixes. Put ALL explanation BEFORE the code block.
- Every proposed config change MUST be wrapped in a fenced code block using triple backticks and a language tag (e.g. yaml, json, toml, ini). RAW config text without triple-backtick fences is WRONG and hard to read.
- Indent code blocks with 3 spaces so they are nested inside the list item. This is critical – without the indent, the code block breaks out of the list and the numbering restarts (causing duplicate numbers like 1, 1, 2, 2).
- Leave a blank line before the opening triple backticks and after the closing triple backticks.
Then ask the user for confirmation before proceeding.
Step 4 – Apply fixes
After the user confirms, apply the agreed-upon changes. If the user wants to skip certain fixes, respect that. Summarize what was changed.