On December 9, 2025, npm will permanently revoke classic tokens and enforce tighter authentication rules. If your pipelines still depend on a long‑lived secret, the clock is ticking. This is the moment to act—because the npm token changes affect every team that publishes JavaScript packages, from solo maintainers to enterprise monorepos.
Here’s the thing: the security upgrades are good for the ecosystem, but they’re operationally sharp. Below is a pragmatic, time‑boxed plan to switch your CI/CD to granular tokens with short lifetimes or—preferably—OIDC‑based Trusted Publishing, without breaking releases.
The npm token changes: dates and impact
Let’s anchor the facts with specific dates and behaviors that matter to your release manager:
- November 5, 2025: Creation of new classic tokens was disabled across the website, CLI, and API. New write‑enabled granular tokens enforce 2FA by default, with an explicit Bypass 2FA option for non‑interactive CI.
- December 9, 2025: All remaining classic tokens are permanently revoked. In parallel, npm ships first‑class CLI support to manage granular tokens from the terminal, and login sessions for local/manual publishing shift to short, time‑boxed behavior (two‑hour sessions).
- Lifetime limits: Write‑enabled granular tokens have a maximum 90‑day lifetime. Existing tokens that were set beyond February 3, 2026 have been adjusted to expire on or before that date.
- 2FA posture: New guidance favors security key/WebAuthn 2FA. Adding new TOTP devices was restricted earlier in the rollout; existing setups continue to work, but expect stronger nudges toward FIDO‑class auth.
Translation: long‑lived secrets are gone, publishing becomes provable, and CI pipelines must either rotate short‑lived granular tokens on a schedule or adopt OIDC so the registry issues a just‑in‑time token for each publish.
Why this is happening—and why you should welcome it
Supply chain incidents in the JavaScript ecosystem have repeatedly exploited stolen credentials and lax publishing flows. Worms and dependency‑confusion stunts don’t need exotic zero‑days—too often, they rely on a leaked token or an unattended maintainer account. If you want the background and response playbook, read our Shai‑Hulud 2.0: The npm Supply Chain Attack Playbook. The spirit of the latest npm changes is simple: reduce blast radius, raise the bar for attackers, and make provenance measurable.
Shorter token lifetimes, strong 2FA, and OIDC‑based issuing are the same patterns cloud platforms use for production infrastructure. It’s overdue for registries—and it’s workable if you treat the change like any other breaking runtime upgrade.
Pick a lane: OIDC vs granular tokens
There are three realistic paths. Choose deliberately:
1) OIDC Trusted Publishing (recommended)
In this model, your CI proves its identity to npm via OpenID Connect. npm issues a short‑lived, one‑time publish token for that job only. No long‑lived secret sits in GitHub Actions secrets, Jenkins credentials, or runner environment files. For most teams on GitHub Actions or GitLab SaaS, this is the cleanest and safest route.
Pros: No rotating secrets; identity‑bound; least artifact sprawl. Cons: Initial setup touches both your registry and CI configuration; some self‑hosted runner networks need additional OIDC plumbing.
2) Granular tokens in CI with rotation
You can continue to use granular tokens for CI if they’re tightly scoped and rotated on a schedule. Expect 90‑day maximum lifetimes and shorter defaults (seven days was used earlier in the rollout). You’ll need automation to mint, distribute, and retire tokens without human heroics.
Pros: Works everywhere, including bespoke CI. Cons: Operational overhead; missed rotations will break releases; tokens can still leak in logs and images.
3) Local/manual publishing with 2FA
For small teams shipping rarely, human‑in‑the‑loop publishing may be fine—especially for private packages. But it doesn’t scale, and it’s the first thing to fall over during an on‑call handoff.
Pros: Minimal change if you already publish locally. Cons: Slower; not auditable; fragile during incidents; increasingly constrained by session timeouts and mandatory 2FA.
Step‑by‑step: OIDC Trusted Publishing on GitHub Actions
If you can adopt OIDC, do it. Here’s a focused, production‑tested setup you can execute in under an hour per package.
- Grant your workflow permission to request an ID token. In your workflow file, set permissions explicitly:
permissions:
id-token: write
contents: read
- Lock the workflow path and environment. Use
on: workflow_callor precisepathsfilters. If you use environments, require reviews for protection. Provenance hinges on preventing arbitrary workflow edits from minting publish credentials. - Register the workflow as a trusted publisher for the package. In your npm package settings, add the GitHub repository and workflow path authorized to publish. If you’re using a monorepo, register the exact workflow that executes the publish step.
- Request and exchange the OIDC token during publish. Most modern publish actions do this for you. Verify that the action uses OIDC (not a stored secret). If you roll your own, request an OIDC token via the runner and call the npm registry exchange endpoint.
- Dry‑run, then ship. Run
npm publish --dry-runin CI first, verifying you’re hitting the intended scope, tag, and registry. Tag a prerelease, confirm provenance metadata, and only then cut a stable tag. - Block the old path. Remove any
NPM_TOKENsecrets and disable jobs that reference them. Search repo history for accidental secrets in workflows, action inputs, and reusable workflows.
Granular token path: a practical rotation and scoping checklist
If OIDC isn’t viable yet, use this hardened approach for granular tokens. It’s not as clean, but it’s safe enough when executed carefully.
- Create the token with least privilege. Scope it to a single org and the smallest set of packages. Avoid wildcards unless your releaser covers many packages by design.
- Set the shortest workable lifetime. Don’t max out at 90 days unless you must. Align the lifetime with an automated rotation job (for example, every 30 days).
- Decide on 2FA behavior. Leave Bypass 2FA off by default. If your pipeline can’t handle interactive prompts, enable Bypass 2FA but compensate with IP and workflow constraints.
- Bind to IP ranges when possible. If your CI has stable egress, restrict the token to that range. For cloud runners, use provider‑documented ranges or a static egress gateway.
- Store the token in a secrets manager, not in repo settings. For GitHub, prefer environment‑scoped secrets with deployment protection rules over org‑wide or repo‑wide secrets.
- Rotate automatically. Build a job that creates the new token, updates the secret, and revokes the old one—atomically. Don’t rely on human follow‑through.
- Audit jobs and logs. Disable printing
npm whoamior fullnpm config listoutputs. Mask values aggressively. - Search for secret sprawl. Hunt for tokens in container images, runner AMIs, terraform state, and obsolete actions caches.
- Fail closed. If
npm publishfails authentication, ensure the pipeline stops before producing partially released artifacts or broken tags. - Plan the OIDC migration anyway. Set a date. Treat granular tokens as a bridge, not the destination.
Monorepos, provenance, and other edge cases
Monorepos (Lerna, Changesets, Nx, Turborepo): Register the publish workflow, not the repo broadly. If multiple packages publish from different workflows, each must be authorized in npm. Double‑check that your tool respects per‑package publishConfig and doesn’t reuse a token across steps.
Self‑hosted runners: OIDC can work, but you must allow the runner to request a signed ID token from your CI control plane. If your network egress is NATed, IP allowlisting at the registry may be impractical—lean on OIDC identity instead of IPs.
Private registries and mirrors: If you use a caching proxy, ensure it’s not intercepting OIDC flows. Keep the publish step pointed at the canonical registry.
Multiple orgs and scopes: Favor one workflow per org to keep trust boundaries crisp. Where that’s not possible, isolate using GitHub environments and separate reusable workflows.
Local/manual publishing: Expect session timeouts (two‑hour tokens) and mandatory 2FA. Keep a hardware key in the HSM drawer and document the fallback for incident responders.
People also ask
Can I keep using classic tokens after December 9?
No. Classic tokens stop working on December 9, 2025. Pipelines that rely on them will fail authentication.
Do I need 2FA for bot accounts?
For local/manual publishing, yes—treat it like any human account. For CI, prefer OIDC so the registry issues a token without requiring an interactive second factor.
What breaks if I ignore this?
Release jobs that run npm publish, npm dist-tag, or npm access will throw 401/403 errors. Monorepo orchestration can fail mid‑pipeline, leaving tags and artifacts in a bad state.
Is OIDC slower than tokens?
Not materially. The exchange adds a small request, but you avoid secret distribution, rotation windows, and flakey failures from expired tokens.
A 72‑hour cutover plan (works for most teams)
Here’s a concise playbook we’re using with customers this week.
- Inventory and triage (Day 1 morning). List every publish path: repos, workflows, packages, and orgs. Flag where
NPM_TOKENis used. Decide per package: OIDC now, or granular token bridge. - Ship OIDC for the easy 60% (Day 1 afternoon). Add
id-token: write, register the workflow in npm, dry‑run, and push a prerelease. Remove any stored publish tokens. - Bridge the hard 40% (Day 2). For bespoke CI or self‑hosted runners you can’t unblock in time, create minimal‑scope granular tokens with short lifetimes, IP limits where possible, and automated rotation. Document the sunset date to move to OIDC.
- Harden and observe (Day 3). Turn on environment protection rules, pin action SHAs, and enable provenance where available. Add smoke tests that pull the newly published package and validate installability before calling the pipeline successful.
Risk management: how to keep shipping while changing auth
There’s always a moment when a pipeline breaks because a secret changed. Reduce that blast radius:
- Shadow publish from a non‑prod branch to a private tag, confirm integrity, then cut stable.
- Feature‑flag token sources so you can flip between OIDC and granular token paths without edits to complex workflows.
- Pin your release toolchain (actions and CLIs) and upgrade intentionally after the cutover.
- Capture SBOMs and link them to release artifacts to speed incident response if something goes sideways.
What to do next (this week)
- Pick your lane: OIDC whenever possible; granular tokens only as a bridge.
- Add
permissions: id-token: writeand register trusted workflows for the top three packages you publish. - Remove any lingering
NPM_TOKENsecrets from repo/org settings and runners. - Set up automated rotation for any temporary granular tokens with short lifetimes.
- Run a prerelease to validate, then ship a real release before December 9.
Where we can help
If you’re juggling this alongside year‑end releases, we’ve helped teams do the cutover in days, not weeks. See what we build on the portfolio and the scope of work on services. Or reach out directly via contacts. We also publish similar upgrade playbooks on the blog when platforms ship breaking changes—because calm, well‑documented change is how you keep shipping.
Zooming out
Security tends to oscillate between convenience and certainty. The npm token changes move the ecosystem toward certainty: short‑lived credentials, strong second factors, and identity‑bound publishing. It’s the same arc cloud providers followed over the last decade. If you build the OIDC path now, you won’t have to revisit this every quarter when another secret ages out—and you’ll sleep better the next time a supply chain headline hits your feed.
