For a decade, publishing to npm meant pasting a long-lived token into your CI and hoping nobody ever stole it. In 2026 that model is finally dying — and if you ship packages, you have about a weekend of work to catch up.
The pressure is not theoretical. The Shai-Hulud worm chewed through 796 packages pulling 132 million downloads a month, and on June 1 attackers pushed tainted code into 32 packages in the @redhat-cloud-services namespace using one compromised employee GitHub account. Almost every recent attack reuses the same move: steal a publishing identity, ship a bad version. Here is the field guide to shutting that down.
The token in your CI is the single most valuable secret you own. The whole point of the 2026 changes is to make that token not exist.
1. Replace tokens with trusted publishing (OIDC)
Trusted publishing lets npm verify your identity through your CI provider over OpenID Connect instead of a stored secret. Each publish uses a short-lived, cryptographically signed token scoped to one workflow — nothing to leak, nothing to rotate.
Configure it on npmjs.com under your package's Trusted Publisher settings: pick GitHub Actions, then enter the org/user, repo, and the exact workflow filename. Then grant the token permission in the workflow:
permissions:
id-token: write
contents: readDelete NODE_AUTH_TOKEN / NPM_TOKEN from the job entirely. If it is gone, it cannot be stolen.
2. Make CI stage-only and approve by hand
Trusted publishing proves where a publish came from, but not that a human meant to ship it. Staged publishing closes that gap. Configure the trusted publisher with stage-only permission so CI can run npm stage publish but a bare npm publish is rejected outright.
The tarball lands in a stage queue and sits there, uninstallable, until a maintainer clears a 2FA challenge on npmjs.com or the CLI:
# in CI
npm stage publish
# then a human approves the staged build with 2FAAutomation submits, a person approves. A stolen CI token now gets an attacker exactly nowhere.
3. Keep the npm CLI above the floor
These features have a hard version floor, and it keeps rising. Trusted publishing needs npm 11.5.1 or later; staged publishing landed in the CLI at 11.15.0. Pin it explicitly in CI so a stale runner doesn't silently fall back to token auth:
- run: npm install -g npm@latest
- run: node --version && npm --version4. Read the provenance you now get for free
When you publish through trusted publishing from GitHub Actions, npm automatically generates and attaches a provenance attestation linking the tarball to the exact commit and workflow that built it. Consumers can verify it:
npm audit signaturesThat command checks that the packages you installed carry valid provenance and signatures — cheap to run in CI, and it surfaces the exact class of tampering these attacks rely on.
5. Defend the install side too
Publishing hardening protects your users; it does nothing for the 1,000 dependencies you pull. npm's newer install controls let you refuse packages that were published seconds ago — the window attackers exploit before a malicious version is yanked.
# refuse anything published in the last 3 days
npm install --before "$(date -d '3 days ago' +%Y-%m-%d)"Pair a cooldown like that with a lockfile and npm ci in CI so builds are reproducible and never silently pick up a fresh, unvetted release.
6. Remember what actually gets attacked
The through-line of 2026's incidents is that identity, not code, is the target. axios in March, node-ipc in May, @redhat-cloud-services in June — none were clever zero-days. They were hijacked accounts and stolen tokens shipping ordinary-looking versions.
That reframes the whole checklist. Trusted publishing removes the token. Staged publishing removes the silent auto-ship. Provenance removes the "it looked normal" defense. You are not patching a bug; you are removing the thing attackers keep stealing.
If you do one thing this week: delete your npm publish token and wire up OIDC. Everything else is defense in depth on top of that.
npm was late to trusted publishing — PyPI shipped it in April 2023, RubyGems that December, crates.io and npm not until July 2025. But the ecosystem with the biggest attack surface finally has the same guardrails, and after this year's incidents there is no reason left to run on a bare token.
References
- npm registry sets stage for more secure package publishing — The Register
- npm Adds 2FA-Gated Publishing and Package Install Controls — The Hacker News
- Trusted publishing for npm packages — npm Docs
- npm trusted publishing with OIDC is generally available — GitHub Changelog
- Our plan for a more secure npm supply chain — The GitHub Blog
- The npm Threat Landscape — Unit 42, Palo Alto Networks