npm Supply Chain Attacks Hit GitHub: 2FA Approval Gate Now Blocks Stolen CI Tokens

Staged publishing in npm 11.15.0 requires a maintainer’s 2FA sign-off before any package version goes live, closing the CI/CD token-theft vector that handed attackers roughly 3,800 GitHub internal repositories.

NPM Package Manager
NPM Package Manager npmjs.com

GitHub shipped the developer security industry's most-requested registry control on May 22, 2026: staged publishing, now generally available for all npm packages. The feature inserts a mandatory two-factor authentication checkpoint between any publish command — automated or manual — and the moment a package version becomes downloadable by the rest of the world. Any developer who runs npm publish or npm stage publish now places their tarball in a staging queue; a human maintainer must separately authenticate with 2FA and issue an explicit approval before the package goes live.

The announcement landed the same week that security firm Socket disclosed TrapDoor, a new coordinated campaign across npm, PyPI, and Crates.io that deployed 34 malicious packages across 384 versions, targeting developers in cryptocurrency, decentralized finance, and AI. The overlap is not coincidental: staged publishing arrives at the peak of the most active supply chain attack campaign in the registry's history.

GitHub calls the new control "proof of presence" — evidence that a real, authenticated human reviewed and approved code before it reached developers. The approval step cannot be completed with automation credentials, OpenID Connect (OIDC) tokens, or any non-interactive path. Only a live 2FA challenge satisfies it.

How npm Staged Publishing Works in Practice

Under the previous model, a single npm publish command — from a developer's terminal or a CI/CD bot — immediately made a new package version installable worldwide. Staged publishing replaces that instant path with a two-step process.

Step one: the publisher runs npm stage publish from the package root, uploading the prebuilt tarball to a staging queue visible on npmjs.com and in the npm command-line interface. Step two: a maintainer — on a trusted device, authenticated with 2FA — runs npm stage approve or approves through the web interface. Until that second step happens, no consumer can install the staged version.

The commands npm stage list, npm stage view, npm stage approve, and npm stage reject all require interactive authentication and cannot be satisfied by OIDC tokens or granular access tokens. GitHub's recommended setup pairs staged publishing with trusted publishing using OIDC, configured as "stage-only": the CI/CD workflow can run npm stage publish but npm publish is rejected outright. Automation submits; a human approves.

For solo maintainers who already run npm publish locally with 2FA enabled, the workflow change is minimal. For large open-source projects that ship frequently from fully automated pipelines — the architecture that the TeamPCP threat group has exploited repeatedly across 2026 — staged publishing requires updating CI/CD configurations to use npm stage publish and designating a maintainer to handle approvals. The feature ships in npm CLI version 11.15.0. Teams using bulk trusted publishing configurations introduced in February 2026 can use those to migrate packages to staged workflows at scale.

npm Supply Chain Attacks: The Kill Chain Staged Publishing Targets

The context for this feature is one of the most destructive supply chain campaigns in npm's history. Since March 2026, a cybercrime group tracked by Google Threat Intelligence as UNC6780 and publicly known as TeamPCP has executed a cascading series of supply chain compromises across npm, PyPI, GitHub Actions, Docker Hub, and the VS Code Marketplace. Palo Alto Networks Unit 42 has tracked more than 500 poisoned packages across 20 documented attack waves.

The campaign's mechanism — documented across every wave — is the same: compromise one trusted tool, steal the CI/CD credentials stored in its runner memory, use those credentials to poison additional packages, and repeat. On May 11, TeamPCP published 84 malicious versions across 42 packages in the TanStack npm namespace in approximately six minutes, exploiting a combination of GitHub Actions cache poisoning and OIDC token extraction from runner memory. The TanStack postmortem confirmed the malicious versions carried valid SLSA Build Level 3 cryptographic provenance — the attestation organizations rely on to verify package integrity.

