On June 9, GitHub announced the breaking changes coming in npm v12, estimated for July 2026. They are the most consequential security changes npm has shipped in years, and they all say the same thing: install-time trust stops being implicit.

  • Dependency install scripts stop running by default. preinstall, install, postinstall from dependencies need explicit approval in a committed allowScripts policy in package.json. Even native builds are included: a package with a binding.gyp gets blocked, because npm runs an implicit node-gyp rebuild for it.
  • Git dependencies stop resolving unless allowed via allow-git. The rationale is precise: a git dependency's own .npmrc can override the git executable, a code-execution path that survives --ignore-scripts.
  • Remote URL tarballs stop resolving unless allowed via allow-remote.

Everything is preparable today on npm 11.16.0+, where the new behavior runs in warning mode. If the pattern sounds familiar, it should: this is the model pnpm v11 shipped, arriving at the ecosystem's default package manager. After node-ipc in May, the AntV burst, and the Miasma worm in June, all of which entered through install-time execution, the default finally moved.

The new question: who reviewed the policy?

Explicit trust is a real improvement, and it relocates the problem rather than ending it. The policy lives in files the repository ships: allowScripts in package.json, allow-git and friends in a committed .npmrc. Which means a repo can weaken its own policy, for everyone who clones it, with one committed line:

dangerously-allow-all-scripts=true   # npm's own escape hatch, left committed

Or more quietly: an allowScripts approval written by name only, which approves every future version of a package instead of the version someone actually reviewed. Or allow-git=all pinned in .npmrc, carrying the relaxed behavior straight through the v12 upgrade.

This is the trust-layer pattern we keep running into: the artifact that grants trust is obeyed, not reviewed. Naming that layer was step one. npm v12 just added four new files worth of it.

What Aguara checks

Aguara's npm-policy analyzer reads package.json and the project .npmrc and flags install-trust decisions weakened below the npm v12 baseline:

RuleSeverityWhat it flags
NPM_DANGEROUS_ALL_SCRIPTS_001HIGHdangerously-allow-all-scripts=true: the documented migration escape hatch, bypassing the policy entirely
NPM_ALLOW_SCRIPTS_UNPINNED_001MEDIUMName-only allowScripts approvals (or allow-scripts-pin=false): tomorrow's compromised release inherits today's approval
NPM_ALLOW_GIT_RELAXED_001MEDIUMallow-git=all|root committed, pinning git resolution open against the v12 default
NPM_ALLOW_REMOTE_RELAXED_001MEDIUMallow-remote=all|root, same for remote tarballs

A missing setting never fires. A repo that simply runs npm's defaults stays clean; the analyzer reports only explicit choices that broaden trust. Every parser behavior was verified against real npm 11.16.0 rather than assumed, down to the details: a deny entry is never confused with an unpinned approval, an inline comment does not hide a live setting, repeated keys resolve the way npm resolves them, and a hand-typed wildcard that npm ignores stays silent.

Readiness, not just risk

There is a second half, and it is not about attacks. A project that depends on git sources or URL tarballs today will simply stop installing under npm v12 until someone grants the exceptions. Two INFO-level findings turn that into a migration list:

$ aguara scan .

INFO  package.json:14  NPM_GIT_INSTALL_TRUST_001
      dependencies.viz resolves from a git source.
      npm v12 will require an explicit allow-git exception.

INFO  package.json:15  NPM_REMOTE_INSTALL_TRUST_001
      dependencies.blob resolves from a remote URL tarball.
      npm v12 will require an explicit allow-remote exception.

INFO severity never fails a default CI gate: these findings inform the upgrade, they do not block it. The classification follows npm's actual install gates, which hold a few surprises we confirmed against the real tool: a repository URL on GitHub or GitLab is a git dependency even without a .git suffix, while an archive or release-download URL on the same host is a remote tarball, and a .git URL on an unknown host is remote unless it uses a git+ scheme.

Before install, before CI, before delegation

npm is making install-time trust explicit. Aguara helps teams review that trust before install, before CI runs it, and before an agent inherits it: the same scan covers the npm policy files, the pnpm posture, the lockfiles, and the agent configuration a repo ships.

$ aguara audit . --ci

One run, before anything executes. That is the point of the layer.

Is your repo ready for npm v12?

aguara scan . reviews the install-trust policy and lists the exceptions the upgrade will require.