Stolen publish tokens are behind many npm supply-chain attacks.
Classic automation published with long-lived tokens stored as CI secrets. Leak one and an attacker can publish malware under your name. The registry now offers better options:
Trusted publishing (OIDC): you register a trust relationship between the package and a CI workflow (GitHub Actions, GitLab CI/CD and others) on npmjs.com or with npm trust github ... (npm 11.15+). In CI, npm publish exchanges the CI provider's short-lived OIDC identity token for a publish credential. There is no npm token to store, rotate or leak. In GitHub Actions the job needs permissions: id-token: write.
Provenance: packages published from supported CI with trusted publishing get a signed provenance attestation automatically (or use npm publish --provenance with token-based CI publishing). It links the tarball to the source repository, commit and workflow that built it, recorded in the public Sigstore transparency log. The npm website shows a provenance badge; consumers verify with npm audit signatures.
Staged publishing (npm stage publish) lets CI upload a version that stays unavailable until a maintainer approves it with 2FA, restoring a human check for automated releases.
Also: require 2FA for publishing in package settings, prefer granular access tokens with short expiry where tokens are unavoidable, and limit maintainers.
Example
# .github/workflows/release.yml
name: release
on:
push:
tags: ["v*"]
permissions:
contents: read
id-token: write # lets npm obtain a GitHub OIDC token
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 24
registry-url: https://registry.npmjs.org
- run: npm ci
- run: npm test
- run: npm publish --access public # no NPM_TOKEN: trusted publishing + provenanceRemember
- Trusted publishing swaps CI OIDC tokens for publish rights: no stored secret
- Provenance links a tarball to its repo, commit and workflow
- Staged publishing adds a 2FA approval to automated releases
- Consumers verify with
npm audit signatures
Watch out for
- Keeping a long-lived automation token in CI secrets after moving to trusted publishing.