astradevlabsastradevlabs
← All posts
Tech News4 min

A field guide to npm’s new supply-chain defenses

Tech News

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:

yaml
permissions:
  id-token: write
  contents: read

Delete 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:

bash
# in CI
npm stage publish
# then a human approves the staged build with 2FA

Automation 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:

yaml
- run: npm install -g npm@latest
- run: node --version && npm --version

4. 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:

bash
npm audit signatures

That 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.

bash
# 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