Credentials stolen in that wave were eventually used to push a backdoored version of Nx Console v18.95.0, a VS Code extension with 2.2 million installs. The poisoned build was live on Microsoft's Visual Studio Marketplace for 11 to 18 minutes. That window was enough: the extension landed on a GitHub employee's device. GitHub confirmed on May 19–20, 2026 that attackers exfiltrated roughly 3,800 internal repositories through the compromised extension.

Staged publishing directly addresses the mechanism at the center of every TeamPCP attack wave. In each case, automation tokens and CI credentials were the lever attackers used to push malicious code to the registry. By requiring a live 2FA challenge for final approval — something an attacker holding only a stolen automation token cannot pass — npm adds a gate that valid-but-stolen credentials cannot silently bypass.

What Staged Publishing Still Cannot Block

Nicholas C. Zakas, creator of the ESLint JavaScript linter and a longtime npm maintainer, has argued that credential hardening alone is insufficient. Staged publishing addresses the publication step, but not the period after a malicious package has been approved and is already circulating in the registry. Zakas has called for registry-side behavioral anomaly detection — flagging publishes from unusual geolocations, restricting lifecycle script additions to major version bumps, and requiring additional verification when release behavior deviates from historical patterns.

An attacker who gains full control of a maintainer's authenticated session, rather than only their automation tokens, could still approve a malicious staged release. The control closes a specific, heavily exploited attack pattern; it does not make npm impervious to insider attacks or fully compromised developer accounts.

GitHub has indicated it plans to expand trusted publishing support to additional CI/CD providers beyond GitHub Actions and GitLab, and will refine staged publishing based on community feedback.

New Install-Time Source Flags in npm 11.15.0

Alongside staged publishing, npm 11.15.0 also adds three new install-time source flags that let teams restrict where dependencies can be fetched from:

  • --allow-file: controls installs from local file paths and tarballs
  • --allow-remote: controls installs from remote URLs, including HTTPS tarballs
  • --allow-directory: controls installs from local directories

These join the existing --allow-git flag introduced in npm 11.10.0. Each flag accepts all (current default) or none, configurable via .npmrc or package.json. In npm CLI version 12, the --allow-git default will change from all to none — a signal that the registry is moving toward strict allowlists rather than permissive defaults.


Frequently Asked Questions

How does npm staged publishing work?

When a maintainer runs npm stage publish, the package tarball is placed in a staging queue rather than going live immediately. A human maintainer must then authenticate with two-factor authentication and issue an explicit approval — via the npm stage approve command or through npmjs.com — before the package becomes publicly installable. Automated CI/CD pipelines and OIDC tokens cannot complete the approval step.

What is the TeamPCP supply chain attack?

TeamPCP (tracked by Google Threat Intelligence as UNC6780) is a cybercrime group responsible for a cascading series of npm and PyPI supply chain attacks throughout 2026. The group compromises one trusted developer tool, steals CI/CD credentials from its runner memory, and uses those credentials to poison additional packages in a self-replicating loop. The campaign has compromised more than 500 packages across 20 documented waves and resulted in the exfiltration of roughly 3,800 of GitHub's internal repositories in May 2026.

How do I protect my npm packages from supply chain attacks?

Update to npm CLI 11.15.0, switch to npm stage publish for all releases, and configure trusted publishing with OIDC in stage-only mode so that direct npm publish commands from CI/CD are rejected. Rotate long-lived credentials — GitHub personal access tokens, npm tokens, and cloud keys stored in CI/CD runner environments — and set the new --allow-file, --allow-remote, and --allow-directory flags to none in .npmrc where non-registry dependency sources are not needed.

What npm CLI version includes staged publishing?

Staged publishing and the new install-time source flags are available in npm CLI version 11.15.0, released May 22, 2026. The npm stage command group — covering npm stage publish, npm stage approve, npm stage reject, and npm stage list — requires this version or newer.

ⓒ 2026 TECHTIMES.com All rights reserved. Do not reproduce without permission.

Join the Discussion