feat: Phase 1 of allowScripts opt-in install-script policy (#9360)#9415
Merged
Conversation
Implements Phase 1 of [npm/rfcs#868](npm/rfcs#868), which makes dependency install scripts opt-in. **Install behaviour is unchanged.** Scripts still run as they always have. The only Phase 1 user-visible change is one advisory block at the end of `npm install` listing packages whose install scripts haven't been reviewed via the new `allowScripts` field in `package.json`. A future release will turn that advisory into an actual block. - `allowScripts` field in `package.json`, read at install time - Three new configs: `allow-scripts`, `strict-script-builds`, `dangerously-allow-all-scripts`. The latter two are no-ops in this release. They're registered so projects can pin them in tooling ahead of the release that flips the default. - `npm approve-scripts` and `npm deny-scripts` commands, with the RFC's asymmetric pin rule (approves can pin, denies are always name-only) - Advisory warning during `npm install`, `ci`, `update`, and `rebuild`. `npm exec` / `npx` consult only the user/global `.npmrc` layer per the RFC, with the policy threaded through libnpmexec for Phase 2 enforcement. - Identity matcher in `@npmcli/arborist` covering registry, git, file, and remote tarballs. Registry identity is derived from the lockfile's resolved URL (via `versionFromTgz`), never from `node.packageName` or `node.version`. Those getters read the installed tarball's `package.json` and can be forged. - Aliases match against the underlying registered package, not the alias name. `trusted@npm:naughty@1.0.0` is approved by writing `naughty`, not `trusted`. Holds even under `omitLockfileRegistryResolved`, where the install location alone (`node_modules/trusted`) would be misleading. The underlying name is derived from the incoming edge's alias `subSpec`. - Bundled deps with install scripts are flagged as unreviewed and filtered out of `npm approve-scripts --all` and positional matches. Per RFC they cannot be allowlisted in Phase 1. - Warning when a non-root workspace declares its own `allowScripts` - Actual blocking. The matcher exists and the policy is threaded through to arborist, but `arb.rebuild()`'s build set still runs everything. Phase 2 will gate `#addToBuildSet` on the matcher. - A safe allowlist syntax for bundled deps. The RFC notes a candidate `parent@1.2.3 > bundled-name` form for a follow-up. Refs: npm/rfcs#868 (cherry picked from commit 7068d42)
ff10c16 to
ab21af4
Compare
kchindam-infy
approved these changes
May 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backports #9360 to v11.