Let’s be blunt: if you haven’t finished your npm token migration, you’re out of runway. As of November 5, 2025, new classic tokens can’t be created. On November 19, 2025, every remaining classic token is revoked. Meanwhile, write‑scoped granular tokens enforce 2FA by default, and long‑lived local publishing sessions are giving way to short‑lived sessions. That’s good security—and a release‑management headache if you don’t have a plan.
Here’s the plan we’re rolling out with teams this week. It’s opinionated, fast to execute, and built for real CI/CD pipelines—not wishful thinking.
What actually changed (with dates and behaviors)
Security announcements often bury the lede. You need the operational facts:
- November 5, 2025: Creation of classic npm tokens is disabled across website, CLI, and API. The
npm token createcommand no longer mints classic tokens. - Now: New granular tokens with write permissions enforce 2FA by default. There’s an explicit “Bypass 2FA” setting intended for non‑interactive CI.
- Now: Granular write tokens are capped at a maximum lifetime (90 days), eliminating “forever” secrets. Review and adjust expirations.
- November 19, 2025: All remaining classic tokens are permanently revoked. Local long‑lived publishing flows are replaced with short‑lived sessions.
Why the pressure? Recent supply‑chain incidents pushed registries toward short‑lived credentials, stronger MFA, and provenance. You don’t need the backstory to act—you need a cutover that doesn’t break releases.
What breaks if you do nothing
Expect immediate failures where CI or release tools still rely on classic tokens:
- Release jobs that run
npm publish,npm dist-tag, ornpm accessstart throwing 401/403 errors. - Monorepo publish steps (Lerna, Nx, Changesets, Turborepo) fail mid‑pipeline.
- Stale secrets embedded in GitHub Action secrets, runner environments, container images, or vaults trigger flakey failures you’ll chase for days.
That’s avoidable—if you pick a lane and execute quickly.
Choose your lane: a practical npm token migration playbook
There are three viable lanes. Pick one per pipeline based on where you publish and how your CI is set up.
Lane A — Prefer OIDC Trusted Publishing (GitHub Actions)
If your public packages live on npm and you build on GitHub Actions, this is the lowest‑friction, highest‑security path. OIDC trusted publishing eliminates long‑lived tokens altogether. The registry issues short‑lived credentials on demand and attaches provenance attestations to public packages. No secret to exfiltrate, nothing to rotate.
Here’s the 7‑step cutover:
- Inventory packages and pipelines. Map each package to its publishing workflow file(s) and environment(s). Identify which ones are public on npm.
- Enable trusted publishing per package/scope. In npm, configure trusted publishing for the package or scope. On the GitHub side, ensure the repo belongs to the right org and that Actions OIDC is allowed for that repository/environment.
- Lock down workflow triggers. Restrict publish to a signed release or a specific branch tag pattern. Require reviewers via environments to prevent accidental publishes.
- Remove token usage. Delete
NPM_TOKENsecrets from the workflow and runners. Replace “login” steps with the registry’s OIDC login action (or rely on the built‑in publish step once configured). - Add provenance flags. Where supported, enable provenance on publish so clients can verify source and builder.
- Rotate fallbacks. If any automation still needs a token (legacy tooling or private registries), use a granular token with least‑privilege and short expiry while you modernize.
- Test in dry‑run. Run a canary release (pre‑release tag) from an internal branch. Validate artifacts, tags, and downstream consumers before flipping mainline releases.
Why this lane wins: you cut the secret sprawl to near zero and stop worrying about rotating tokens across dozens of repos.
Lane B — Granular Tokens with least‑privilege (for private/internal or non‑GitHub CI)
Not every team can use trusted publishing today—private packages, self‑hosted registries, or non‑GitHub CI might require tokens. Fine. Use granular access tokens, but treat them like per‑pipeline, narrowly scoped, short‑lived credentials.
Execute like this:
- Scope precisely. Create a token per pipeline or per project scope. Restrict to the exact package(s) or scope that pipeline publishes. Do not grant org‑wide access unless absolutely necessary.
- Use read/write only where needed. Most publish pipelines need write; everything else (build, test, install) should use read‑only or rely on the CI’s default auth.
- Keep lifetimes short. Cap the expiry at 7–30 days while you finish modernization, with calendar‑based rotation. The platform caps write tokens at a maximum (90 days), so plan rotation windows accordingly.
- 2FA defaults on for write. For non‑interactive CI, explicitly enable the “Bypass 2FA” setting on that token. Confine its usage to a controlled IP range if possible.
- Quarantine distribution. Store the token only in your CI secret manager—not in repo secrets or shell profiles. Block printing by setting masked/sealed secrets in your CI. Never bake into images.
- Rotate on any signal. Failed publish due to auth, unfamiliar IP access, or pipeline drift? Rotate immediately, audit accesses, and shorten the next token’s TTL.
Granular tokens are a bridge, not a destination. Put an OIDC migration on your OKRs so you’re not reliving this in a quarter.
Lane C — Short‑term patch for classic token holdouts
If you discover a mission‑critical pipeline still using a classic token on November 18, don’t panic. Replace it with a granular token with minimal scope and the shortest acceptable TTL, cut a hotfix release, and schedule the OIDC refactor next sprint. Add guardrails: environment‑level approvals, IP allow‑lists, and alerting on unusual registry requests. Then remove any lingering classic token references from runners and images the same day.
How to find—and eradicate—classic tokens at scale
Discoverability is the hard part. The place you least expect is where you’ll find a forgotten token. Use a layered approach:
- Repo search at the org level. Scan for
NPM_TOKEN,_authToken,npmrc, and registry URLs in history and current branches. Check workflow YAMLs, release scripts, and package scripts. - Secret inventories. Enumerate CI/platform secret stores (organization, environment, and repository scopes). Prioritize anything named
NPM,TOKEN,PUBLISH, orREGISTRY. - Runner and image hygiene. Search self‑hosted runners and base images for stray
.npmrcfiles, environment variable defaults, or layer caches with tokens. Rebuild images if in doubt. - SBOM and lockfile checks. Confirm your lockfiles aren’t pointing at tokenized registry URLs. In private package setups, verify that read operations don’t rely on write‑scoped creds.
- Access logs. Use registry and firewall logs to find token usage by IP and path. Look for off‑hours traffic patterns that suggest leaked secrets.
When you find a classic token, treat it as compromised. Revoke, replace with the appropriate lane (OIDC or granular), and document the change so you don’t rediscover it next quarter.
People also ask
Does 2FA really apply to npm granular tokens used in CI?
For tokens with write permissions, 2FA is enforced by default. CI is non‑interactive, so you’ll need to enable the token’s explicit “Bypass 2FA” option to let automated publishes proceed. That setting should be used sparingly, with tight scoping, short lifetimes, and environment‑level protections. If you can, skip tokens entirely and move to OIDC trusted publishing where the registry issues short‑lived session credentials to the workflow.
What if we publish private packages or use an internal registry like Artifactory or Nexus?
Trusted publishing is strongest when both your CI and the target registry speak OIDC for workload identity. For npm’s public registry, it’s straightforward with GitHub Actions. For private registries, many vendors now support OIDC‑backed auth flows or can front with an identity‑aware proxy. If that isn’t available, use granular tokens with the narrowest permissions, restrict by IP ranges, and rotate aggressively. Keep the OIDC migration in your platform roadmap so you can drop secrets once your registry supports it.
Is trusted publishing available outside GitHub Actions?
The most mature path today is GitHub Actions to the public npm registry. Other CI systems support OIDC workload identity, but your result depends on registry capabilities and first‑class integrations. If you’re on a different CI, the practical near‑term path is granular tokens with disciplined scoping and rotation, while you evaluate how to add OIDC to the chain (either natively or via an intermediary identity layer).
Timeline you can pin to your wall
Use this to keep leadership and release managers aligned:
- November 5, 2025: Classic token creation disabled. CLI switched. Granular write tokens enforce 2FA by default. Maximum lifetimes apply.
- Between Nov 5–18: Migrate pipelines to OIDC trusted publishing or granular tokens. Clean up old secrets in runners, images, and repo settings.
- November 19, 2025: All classic tokens revoked. Local long‑lived publishing replaced with short sessions.
Build your contingency: if a release fails for auth, flip to a granular token with a 7–30 day TTL as a temporary measure, then complete OIDC.
Zooming out: CI security is converging
The npm deadline isn’t happening in isolation. GitHub has also tightened dangerous workflow patterns in Actions this fall, and many teams are already patching pipelines ahead of the early‑December cutover for sensitive triggers. If your workflows still rely on risky patterns for third‑party or forked PRs, fix that next. We published a pragmatic playbook for the Actions change; it pairs naturally with the token migration work because both reduce secret exposure in CI.
If you need a deeper dive, see our hands‑on guide to the Dec 8 GitHub Actions cutover and our last‑week CI cutover guide for npm tokens. If you’d rather ship than shepherd migrations, we help teams implement OIDC trusted publishing and defense‑in‑depth CI. Start with our software delivery services or just talk to us.
Let’s get practical: a 72‑hour checklist
Use this as your task list and paste it into your incident channel or release calendar. Triage first, optimize second.
Day 1 — Triage and inventory
- List every package you publish to npm and the workflows that publish them.
- Classify each pipeline into Lane A (OIDC) or Lane B (granular token). Mark any “can’t move today” as Lane C (temporary patch).
- Delete classic tokens from CI secret stores and repo settings. Revoke them in npm even before the registry does it for you.
- Search runners and images for stray
.npmrcwith_authToken. Rebuild images where needed.
Day 2 — Implement and dry‑run
- Enable trusted publishing on your public packages. Wire up OIDC in GitHub Actions and restrict publish triggers.
- Create granular tokens for private/internal pipelines with tight scopes and short TTL. Enable “Bypass 2FA” only where publish steps are non‑interactive.
- Run canary publishes (pre‑release tags). Validate provenance, tags, and consumer installs.
Day 3 — Cutover and hardening
- Flip mainline releases to the new auth path. Remove legacy token steps from workflows and environment variables.
- Enforce environment approvals and branch protections for release workflows. Turn on dependency review gates before publish.
- Document rotation cadence for any remaining tokens and schedule OIDC migrations for holdouts.
Real‑world gotchas (so you don’t have to learn the hard way)
Monorepos often publish several packages with one workflow. When you enable trusted publishing, ensure the package scope in npm matches the repository identity you’re asserting through OIDC. If the monorepo publishes across multiple scopes, split the job or add per‑package environments with approvals.
Changesets and similar tools can attempt multiple publishes in a single run. With granular tokens, short TTLs can expire mid‑job if your build takes too long. Tweak TTLs and parallelism, or move to OIDC to avoid chasing the clock.
Some teams rely on release bots that run interactive commands behind the scenes. Double‑check that no TOTP prompts are triggered during publish—tokens with “Bypass 2FA” exist for this reason, but keep their blast radius tight. Better, move those bots to OIDC.
Finally, don’t forget dist‑tag management. If your pipeline pushes latest and next tags separately, confirm both operations use the new auth path. It’s common to migrate npm publish but leave npm dist-tag add on the old token.
What to do next
- Pick a lane per pipeline and execute the 72‑hour checklist—today.
- For public packages on GitHub Actions, enable OIDC trusted publishing and remove tokens entirely.
- For private/internal pipelines, create granular tokens with least‑privilege, short TTL, and “Bypass 2FA” only where required.
- Scrub classic tokens from repos, runners, images, and vaults. Treat any found token as compromised.
- Plan your second sprint to finish OIDC migrations and tighten workflow triggers ahead of the early‑December Actions changes. Our guided checklist will save you time.
Deadlines like this can feel disruptive. The upside is real: fewer secrets in CI, stronger provenance, and a smaller blast radius if something goes wrong. Move now, ship on time, and sleep better next week.
