npm Token Migration: Your Nov 19 Cutover Plan
Here’s the thing: the npm token migration isn’t a soft nudge—it’s a hard cutover on November 19, 2025. Classic tokens are being revoked, and write-enabled granular tokens are tightening up. If you run CI-driven publishes or keep old tokens lying around, your release train can stop on that date. This guide gives you the last‑mile plan to survive the switch—and come out more secure than you were last week.
What exactly changes, and when?
On November 5, npm disabled creation of classic tokens and began enforcing new rules for granular tokens. Existing classic tokens continue to function only until November 19, 2025, when they’ll be permanently revoked. New tokens with write permissions enforce 2FA by default; a Bypass 2FA option exists for CI/CD. Existing write-enabled granular tokens are capped at a 90‑day maximum lifetime, with long expirations adjusted forward (notably to February 3, 2026). On November 19, long‑lived local publishing tokens also shift to short session tokens. (github.blog)
Zooming out, GitHub’s broader roadmap since late September has been clear: harden npm publication. They’re pushing three lanes—local publishing with required 2FA, short‑lived granular tokens, and Trusted Publishing (OIDC). Expect shorter defaults (seven-day expirations for new write tokens) and the gradual phase‑out of TOTP in favor of phishing‑resistant 2FA. (github.blog)
OIDC‑based npm Trusted Publishing is already GA, so you can publish from GitHub Actions without any stored npm token. That’s the safest long‑term option and, for many teams, the fastest way to get out of the token business entirely. (github.blog)
Why this migration is happening (and why you should care)
September’s “Shai‑Hulud” worm abused stolen maintainer credentials and automated its spread across the npm ecosystem—hundreds of packages, millions of weekly downloads. The lesson wasn’t subtle: broad, long‑lived tokens are a blast radius problem; CI can be a persistence vector. Shorter token lifetimes, enforced 2FA, and OIDC provenance help close that door. (tomshardware.com)
What breaks on November 19?
Anything still relying on an npm classic token will fail to authenticate or publish. That includes:
• GitHub Actions jobs using secrets like NPM_TOKEN created before granular tokens. • Local developer scripts that silently read a classic token from ~/.npmrc. • Other CI systems (Jenkins, CircleCI, GitLab CI) configured with classic tokens in vaults or environment variables. • Automation that assumes long‑lived write tokens without 2FA rules. (github.blog)
If your org publishes from macOS runners, also watch the macOS 13 brownout windows this month (Nov 11, 18, and 25 UTC) ahead of the December 4 retirement. Those temporary failures are unrelated to npm—but if you scheduled migration or release rehearsals in those windows, you’ll chase ghosts. Move to macOS 14/15 (arm64) labels or Linux where possible. (github.blog)
Choose your lane: tokens or OIDC?
For most teams, OIDC Trusted Publishing is the steady state. You get ephemeral credentials, signed provenance, and nothing to rotate. The only caveat is the setup step in your package settings to trust a specific workflow identity.
If you can’t flip to OIDC by the 19th, use granular tokens with least privilege, tight expiries, and explicit scopes. For noninteractive CI publishes, either enable Bypass 2FA on the token or prefer OIDC ASAP. (github.blog)
Last‑mile, 90‑minute cutover runbook
Block a focused 90 minutes with one engineer who has registry and repo admin rights. Here’s the order that avoids most snags.
0–10 minutes: Inventory and blast radius
• Search for tokens: check Actions > Secrets and variables at org and repo levels for NPM_TOKEN, NPM_AUTH_TOKEN, or similar. • Grep your repos for _authToken= and //registry.npmjs.org/ in .npmrc. • List tokens in npm at npmjs.com/settings/<user>/tokens. Identify any “classic” types and note expirations on granular tokens. (github.blog)
10–35 minutes: Enable OIDC Trusted Publishing (preferred)
• In npm package settings, add a Trusted Publisher for your repo’s GitHub Actions workflow. • In GitHub, ensure the workflow uses the id-token: write permission and actions/setup-node with registry-url. • Use the npm publish step without injecting a token; the registry verifies the OIDC assertion. • Verify provenance appears on your published package. (github.blog)
Minimal example:
permissions:\n contents: read\n id-token: write\n\non: [push]\n\njobs:\n release:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n - uses: actions/setup-node@v4\n with:\n node-version: 22\n registry-url: 'https://registry.npmjs.org'\n - run: npm ci\n - run: npm publish --provenance
35–55 minutes: If you must use a token
• Generate a granular access token with only the package(s) and permissions you need. • If it’s for CI publishing, decide whether to enable Bypass 2FA now (short term) or move to OIDC (soon). • Set a short expiration—seven to 30 days—to force a revisit. • Store it in your CI secret manager and update workflows to read NPM_TOKEN. • Remove any lingering _authToken from ~/.npmrc on build hosts. (github.blog)
55–75 minutes: Dry run and rollback
• Publish to a canary tag (e.g., next or beta) from a draft release branch. • Confirm the package landed with provenance (OIDC) or expected metadata (token). • If it fails with 2FA prompts, you’re still on a token that requires interactive auth—fix Bypass 2FA or switch to OIDC. • Keep a rollback plan: hide the bad version on npm and re‑publish the previous stable.
75–90 minutes: Revoke and document
• Revoke all classic tokens; log the IDs in your change record. • Document the new publishing path in CONTRIBUTING.md. • Open a ticket to rotate any granular tokens before they hit their capped expiration. (github.blog)
Copy‑paste: secure GitHub Actions publish with OIDC
This is the minimal, reproducible pattern I recommend for most orgs using GitHub Actions. It avoids secrets for npm entirely and works across monorepos and single‑package repos alike.
name: Release\n\non:\n workflow_dispatch:\n push:\n tags:\n - 'v*'\n\npermissions:\n contents: read\n id-token: write\n\njobs:\n publish:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n - uses: actions/setup-node@v4\n with:\n node-version: 22\n registry-url: 'https://registry.npmjs.org'\n - run: npm ci\n - run: npm test --if-present\n - run: npm publish --provenance --tag latest (github.blog)
People also ask: quick answers
Do I need to rotate granular tokens created before November?
If they’re write-enabled, yes—plan for rotation. All such tokens now have a 90‑day maximum lifetime, and some expirations were adjusted to February 3, 2026. Don’t wait for them to lapse mid‑sprint. (github.blog)
Should I enable Bypass 2FA for CI?
Only if you can’t adopt OIDC yet. Bypass 2FA exists for noninteractive workflows but keeps you in the business of managing secrets. The migration goal is OIDC, which eliminates stored npm tokens entirely. (github.blog)
What’s the default and max lifetime for new write tokens?
New guidance moves defaults toward shorter lifetimes (seven days) and caps max lifetime at 90 days for write-enabled granular tokens. Enforce least privilege and rotate often—or skip tokens via OIDC. (github.blog)
Risk and edge cases I’ve seen in migrations
• Hidden dotfiles in CI images. A forgotten ~/.npmrc with an old _authToken will override your env var or OIDC config and trigger baffling 2FA errors. Examine your base container images closely.
• Org‑wide 2FA + machine users. If your org enforces 2FA, service accounts without hardware keys will block local publishing. Either convert them to OIDC or set Bypass 2FA on a granular token as a short‑term bridge. (github.blog)
• Monorepo gotchas. Multiple packages publishing in parallel can race the registry rate limits. Stagger jobs or publish sequentially within one workflow so provenance stays intact. (github.blog)
• macOS runner retirements. If you’re on macOS 13 labels, expect intermittent failures in the November brownouts and full retirement December 4. Migrate labels now to avoid conflating runner deprecations with token migration issues. (github.blog)
Data points and dates to share with stakeholders
• Nov 5, 2025: Classic token creation disabled; granular write tokens tightened (2FA defaults, lifetime caps). (github.blog)
• Nov 19, 2025: Classic tokens revoked; long‑lived local publishing flows replaced with session tokens. Plan for zero‑stored‑token publishing where possible. (github.blog)
• Security driver: Shai‑Hulud worm exposed the risk of stolen maintainer secrets and CI persistence, accelerating npm’s roadmap. (tomshardware.com)
• Safer default: OIDC Trusted Publishing is GA—no secret storage, verifiable provenance. (github.blog)
Let’s get practical: a one‑page checklist
• Decide your lane: OIDC now, or granular token as a short‑term bridge. • Inventory: find all places using npm tokens (secrets, vaults, .npmrc). • Flip one canary package: wire OIDC and publish a prerelease. • Revoke classics: remove every classic token. • Rotate granulars: short expiry, least privilege, documented owners. • Harden org: passkeys for 2FA, require provenance, remove machine users for publishing. • Schedule a fire drill: publish twice before Nov 19—once from main, once from a hotfix branch. (github.blog)
What about non‑GitHub CI?
Trusted Publishing with OIDC is supported beyond GitHub Actions, but GitHub Actions is the most turnkey path today. If you’re on Jenkins, CircleCI, or others, you can still move to granular tokens with tight expirations and IP restrictions, then plan your OIDC rollout with your CI vendor’s OIDC support. (github.blog)
Bonus: two GitHub Actions updates that help right now
• Nested reusable workflows: limits increased (up to 10 nested, 50 total calls per run). Refactor your publish orchestration without hitting ceilings. • M2 macOS runners GA: better performance for build/test phases if you’re targeting Apple silicon. (github.blog)
What to do next
1) Pick one package and switch it to OIDC today. 2) Revoke all classic tokens. 3) If any team truly can’t move yet, issue a granular token with least privilege and a 7–30 day expiry—and create a ticket to remove it. 4) Run two rehearsal publishes before November 19. 5) Add provenance to your release checklist.
If you want a deeper, step‑by‑step cutover, read our field guide The Nov 19 Cutover Playbook. For impacts across your pipelines, we also published What Will Break on Nov 19 and a fast GitHub Actions briefing: November 2025 Changes That Matter. If you need help wiring OIDC across a monorepo or enterprise org, see our engineering services or contact the team—we’ve done this migration multiple times and can get you to green builds in days, not weeks.