Let’s get straight to it: npm classic tokens are gone. As of December 9, 2025, every classic token was permanently revoked. Local publishing now uses short, session‑based auth; CI/CD must switch to granular access tokens or, better, OIDC trusted publishing. If your pipeline still points to a long‑lived NPM_TOKEN, you’re on borrowed time—and likely already dealing with failed releases.
I’ll break down exactly what changed, why it happened, and how to ship a clean migration in under two days. I’ve included a fast path for teams on GitHub Actions as well as a safe fallback for every other CI system.
What changed on December 9, 2025—and why it matters
Here’s the thing: this wasn’t a surprise flip. On November 5, 2025, npm disabled creation of new classic tokens and tightened rules around granular tokens, including a hard cap on their lifetime when they have write permissions. On December 9, the hammer dropped—all classic tokens stopped working. At the same time, npm shipped session‑based authentication for local publishing: an npm login now yields a two‑hour session token that expires automatically. That’s great for manual publishes, but it’s not a CI strategy.
Two more details matter for migration planning. First, write‑enabled granular tokens now have a maximum lifetime measured in weeks, not years; that forces rotation discipline. Second, npm temporarily restored a legacy API endpoint used by older tooling, but its removal is planned—so treat it as a grace window, not a crutch.
Why the crackdown? Supply‑chain attacks have escalated all year. Wormable malware campaigns, compromised maintainer accounts, and misused tokens all drove a simple conclusion: long‑lived credentials are liabilities. Short‑lived, scoped tokens and OIDC‑based, just‑in‑time credentials dramatically shrink the blast radius.
Are session tokens enough for teams?
Short answer: no. Session tokens from npm login are designed for humans, not robots. They live two hours, aren’t visible in your token list, and force re‑auth. That’s excellent for defense, but CI needs non‑interactive authentication. Your choices are:
• OIDC trusted publishing: your workflow requests an identity token at publish time, npm verifies it, and issues a temporary token just for that run. No secret stored, nothing long‑lived to leak.
• Granular access tokens: scoped, short‑lived secrets you store in your CI provider. They work everywhere but demand rotation and least‑privilege discipline.
Primary keyword checkpoint: “npm classic tokens”
If you’re scanning for the headline, here it is again: npm classic tokens are permanently revoked. Replace them with trusted publishing or short‑lived granular tokens, or your releases will keep failing at the worst possible time.
Your two‑path migration plan (fast and durable)
Path A (preferred): OIDC trusted publishing on GitHub Actions
This is the safest, lowest‑maintenance option if your source of truth is on GitHub. You stop storing NPM_TOKEN entirely and let npm mint a short‑lived token per run.
Do this:
1) Associate your package with its GitHub repo in npm’s settings so the registry recognizes your publisher identity. Ensure your package.json has an accurate repository field.
2) In your workflow, request an OpenID Connect token. On GitHub Actions, that means setting permissions: id-token: write on the job that publishes, and granting read access to the repo if needed for versioning scripts.
3) Use the official setup step for Node.js and configure your publish step to target the npm registry without providing a stored secret. Behind the scenes, the action negotiates with npm to exchange the OIDC identity for a short‑lived publish credential.
4) Enable provenance/attestation if your tooling supports it, so consumers can verify the package came from a repository and workflow you control.
5) Dry‑run once with a pre‑release tag, then cut a normal release. No tokens in CI, no vault items to rotate, fewer pager alerts when people quit or rotate roles.
What it fixes: the classic “who leaked our NPM_TOKEN?” problem, secrets sprawl across jobs, and inconsistent 2FA enforcement. What it doesn’t: misuse of your repo itself. If an attacker can push to main and trigger your publish job, they can still ship a malicious package—so keep protected branches, required reviews, and signed commits in place.
Path B (everywhere): granular tokens with rotation
If you’re not on GitHub Actions or can’t enable OIDC yet, go with granular tokens.
Do this:
1) Create a granular access token with only the scopes you truly need to publish the intended package(s). If the token offers a “bypass 2FA for automation” option, use it only for non‑interactive CI jobs and document the justification.
2) Set an explicit expiration within the allowed maximum for write tokens. Plan rotation before the deadline—don’t rely on memory or a calendar invite that gets ignored.
3) Store the token in your CI secret manager, not in repo variables. Reference it in the publish step only. Avoid re‑exporting it into sub‑jobs or third‑party actions unless you trust them and they need it.
4) Build a simple rotation runbook: who owns the token, how to create the replacement, and which pipelines consume it. Use a staggered cutover where old and new tokens overlap by a day to avoid race conditions.
5) Monitor failed publishes and auth errors. A sudden spike usually means the token expired, the scope is too narrow, or the registry endpoint changed.
What breaks—and how to unstick it fast
• Old Yarn auth paths: If your pipeline still hits a legacy endpoint during publish or login, you might see two‑hour session behavior or failures. Use modern authentication in your workflow or switch the publishing step to npm CLI until you can upgrade your tooling. The legacy endpoint that was briefly restored is going away; don’t build new scripts on it.
• Manual publish muscle memory: Developers who used to run a quick “npm publish” at the end of the day will hit two‑hour sessions and 2FA prompts. That’s intentional. Prefer automated releases via CI with trusted publishing, or keep local 2FA keys handy.
• Monorepos with multiple packages: Each package needs its publisher relationship and scopes confirmed. Centralize release orchestration so you don’t manage a dozen independent secrets.
• Air‑gapped or constrained CI: If OIDC isn’t available, granular tokens work—but you must automate rotation. A simple cron job that opens a ticket and a PR to update the secret reference each month is enough to start.
Security side effects you actually want
Short‑lived credentials shrink the attack window. Even if a token leaks in build logs, it’s likely useless within hours or days. Enforced expiry prevents forgotten tokens from becoming the weakest link a year later. Tighter 2FA and provenance features make tampering harder to hide, and incident response clearer: you can trace which workflow, commit, and identity produced a package.
People also ask
Do I need 2FA for CI publishing?
Not interactively. With trusted publishing, the registry issues a one‑time token to your workflow based on OIDC—no 2FA prompt is needed at publish time. If you use a granular token instead, you can enable a “bypass 2FA for automation” option so your non‑interactive jobs don’t stall. For human publishes, keep 2FA on.
Can I keep using classic tokens for a bit?
No. They were revoked on December 9, 2025. Any pipeline that still references an old NPM_TOKEN value is either failing or quietly falling back to behavior you don’t expect. Rip them out.
How do npm session tokens work?
They’re short‑lived login sessions intended for people, not bots. A developer runs login, gains a two‑hour window to publish or manage packages, and then the session expires automatically. CI should use OIDC or granular tokens instead.
Intersecting risks right now: React2Shell and Node.js
Zooming out, a lot hit JavaScript maintainers in December. If you run Next.js with the App Router and React Server Components, you’re navigating the fallout from the critical RCE tracked as React2Shell (CVE‑2025‑55182). If your app was online and unpatched around early December, rotate secrets—attackers often drop miners first and pivot later. Also, on December 11, 2025, Next.js shipped additional fixes for two RSC protocol issues and later clarified a complete fix path. If you need a practical patch map and proof plan, use our field notes in Next.js Security Update: Patch and Prove Now and the follow‑ups covering the December 11 advisory.
On the platform side, the Node.js project is rolling out security releases across active lines around December 18, 2025. Keep an eye on your Node runtime baselines in containers and serverless functions so framework patches don’t sit on top of vulnerable runtimes. We put the key dates and a safe‑upgrade runbook here: Node.js Security Releases Dec 18: Your Patch Runbook.
Let’s get practical: a 24‑hour rollout checklist
• Hour 0–2: Inventory what’s publishing to npm. List repos, pipelines, and who owns them. Flag which ones use GitHub Actions versus other CI.
• Hour 2–4: Pick your path. If you’re on GitHub Actions and can enable OIDC, go trusted publishing. Otherwise, create granular tokens and set expirations aligned to your rotation cadence.
• Hour 4–8: Update one pipeline end‑to‑end and ship a pre‑release tag to validate the flow. Capture the steps in a short runbook so the next repos move faster.
• Hour 8–12: Roll out to the rest of your Tier‑1 packages. For monorepos, handle each package’s publisher association. If you see auth errors, double‑check scopes and that the workflow job has the right identity permissions.
• Hour 12–18: Remove any lingering NPM_TOKEN secrets from org‑level secret stores and repository variables. Revoke old tokens in npm settings to reduce your attack surface.
• Hour 18–24: Add monitors. Alert on failed npm publishes. Schedule monthly token rotation tickets for teams still on granular tokens. Capture a post‑mortem of the before/after state.
A minimal policy that actually works
Here’s a light‑touch standard we’ve implemented with multiple teams without slowing delivery:
• Use trusted publishing with OIDC wherever available. No long‑lived publish secrets in CI.
• If you must use granular tokens, scope them to the smallest possible set of packages and permissions, and cap their lifetime to the allowed maximum for write tokens.
• Enforce protected branches and required reviews on publish‑triggering workflows. If a tag triggers publish, lock down who can create tags.
• Store CI secrets only in the provider’s secret manager. Never in repo variables. Avoid exposing secrets to third‑party actions.
• Rotate secrets on a schedule you won’t forget, and document the rotation steps in the repo.
Edge cases and gotchas
• Private mirrors and air‑gapped builds need a mirror‑side identity story. If you cache artifacts, make sure your publish job still targets the public registry when it should, and that mirrors don’t capture short‑lived credentials in logs.
• Monorepos that publish many packages can drown in per‑package administration. Use a single release orchestrator job and a clear mapping between packages and workflows to avoid “some packages updated, some didn’t.”
• Teams mixing package managers sometimes assume the publish step is interchangeable. It’s not. For publishing, standardize on npm CLI until all your tools support modern auth flows equally well.
How this connects to real incidents
If the past few months taught the ecosystem anything, it’s that attackers go after the sloppy, not the sophisticated. Leaked tokens from CI logs, compromised maintainer accounts, and dependency worms spread because long‑lived credentials made persistence trivial. Short‑lived auth and OIDC won’t stop every attack, but they burn precious time off the clock for adversaries—and buy it back for your responders.
What to do next
• Move your top two packages to trusted publishing this week. Don’t boil the ocean—prove the pattern, then scale.
• If you’re mid‑incident or suspect exposure from the React server‑side issues, use our incident‑ready checklists in React2Shell: Patch, Prove, and Monitor This Week and the week‑three hardening plan in Fix, Verify, Fortify to reduce dwell time.
• Align your Node baselines with the December security releases. Keep your runtime clean so app‑level patches aren’t sitting on a shaky foundation.
Need a hand?
If you want a white‑glove migration or just a quick second pair of eyes on your pipeline, our team ships this work every week. See what we do, what it costs, and how we measure progress. Start here: what we do, our recent portfolio highlights, and a direct line on the contact page. Or keep reading the latest field guides on our blog—we’ll keep tracking the platform changes so you can keep shipping.
