Here’s the thing: the npm token migration is no longer theoretical. As of November 5, 2025, new classic tokens can’t be created, new granular write tokens enforce 2FA by default, and granular write tokens are capped at 90 days. On November 19, 2025, npm will revoke all remaining classic tokens and replace long‑lived local publishing tokens with short 2‑hour sessions. Meanwhile, the latest GitHub Actions images (Ubuntu 24.04 and Windows Server 2022/2025) have dropped preinstalled Node 18 following its April 30, 2025 EOL. If you run JS releases in CI, these two shifts collide. Let’s defuse this, fast.
What actually changes on November 19?
Two milestones matter this month:
1) npm permanently revokes classic tokens (Nov 19, 2025). If any workflow uses a classic token (often named NPM_TOKEN or NPM_AUTH_TOKEN in secrets), publish steps will fail. New granular write tokens mandate 2FA and expire in at most 90 days, with an optional “Bypass 2FA” flag designed specifically for noninteractive CI. Better yet, you can avoid tokens entirely using trusted publishing with OIDC.
2) GitHub Actions runner images removed preinstalled Node 18 (early November). Builds that assumed “Node 18 is on the image” without actions/setup-node may now fail or slow down significantly. Given Node 18 hit EOL on April 30, 2025, you should move to Node 20 or 22 anyway.
Primary question: Do I need a token at all—or should I use OIDC?
If you publish from GitHub Actions or GitLab.com shared runners, choose trusted publishing (OIDC). It eliminates long‑lived NPM_TOKEN secrets, authenticates each publish with short‑lived workflow‑scoped credentials, and automatically attaches provenance. For many teams, this is the fastest, safest path through November with the fewest moving parts to rotate later.
10‑day CI rescue plan (works even during sprint week)
Here’s a pragmatic schedule you can run between standups. It assumes you’re publishing public packages from GitHub Actions. Adjust for private packages and multi‑registry setups as needed.
Day 1: Inventory and blast‑radius scan
Start by finding every place a classic token might break your pipeline.
- Search your org:
NPM_TOKEN,NPM_AUTH_TOKEN,_authToken=, and//registry.npmjs.org/:in workflows,.npmrc, and build scripts. - List repository and environment secrets that look like npm tokens. If you see “classic” in the npm UI for any key you still use in CI, schedule its retirement.
- Identify jobs relying on preinstalled Node (no
actions/setup-node). Mark them for explicit setup with Node 20 or 22.
Day 2: Decide OIDC vs. tokens, per package
Default to OIDC for public packages on GitHub‑hosted runners. Use a granular write token with “Bypass 2FA” only if you can’t switch to OIDC right away (for example, private repos where you still need provenance tradeoffs, or complex self‑hosted runner topologies today). If you must use tokens, document the new 90‑day rotation and owners.
Day 3: Enable trusted publishing (OIDC) on npm
In each package’s npm settings, add a trusted publisher for the repo and workflow that runs npm publish. Then, update your workflow permissions and publish step. Minimal working example:
name: release
on:
push:
tags:
- 'v*.*.*'
permissions:
contents: read
id-token: write # required for OIDC
jobs:
publish:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v5
with:
node-version: '22'
- run: npm ci --ignore-scripts
- run: npm test -w .
- run: npm publish --access public
No NPM_TOKEN. No --provenance; provenance is attached automatically with trusted publishing for public packages from public repos.
Day 4: Fix Node versions explicitly
Add actions/setup-node@v5 to any job that runs Node, and pick 20 or 22 unless you’ve already validated 24. Also set the registry URL only if you still use tokens:
- uses: actions/setup-node@v5
with:
node-version: '22'
cache: 'npm'
Why now? Recent runner images have removed the cached Node 18 tool. If your job called node without setup‑node, it could suddenly break. Pin and cache explicitly.
Day 5: Create a granular write token (only where OIDC can’t run)
If you must ship with tokens, create a granular access token with the narrowest scopes, check “Bypass 2FA” for CI, and set an explicit expiration date within 90 days. Store it as a repository or environment secret. Update your workflow:
- uses: actions/setup-node@v5
with:
node-version: '22'
- run: npm ci --ignore-scripts
- run: npm test
- run: npm publish --access public
env:
npm_config_//registry.npmjs.org/:_authToken: ${{ secrets.NPM_PUBLISH_TOKEN }}
Plan your rotation calendar the day you create it. Put the date in your on‑call notes and your incident docs.
Day 6: Dry‑run and provenance checks
Use tags on a canary package or a --dry-run publish to validate OIDC or token auth, permissions, and provenance. Expect to fix typos in the workflow filename and environment name—OIDC matching is exact. If your build installs private dependencies, remember that OIDC covers publish, not install. You’ll still need a read‑only token for those installs.
Day 7: Cut over low‑risk packages
Migrate smaller packages first. Verify signed provenance appears on their npm pages when using trusted publishing from public repos. Capture real logs and annotate a runbook.
Day 8: Upgrade the rest and remove classic tokens
Roll the changes across critical packages. Then, revoke any classic tokens that are no longer needed. If you’re keeping a granular token for a short time, make sure it has “Bypass 2FA” enabled and the least scope needed for publish.
Day 9: Stress test failure modes
Intentionally break things in a staging repo: wrong workflow filename, no id-token: write, missing permissions, expired tokens, private dependencies without read credentials. It’s cheaper to fail now than on November 19.
Day 10: Lock in observability
Add alerts and dashboards for publish jobs. Log HTTP 401/403 errors from npm, provenance status, and token expiration reminders. Document exactly how to rotate granular tokens—or how to confirm OIDC is still working—so an on‑call engineer can recover in minutes.
People also ask
What happens if I do nothing before November 19?
Any workflow that still depends on a classic token will fail to publish. Pipelines that assumed Node 18 was preinstalled can also fail or slow down on the latest runner images. Your team will experience release delays exactly when you least want them—end of sprint or just before a holiday code freeze.
Do I need “Bypass 2FA” for CI?
Only if you’re still using granular write tokens for automated publishing. OIDC trusted publishing doesn’t require your own token or 2FA bypass; it issues a short‑lived credential for that run. If you stick with tokens temporarily, enable the bypass for headless jobs or they’ll prompt for a second factor you can’t provide.
Will trusted publishing work with private repos or private packages?
Trusted publishing supports both public and private packages. Provenance attaches automatically for public packages published from public repos. Private repositories can publish via OIDC, but provenance isn’t attached in that case. If you install private dependencies during the build, you still need a read token for install steps—OIDC only covers the publish command.
Data points, dates, and versions you should know
Keep these handy for change requests and CAB notes:
- Nov 5, 2025: New classic tokens disabled; granular write tokens enforce 2FA and a max 90‑day lifetime; “Bypass 2FA” option appears for CI.
- Nov 19, 2025: npm revokes all classic tokens and shifts local long‑lived logins to 2‑hour sessions.
- Node 18 EOL: April 30, 2025; latest runner images removed preinstalled Node 18 toolcache. Use Node 20 or 22 via
actions/setup-node. - Trusted publishing: Generally available; requires npm CLI 11.5.1+; GitHub‑hosted runners supported; automatically attaches provenance for public packages from public repos.
Risk triage: where teams get bitten
After helping multiple orgs through similar cutovers, four failure patterns dominate:
- Shadow tokens in old workflows. A forgotten release job in a subpackage or a docs site uses a classic token. It breaks first and pages the frontend team at midnight.
- Implicit Node runtime. A custom action or postinstall hook calls
nodedirectly withoutsetup-node; Node 18 vanishes; the job fails. - Private dependency installs. Teams flip to OIDC, but forget they still need a read token for
npm cion private modules. - 2FA surprises. A granular token without “Bypass 2FA” blocks noninteractive publishes. Fix by recreating the token with bypass enabled—or finish your OIDC migration.
Security win: OIDC + provenance changes the trust story
Granular write tokens with 2FA and expirations are an improvement, but they’re still secrets you must protect and rotate. Trusted publishing removes those long‑lived write credentials entirely and gives you provenance for free on public packages. That’s significant for customers, auditors, and due diligence. It’s also resilient: even if logs leak, there’s no reusable token to steal.
Practical YAML you can copy
For tag‑based releases with OIDC and Node 22:
name: release
on:
push:
tags:
- 'v*.*.*'
permissions:
contents: read
id-token: write
jobs:
publish:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v5
with:
node-version: '22'
cache: 'npm'
- run: npm ci --ignore-scripts
- run: npm test
- run: npm publish --access public
For a temporary granular token path (with “Bypass 2FA” enabled):
- uses: actions/setup-node@v5
with:
node-version: '22'
- run: npm ci --ignore-scripts
- run: npm publish --access public --ignore-scripts
env:
npm_config_//registry.npmjs.org/:_authToken: ${{ secrets.NPM_PUBLISH_TOKEN }}
Edge cases and gotchas
Monorepos and workspaces. Ensure each published package is configured as a trusted publisher, or consolidate your publish into a single workflow file whose name matches your npm settings exactly. For pnpm and changesets flows, validate that the publishing step still happens inside the workflow you registered.
Self‑hosted runners. Today’s trusted publishing support is focused on cloud‑hosted runners. If you’re on self‑hosted, plan a parallel track: either move publishing jobs to GitHub‑hosted runners, or keep granular tokens with strict scoping and rotation until support expands.
Private dependencies. OIDC doesn’t grant read access to private packages during npm ci. Add a read token scoped to read:packages and inject it only for the install step. Keep it separate from any write token and rotate it on a scheduled cadence.
Provenance visibility. Publishing from a public repo to a public package yields visible provenance on npm. Publishing from a private repo won’t show provenance publicly, even if the package is public. That’s expected—don’t chase it on release day.
What to do next (leaders and developers)
For engineering leaders:
- Approve a short freeze window to merge the CI changes in this guide.
- Mandate
actions/setup-nodeeverywhere; forbid implicit Node usage. - Adopt trusted publishing as the org default for public packages; tokens are the exception.
- Schedule a recurring token rotation for any remaining granular tokens (e.g., every 75–80 days).
For developers and maintainers:
- Run the 10‑day plan. Start with the inventory and OIDC setup today.
- Test a canary package, then roll across your repos using a template workflow.
- Document exactly where private dependency read tokens live, and how to rotate them.
- Add monitoring for 401/403 publish failures and token expirations.
Related deep dives
If you want a step‑by‑step with screenshots and org‑level patterns, read our CI/CD cutover guide for npm token migration and the fast‑track Nov 19 cutover plan. Running releases on GitHub Actions? Pair this with our advice on what to change now in Actions. Upgrading Node? Our Node 25 upgrade playbook covers common breakage and how to validate toolchains.
Zooming out
November’s changes aren’t just bureaucracy. They’re a push to shorten the blast radius when credentials leak and to give consumers cryptographic proof of how packages were built. Whether you’re shipping a CLI used by thousands or a small internal library, moving to OIDC plus provenance is one of those rare security upgrades that actually reduces operational overhead once it’s in place. Run the plan now, and your release train will keep rolling on November 19.