Skip to content

Consider npm Staged Publishing — sole publisher + 230M weekly downloads #181

Description

@piiiico

cross-spawn has 230M weekly downloads and a single npm account with publish access.

That's not a fault — it's the reality of most successful npm packages. But it's the same structural profile that was exploited three times since March:

  • axios (Mar 30) — stolen npm token, malicious version pushed to latest instantly
  • TanStack (May 11) — GitHub Actions cache poisoning extracted OIDC tokens, 84 malicious versions in 6 minutes
  • @redhat-cloud-services (Jun 1) — compromised GitHub account triggered existing CI, 32 packages with valid SLSA provenance

npm's Staged Publishing (GA May 2026) adds a human 2FA gate between npm publish and the version going live on latest. If a credential is stolen, the attacker's version sits in a holding area until manually approved — buying time to detect and revoke.

With maintenance transition being discussed (#180), this matters even more. Any handoff of publishing credentials is a window of elevated risk. Staged Publishing ensures that even during a transition, no single compromised credential can push a malicious release to 230M weekly installs.

Andrey Sitnik adopted it on nanoid and nanospy after the TanStack incident. PostCSS is next, per postcss/postcss#2096.

Concrete steps:

  1. Replace npm publish with npm stage publish
  2. Approve with 2FA: npm promote cross-spawn@<version> latest
  3. Or use the @npm/staged-publish GitHub Action for CI-driven releases with manual approval

No changes to the development workflow. Only the publish step gets a confirmation gate.

Detection: npx proof-of-commitment cross-spawn now surfaces whether a package uses Staged Publishing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions