npm classic tokens are over: IR guidance for revocations, 2FA, and short‑lived credentials
On November 5, 2025, GitHub disabled creation of classic npm tokens and tightened controls on granular tokens; write-capable granular tokens now enforce 2FA by default and are limited to a maximum 90-day lifetime, with a seven-day default for new write tokens. GitHub also indicated that local publishing sessions would shift to two-hour tokens, and initially targeted November 19 for revoking all remaining classic tokens. Validate the current cutoff in your environment-GitHub’s community channel noted a possible shift to December 9 to coincide with CLI improvements-then proceed as if long-lived classic credentials are dead and rotation is mandatory. (GitHub Changelog, Nov 5, GitHub Changelog, Sep 29, GitHub Community discussion, Nov 13). (github.blog)
Intrusion Flow
Attackers have repeatedly abused exposed maintainer credentials to publish trojanized packages to npm-most recently via the self-replicating “Shai-Hulud” campaign that stole tokens and propagated through maintainer accounts. Shorter token lifetimes and enforced second factors reduce the abuse window and raise the bar for interactive publishing. Expect attackers to pivot toward stealing CI tokens or misusing any “Bypass 2FA” write tokens that teams enable for automation. Prefer OIDC-based trusted publishing to avoid long-lived secrets in pipelines. (CISA alert on Shai-Hulud, GitHub plan for a more secure npm supply chain, npm trusted publishing docs). (cisa.gov)
Key Artifacts to Pull
- Workflows and configuration
- GitHub Actions/GitLab CI files that publish packages. Trusted publishing requires an OIDC token grant (
permissions: id-token: write) and cloud-hosted runners. Pull the exact workflow referenced in npm’s Trusted Publisher configuration. (npm trusted publishing). (docs.npmjs.com) - Package settings on npmjs.com: “Trusted publisher” binding (repo, workflow filename) and publishing access policy (option to require 2FA and optionally disallow tokens). (Trusted publishers, Require 2FA for publishing). (docs.npmjs.com)
- GitHub Actions/GitLab CI files that publish packages. Trusted publishing requires an OIDC token grant (
- Token inventory
- User/Org Access Tokens page and
npm token listoutput to confirm which tokens exist, scopes, CIDR restrictions, and expirations; granular tokens are configurable only on the web today. (Creating and viewing access tokens, About access tokens). (docs.npmjs.com)
- User/Org Access Tokens page and
- Local and build-host credentials
- Any
.npmrcfiles and environment injects where tokens may be present; tokens are commonly set via the scoped auth line//registry.npmjs.org/:_authToken=or viaNODE_AUTH_TOKEN/NPM_TOKENin CI. (pnpm .npmrc reference for _authToken and env substitution, CircleCI example showing classic token line, npm trusted publishing guidance showing NODE_AUTH_TOKEN for private deps). (pnpm.io)
- Any
- Provenance and publish evidence
- Workflow runs and release tags; if you enable trusted publishing or
npm publish --provenance, provenance attestations can corroborate source and build context. (Generating provenance statements). (docs.npmjs.com)
- Workflow runs and release tags; if you enable trusted publishing or
Detection Notes
- Find embedded tokens and risky config
- Search repos, .npmrc, CI variables, and images for classic token artifacts and generic npm auth lines:
The scoped auth key and env usage are documented across npm ecosystem docs and examples. (pnpm .npmrc, npm trusted publishers - handling private deps, CircleCI example). (pnpm.io)
# common npm auth token config in .npmrc rg -n "^//registry\.npmjs\.org/:_authToken=.*" -g '!node_modules' # environment variables commonly used in CI rg -n "NODE_AUTH_TOKEN|NPM_TOKEN" -g '!node_modules'
- Search repos, .npmrc, CI variables, and images for classic token artifacts and generic npm auth lines:
- Identify failing publishes due to revocations
- After revocation, pipelines still using classic tokens will fail with authentication errors; trusted publishing docs call out “Unable to authenticate” scenarios and how to validate the workflow name and OIDC permissions. (npm trusted publishing troubleshooting). (docs.npmjs.com)
- Check token posture changes
- Confirm granular token expirations (max 90 days; seven-day default for new write tokens) and whether any write tokens have “Bypass 2FA” enabled. Treat bypassed tokens as high-risk. (GitHub Changelog, Sep 29, About access tokens - granular controls). (github.blog)
Response Guidance
- Stabilize builds
- If you publish from CI, move to trusted publishing (OIDC). Minimal GitHub Actions example:
Configure the package’s Trusted Publisher on npmjs.com to match your repo and workflow filename. (npm trusted publishing). (docs.npmjs.com)
permissions: id-token: write contents: read jobs: publish: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' registry-url: 'https://registry.npmjs.org' - run: npm ci && npm test - run: npm publish - If you must use tokens in CI, generate read-only granular tokens for installs and the narrowest write token for publishing; enable the token’s “Bypass 2FA” only when required for non-interactive workflows, and set short expirations. (About access tokens - granular features and bypass 2FA, Creating and viewing access tokens). (docs.npmjs.com)
- If you publish from CI, move to trusted publishing (OIDC). Minimal GitHub Actions example:
- Lock down accounts and packages
- Require 2FA for publishing at the package level; if you’re on trusted publishing, consider “Require two-factor authentication and disallow tokens” to remove token-based publishing entirely. (Requiring 2FA for publishing). (docs.npmjs.com)
- Rotate and revoke any exposed secrets promptly. Use npm’s token management (web or CLI) to list and delete old tokens. (Revoking access tokens). (docs.npmjs.com)
- Preserve and review evidence
- Export workflow run logs, package provenance (if enabled), and the Access Tokens audit view before rotating credentials. Provenance helps attribute publishes to specific CI runs. (Generating provenance statements). (docs.npmjs.com)
- Communicate the timeline clearly
- Reference GitHub’s November 5 change (classic creation disabled, policy changes) and the planned revocation window. Some messaging suggested a date shift; confirm against current GitHub/npm notices and your token page before asserting revocation in incident reports. (GitHub Changelog, Nov 5, GitHub Community discussion). (github.blog)
Takeaways
- Prefer OIDC trusted publishing over tokens; it eliminates long-lived publish secrets in CI and automatically enforces strong authentication. (npm trusted publishing). (docs.npmjs.com)
- If you keep tokens, use granular scope, short expirations (≤90 days), and avoid “Bypass 2FA” except where strictly necessary. (GitHub Changelog, Sep 29, About access tokens). (github.blog)
- Sweep code, images, and CI for
//registry.npmjs.org/:_authToken=lines andNODE_AUTH_TOKEN|NPM_TOKENusage; rotate anything found and move to OIDC. (pnpm .npmrc, CircleCI example). (pnpm.io) - Expect fewer successful credential-stuffing attempts against npm accounts, but more focus on CI-side theft and misconfiguration. Keep provenance on and monitor pipeline changes closely. (Generating provenance statements). (docs.npmjs.com)
Sources / References
- GitHub Changelog – npm security update: Classic token creation disabled and granular token changes (Nov 5, 2025): https://github.blog/changelog/2025-11-05-npm-security-update-classic-token-creation-disabled-and-granular-token-changes
- GitHub Changelog – Strengthening npm security: authentication and token management (Sep 29, 2025): https://github.blog/changelog/2025-09-29-strengthening-npm-security-important-changes-to-authentication-and-token-management/
- npm Docs – About access tokens (granular tokens, bypass 2FA, IP allowlists): https://docs.npmjs.com/about-access-tokens
- npm Docs – Creating and viewing access tokens: https://docs.npmjs.com/creating-and-viewing-access-tokens/
- npm Docs – Revoking access tokens: https://docs.npmjs.com/revoking-access-tokens/
- npm Docs – Requiring 2FA for package publishing and settings modification: https://docs.npmjs.com/requiring-2fa-for-package-publishing-and-settings-modification/
- npm Docs – Trusted publishing for npm packages (OIDC): https://docs.npmjs.com/trusted-publishers/
- npm Docs – Generating provenance statements: https://docs.npmjs.com/generating-provenance-statements
- pnpm Docs – .npmrc registry and authentication (_authToken and env usage): https://pnpm.io/9.x/npmrc
- CircleCI – Deploy to npm registry (classic token line example): https://circleci.com/docs/deploy-to-npm-registry/
- CISA – Widespread Supply Chain Compromise Impacting npm Ecosystem (Shai‑Hulud): https://www.cisa.gov/news-events/alerts/2025/09/23/widespread-supply-chain-compromise-impacting-npm-ecosystem
- GitHub Blog – Our plan for a more secure npm supply chain: https://github.blog/security/supply-chain-security/our-plan-for-a-more-secure-npm-supply-chain/
- GitHub Community discussion – Update on classic token removal timeline: https://github.com/orgs/community/discussions/179562