GitHub is tightening npm’s install-time security defaults. The June 9, 2026 changelog confirms that npm v12, expected in July 2026, will stop running several high-risk install behaviors unless you explicitly opt in.
That is a meaningful shift for engineering teams. Many projects depend on Git-sourced packages, HTTPS tarballs, or native modules that compile during npm install. Those workflows still work, but silent automatic execution is going away.
The timing is not accidental. npm supply chain attacks in 2026 have repeatedly abused install-time execution — from the TanStack Mini Shai-Hulud compromise and AntV worm wave to Phantom Gyp Miasma packages that weaponize binding.gyp during npm install. GitHub’s defaults target the same execution paths those campaigns relied on.
This guide explains what is changing, why GitHub made these defaults, and how to prepare before v12 lands in your CI pipelines and developer laptops.
Why GitHub is changing npm install defaults
Software supply chain attacks increasingly target the moment dependencies are fetched and executed, not just the registry metadata teams usually scan.
Recent incidents show attackers abusing:
- lifecycle scripts that run during install, even when teams think they disabled scripts — see Corgea’s analysis of TrapDoor’s multi-registry postinstall stealer and the node-ipc DNS exfiltration backdoor;
- non-registry dependency sources that bypass normal registry review;
- install-time configuration that can override tooling behavior before application code runs — including Phantom Gyp attacks that hijack implicit
node-gyp rebuildwithout advertising lifecycle scripts inpackage.json.
GitHub’s answer is a deny-by-default model for install-time code execution and non-registry resolution. Instead of trusting every dependency source and script automatically, npm v12 requires explicit approval.
That aligns with broader GitHub supply chain work in 2026, including staged publishing, expanded OIDC support for Dependabot, and the GitHub Actions security roadmap. The npm CLI changes focus on the workstation and CI install step, where a single malicious package can still execute code before your scanners run — the same window exploited in the Red Hat Cloud Services Miasma worm and the GitHub breach through a poisoned VS Code extension.
The three breaking changes in npm v12
Each change turns an automatic npm install behavior into an explicit opt-in.
1. --allow-git defaults to none
Today: npm install can resolve Git dependencies, including direct and transitive ones, from sources such as github:, gitlab:, git+https://, and bare owner/repo shorthands.
In v12: Git dependencies are blocked unless you pass --allow-git or configure it in .npmrc or package.json.
Why it matters: Git dependencies introduce a code-execution path where a dependency’s .npmrc can override the Git executable, even when you use --ignore-scripts. Blocking Git resolution by default closes that path.
Availability: Announced February 18, 2026. Available behind warnings in npm 11.10.0+.
2. --allow-remote defaults to none
Today: npm install can resolve dependencies from remote URLs, including HTTPS tarballs, for both direct and transitive dependencies.
In v12: Remote URL resolution is blocked unless you explicitly allow it with --allow-remote.
Why it matters: Remote tarballs bypass the npm registry’s publish controls and staged publishing protections. A compromised or typosquatted URL in a lockfile or transitive dependency can pull arbitrary code.
Availability: Flag introduced in npm 11.15.0+. Default change arrives in v12.
Not changing in v12: --allow-file and --allow-directory keep their current defaults. You can still set them to none today if you want stricter local-source controls.
3. allowScripts defaults to off
Today: npm install runs preinstall, install, and postinstall scripts from dependencies unless you pass --ignore-scripts.
In v12: Dependency lifecycle scripts do not run unless they are explicitly allowed in your project configuration.
Important details:
- This includes implicit
node-gyp rebuildfor packages withbinding.gypand no explicit install script. npm treats that rebuild as install-time execution, so it is blocked too. preparescripts from Git, file, and link dependencies are blocked the same way.- The allowlist is project-scoped and should be committed to
package.json.
Why it matters: Install scripts are one of the most abused execution paths in npm supply chain attacks. Malicious packages often do their damage in postinstall before application code loads — the TrapDoor campaign used ecosystem-specific install hooks across npm, PyPI, and Crates.io, while node-ipc stole credentials the moment a compromised version was required. Requiring an explicit allowlist turns install scripts from ambient trust into reviewed trust.
Availability: Warnings available in npm 11.16.0+.
How the new script approval workflow works
GitHub introduced npm approve-scripts and npm deny-scripts to manage the transition.
Step 1: Preview what would be blocked
On npm 11.16.0 or newer:
npm approve-scripts --allow-scripts-pending
This shows packages that would lose install-time script execution under the new defaults.
Step 2: Build your allowlist
Approve packages you trust:
npm approve-scripts <package-name>
Block packages you do not want running scripts:
npm deny-scripts <package-name>
The resulting configuration is written to package.json under the allowScripts field. Commit it like any other dependency policy.
Step 3: Run a normal install and read the warnings
Upgrade to npm 11.16.0+, run your usual install command, and review warnings. They tell you which behaviors v12 will block and which packages need explicit approval.
After you upgrade to v12, only approved scripts keep running. Anything left unapproved stops.
For npx and global installs, see GitHub’s allow-scripts config documentation.
What this means for common workflows
Native modules and node-gyp
Packages that compile native code during install are affected even when they do not define an explicit install script. If a dependency ships binding.gyp, npm runs an implicit node-gyp rebuild, which v12 blocks unless that package is on your allowlist.
That matters because attackers already abuse this path. The Phantom Gyp Miasma wave used a 157-byte binding.gyp to force command substitution during install across dozens of packages including @vapi-ai/server-sdk and ai-sdk-ollama. The dbmux compromise showed the same technique can run even when package.json does not advertise lifecycle scripts.
Teams using bcrypt, sharp, sqlite3, node-sass, or similar native dependencies should run npm approve-scripts --allow-scripts-pending early and confirm their CI images approve the packages they actually need.
GitHub shorthand dependencies
Dependencies declared as owner/repo or github:org/pkg will fail in v12 unless you allow Git sources:
npm install --allow-git=all
Or in .npmrc:
allow-git=all
Audit your package.json and lockfile for Git-sourced entries before v12. Many monorepos and internal tooling repos still pull packages this way.
Remote tarball dependencies
Dependencies installed from https:// tarball URLs need explicit remote permission:
npm install --allow-remote=all
Search lockfiles for resolved URLs that do not point at registry.npmjs.org or your private registry.
CI/CD pipelines
Most production pipelines should adopt a staged rollout:
- Pin npm to 11.16.0+ in CI and on developer machines.
- Run
npm ciornpm installand capture warnings. - Run
npm approve-scripts --allow-scripts-pendingand commit the allowlist. - Add explicit
--allow-gitor--allow-remoteflags only where your dependency graph requires them. - Test the same install command against a v12 prerelease before the July 2026 GA.
Pair this with the supply chain controls in Corgea’s developer machine hardening guide and GitHub Actions security checklist.
npm v12 preparation checklist
Use this checklist before v12 becomes your default npm version.
Inventory (do this first)
- List direct dependencies installed from Git, file paths, directories, or remote URLs.
- Search lockfiles for non-registry
resolvedURLs. - Identify packages with
preinstall,install,postinstall, orbinding.gyp. - Note which packages are dev-only versus production runtime dependencies.
Policy
- Decide whether Git and remote URL installs are allowed at all in your organization.
- Define who can approve install scripts (team lead, security, or platform engineering).
- Document the approval process in your internal dependency policy.
Tooling
- Upgrade local and CI npm to 11.16.0 or newer.
- Run
npm approve-scripts --allow-scripts-pendingon representative projects. - Commit the resulting
allowScriptsconfiguration inpackage.json. - Add
.npmrcor install flags for any required--allow-gitor--allow-remoteexceptions. - Pin npm version in CI (
.npmrcengine-strict,packageManagerfield, or setup-node action).
Validation
- Run a clean install in CI with warnings enabled and fix failures.
- Test Docker builds and release pipelines that run
npm ci. - Confirm native module builds still succeed after script approvals.
- Test against an npm v12 prerelease in a non-production branch.
Longer-term hardening
- Enable staged publishing for packages your team publishes.
- Pair staged publishing with trusted publishing (OIDC) for CI releases.
- Scan dependencies and lockfiles in pull requests with Corgea dependency scanning.
- Review install-time risk alongside Node.js security best practices.
Timeline and related GitHub changes
| Date | Change |
|---|---|
| Feb 2026 | --allow-git announced; default will change in v12 |
| May 2026 | Staged publishing GA; --allow-file, --allow-remote, --allow-directory flags ship in npm 11.15.0 |
| Jun 2026 | npm v12 breaking changes confirmed; allowScripts warnings in npm 11.16.0+ |
| Jul 2026 (est.) | npm v12 release with new security defaults |
These npm CLI changes complement registry-side controls. Staged publishing requires a maintainer with 2FA to approve packages before they become installable. Install-time controls reduce what untrusted packages can do when someone does install them.
Together, they move npm toward a model where publishing and installing both require explicit human or policy approval instead of implicit trust.
What teams should do this week
If you maintain Node.js applications or publish npm packages, start now rather than waiting for v12.
- Upgrade npm to 11.16.0+ on developer machines and in CI.
- Run your normal install and read every warning.
- Generate a script allowlist with
npm approve-scripts --allow-scripts-pending, then commit it. - Audit non-registry dependencies in
package.jsonand lockfiles. - Test one critical repo against npm v12 prerelease before the GA window.
The breaking changes are intentional. GitHub is closing install-time execution paths that attackers have repeatedly abused — the same paths visible across Corgea’s npm supply chain research. Teams that treat the migration as a dependency hygiene exercise, not just a version bump, will end up with smaller attack surface and clearer trust boundaries around third-party code.
Further reading
GitHub and npm documentation
- Upcoming breaking changes for npm v12 — GitHub Changelog announcement
- Staged publishing and new install-time controls for npm — Related May 2026 release
- npm approve-scripts documentation
- npm deny-scripts documentation
Corgea learn guides
- How to secure developer machines against supply chain attacks — Workstation hardening checklist
- GitHub Actions security checklist — CI/CD supply chain controls
- Node.js security best practices 2026 — Runtime and dependency hygiene
Corgea research on npm supply chain attacks
- TanStack Mini Shai-Hulud compromise — CI workflow abuse and OIDC token theft
- AntV Mini Shai-Hulud worm wave — Hundreds of malicious npm releases in one campaign
- Phantom Gyp Miasma on Vapi and ai-sdk-ollama —
binding.gypinstall-time command substitution - dbmux Phantom Gyp compromise — Implicit
node-gyp rebuildas malware loader - TrapDoor multi-registry crypto stealer — Postinstall hooks across npm, PyPI, and Crates.io
- node-ipc DNS exfiltration backdoor — Credential theft on package load
- Red Hat Cloud Services Miasma worm — Trusted publishing abuse
- GitHub breach via poisoned VS Code extension — Cascading supply chain from npm to internal repos