Rotating npm Publish Tokens Without Breaking CI
A leaked or expiring publish token must be replaced, but a careless rotation breaks every release pipeline that depends on it. This page shows how to rotate npm publish tokens safely with no failed publishes.
Exact symptoms and error messages
After a token is revoked but not yet replaced, release jobs fail:
npm error code E401
npm error 401 Unauthorized - PUT https://registry.npmjs.org/@acme%2fui
npm error This token has been revoked.
Root cause analysis
Publish tokens are long-lived shared secrets, so rotation is a two-sided change: the new token must be in the secret store before the old one is revoked, or there is a window where CI has no valid credential. Granular, short-lived tokens shrink that risk, and OIDC-based provenance publishing removes the standing secret entirely.
Token rotation breaks pipelines because a publish token is a long-lived shared secret with two sides that must stay in sync: the secret store CI reads from, and the registry's list of valid tokens. Revoke the registry side before the store side is updated and there is a window where CI holds a credential the registry no longer accepts — every release in that window fails. The whole risk is the ordering of those two operations.
Granular, expiring tokens shrink the window but do not remove it; the ordering still matters. The only way to remove the standing secret entirely is OIDC, where CI exchanges a short-lived identity for publish rights per job. With no long-lived token, there is nothing to rotate and nothing to leak between rotations — which is why provenance-based publishing is increasingly the recommended end state.
Token rotation breaks pipelines because a publish token is a long-lived shared secret with two sides that must stay in sync: the secret store CI reads from, and the registry's list of valid tokens. Revoke the registry side before the store side is updated and there is a window where CI holds a credential the registry no longer accepts — every release in that window fails. The whole risk is the ordering of those two operations.
Granular, expiring tokens shrink the window but do not remove it; the ordering still matters. The only way to remove the standing secret entirely is OIDC, where CI exchanges a short-lived identity for publish rights per job. With no long-lived token, there is nothing to rotate and nothing to leak between rotations, which is why provenance-based publishing is increasingly the recommended end state — it eliminates the rotation problem rather than making it safer.
Resolution and configuration patch
Rotate in a safe order — create, deploy, verify, then revoke:
# 1. Mint a new granular token scoped to the package (write)
# 2. Update the CI secret (no revoke yet)
gh secret set NPM_TOKEN --body "$NEW_TOKEN"
# 3. Run a dry-run publish on the pipeline to confirm auth
npm publish --dry-run
# 4. Only now revoke the old token
Better still, move to OIDC so CI exchanges a short-lived identity for publish rights and there is no token to rotate.
Bake the safe ordering into a runbook so rotation is mechanical rather than improvised under pressure:
# 1. Mint the new granular token (write scope, package-scoped)
# 2. Update the CI secret WITHOUT revoking the old token yet
gh secret set NPM_TOKEN --body "$NEW_TOKEN"
# 3. Trigger a dry-run publish on the pipeline to confirm the new token works
gh workflow run release.yml -f dry_run=true
# 4. ONLY after a green dry-run, revoke the old token
npm token revoke <old-token-id>
The dry-run between steps 2 and 4 is the safety interlock: it proves the replacement authenticates on the real pipeline before the old credential is destroyed.
Rotate in a safe order — create, deploy, verify, then revoke:
# 1. Mint the new granular token (write scope, package-scoped)
# 2. Update the CI secret WITHOUT revoking the old token yet
gh secret set NPM_TOKEN --body "$NEW_TOKEN"
# 3. Trigger a dry-run publish on the pipeline to confirm the new token works
gh workflow run release.yml -f dry_run=true
# 4. ONLY after a green dry-run, revoke the old token
npm token revoke <old-token-id>
The dry-run between steps 2 and 4 is the safety interlock: it proves the replacement authenticates on the real pipeline before the old credential is destroyed.
CLI validation and debug commands
# Confirm the new token authenticates before revoking the old one
npm whoami
# List active tokens to find the one to revoke
npm token list
# Revoke by id once the new token is verified live
npm token revoke <token-id>
Prevention and CI guardrails
- Always deploy the replacement secret before revoking the old token.
- Prefer granular, expiring tokens scoped to a single package over classic tokens.
- Move to OIDC/provenance publishing so there is no long-lived secret to rotate.
- Alert on token expiry so rotation is planned, not an incident response.
- Always deploy the replacement secret before revoking the old token.
- Prefer granular, expiring tokens scoped to a single package over classic tokens.
- Move to OIDC/provenance publishing so there is no standing secret to rotate.
- Alert on token expiry so rotation is planned, not an incident response.
Moving to OIDC so there is nothing to rotate
The most durable answer to token rotation is to stop having a token. With OIDC-based publishing, the CI job proves its identity to the registry and receives short-lived publish rights for that run only. There is no secret in the store to leak, expire, or rotate — the credential exists for the duration of the job and then vanishes.
This also strengthens provenance: because the registry knows the publish came from a verified CI identity, it can attach an attestation tying the tarball to the source and build, the same guarantee described in Adding SLSA Provenance to Package Releases. Migrating is usually a matter of granting the workflow id-token: write, publishing with --provenance, and removing the standing NPM_TOKEN secret. The rotation runbook then becomes unnecessary, because the thing it protects no longer exists.
Alerting on expiry so rotation is planned
Rotation goes wrong most often when it is reactive — a token expires or leaks and someone scrambles. Making it planned means knowing an expiry is coming before it lands. Granular tokens have an expiry date, so record it and alert ahead of time rather than discovering it from a failed release.
A simple scheduled check that lists tokens and flags any expiring within, say, two weeks turns rotation into routine maintenance. Pair it with the safe ordering runbook, and rotation becomes a calm, scheduled task: the alert fires, you mint and deploy the replacement, dry-run it green, and revoke the old token — no failed pipelines, no incident. The failure mode this prevents is the 3 a.m. 'this token has been revoked' error that stops every release until someone reconstructs the correct ordering under pressure.
Moving to OIDC so there is nothing to rotate
The most durable answer to token rotation is to stop having a token. With OIDC-based publishing, the CI job proves its identity to the registry and receives short-lived publish rights for that run only. There is no secret in the store to leak, expire, or rotate — the credential exists for the duration of the job and then vanishes, so the entire rotation runbook becomes unnecessary because the thing it protects no longer exists.
This also strengthens provenance: because the registry knows the publish came from a verified CI identity, it can attach an attestation tying the tarball to its source and build. Migrating is usually a matter of granting the workflow id-token: write, publishing with --provenance, and removing the standing token secret. The move eliminates two problems at once — the rotation burden and the standing-secret attack surface — while adding a verifiable link from the published artifact back to its source. For a team currently managing token rotation carefully, OIDC is not just a safer way to rotate but a way to stop needing to, which is the better outcome.
Alerting on expiry so rotation is planned
Rotation goes wrong most often when it is reactive — a token expires or leaks and someone scrambles under pressure, which is exactly when the safe ordering gets skipped. Making rotation planned means knowing an expiry is coming before it lands. Granular tokens have an expiry date, so record it and alert ahead of time rather than discovering it from a failed release.
A simple scheduled check that lists tokens and flags any expiring within, say, two weeks turns rotation into routine maintenance. Paired with the safe-ordering runbook, rotation becomes a calm, scheduled task: the alert fires, you mint and deploy the replacement, dry-run it green, and revoke the old token — no failed pipelines, no incident. The failure mode this prevents is the 3 a.m. 'this token has been revoked' error that stops every release until someone reconstructs the correct ordering under pressure. Between planning via expiry alerts and, ideally, moving to OIDC to remove the token entirely, a team can make publish-credential management a non-event rather than a recurring source of release outages.
Scoping tokens to limit rotation risk
The blast radius of a leaked or mishandled token is set by its scope, so narrowly-scoped tokens make rotation both safer and less frequent. A classic token with organization-wide publish rights is a serious exposure whose rotation touches every pipeline that uses it; a granular token scoped to a single package affects only that package's release, so its rotation is contained and its leak is bounded. Preferring granular, package-scoped tokens over broad ones means a rotation is a small, local operation rather than an organization-wide event.
Expiry is the complementary lever. A token with an expiry date forces periodic rotation, which keeps a long-forgotten credential from living indefinitely, and it turns rotation into a scheduled, expected task rather than a reaction to a leak. The combination — narrow scope plus a defined lifetime — is what makes token management sustainable: each token protects one thing for a bounded time, so a leak is limited and a rotation is routine. This is the same least-privilege, short-lived-credential discipline that OIDC takes to its conclusion by removing the standing token entirely, and for teams not yet on OIDC, granular expiring tokens are the intermediate step that most reduces rotation risk.
Frequently Asked Questions
How do I rotate with zero failed publishes?
Add the new token to the secret store and verify it with a dry-run publish before you revoke the old one. Never revoke first — that guarantees a window with no valid credential.
Can I avoid publish tokens entirely?
Largely, yes. OIDC-based publishing lets CI exchange a short-lived identity token for publish rights per job, so there is no standing secret to leak or rotate.
How do I rotate a publish token with zero failed releases?
Deploy the new token to the secret store first, prove it with a dry-run publish on the real pipeline, and only then revoke the old token. Never revoke first — that guarantees a window where CI has no valid credential.
Can I avoid publish-token rotation entirely?
Yes, with OIDC. The CI job exchanges a short-lived identity for publish rights per run, so there is no standing secret to leak or rotate — and it enables provenance attestation as a bonus.
How do I keep rotation from becoming an incident?
Alert on token expiry ahead of time and follow a fixed ordering runbook. That turns rotation into scheduled maintenance instead of a scramble triggered by a failed release.
How do I rotate a publish token with zero failed releases?
Deploy the new token to the secret store first, prove it with a dry-run publish on the real pipeline, and only then revoke the old token. Never revoke first — that guarantees a window where CI has no valid credential.
Can I avoid publish-token rotation entirely?
Yes, with OIDC. The CI job exchanges a short-lived identity for publish rights per run, so there is no standing secret to leak or rotate — and it enables provenance attestation as a bonus. Migrating removes the rotation burden rather than making it safer.
How do I keep token rotation from becoming an incident?
Alert on token expiry ahead of time and follow a fixed ordering runbook (create, deploy, verify, revoke). That turns rotation into scheduled maintenance instead of a scramble triggered by a failed release.
How does token scope affect rotation risk?
A narrowly-scoped, package-specific token limits both a leak's blast radius and the rotation's reach — only that package's release is affected. A broad organization-wide token makes every rotation an org-wide event. Prefer granular, expiring tokens so each rotation is a small, local, scheduled task.
Related
- Private Registries and Access Control — the overview for private distribution and access control.