npm Revoked the Skeleton Key, Not the Publish Key
Phase one landed early. Phase two is a CI provider problem.
On July 31 GitHub published a changelog entry saying npm granular access tokens configured to bypass 2FA can no longer perform sensitive account, organization, and package management actions. If you skimmed it and concluded your publish pipeline just broke, it did not. If you concluded nothing changed, that is also wrong. The interesting part of this release is the gap between what shipped and what the announcement tells you to do about it.
What actually changed
The restricted set, per the changelog: creating or deleting tokens, changing package access, maintainers, or trusted publishing configuration, and managing organization and team membership and their package grants. The community discussion tracking the deprecation adds the account-level operations — generating recovery codes, and changing your password, email, profile, or 2FA configuration. All of these now require an interactive 2FA challenge.
Publishing is not on that list. A bypass-2FA token can still push a new version today. The changelog is also explicit that GitHub personal access tokens, GitHub App tokens, and GITHUB_TOKEN in Actions are untouched: this is an npm registry credential change, not an Actions change.
A timing detail worth knowing before you plan an audit. The July 8 changelog and the community discussion both dated this phase to early August 2026. The July 31 entry describes the restriction in the present tense, so a team that scheduled its review for the first week of August is reviewing something already live.
Why phase one is the right half to ship first
The token docs explain the shape of the problem. The bypass flag applies to write-enabled granular access tokens, defaults to false, and when enabled it overrides both account-level and package-level 2FA requirements. That means a leaked bypass token was never merely a publish credential — it was an account credential. The discussion's stated rationale walks the chain: change the email, generate recovery codes, mint fresh tokens, add a maintainer, then publish malicious versions.
Phase one severs the escalation chain and leaves the publish path intact, and the split maps onto who has to do the work. Nothing in the July restrictions asks you to change a pipeline to comply. The January change makes every automated publisher rebuild how its release job authenticates. That is a five-month notice period for the half of the deprecation that carries a migration cost, and none for the half that does not.
The part the announcement leaves out
The migration guidance is one sentence: move automated publishing to trusted publishing over OIDC, or to staged publishing. Both docs pages carry constraints the changelog never mentions, and they decide whether that sentence applies to you.
Trusted publishing supports GitHub Actions on GitHub-hosted runners, GitLab CI/CD on GitLab.com shared runners, and CircleCI cloud. Self-hosted runners are listed as not yet supported, with support planned. It requires npm CLI 11.5.1 or later and Node 22.14.0 or higher, and a package can have exactly one trusted publisher configured at a time. Provenance attestations are generated automatically from GitHub Actions and GitLab but not from CircleCI, and automatic generation needs both a public repository and a public package — a public package built in a private repo gets none.
Staged publishing needs npm CLI 11.15.0 and Node 22.14.0. CI runs npm stage publish, a maintainer inspects with npm stage list, npm stage view <stage-id>, and npm stage download <stage-id>, then releases it with npm stage approve <stage-id> behind a 2FA challenge. Staging itself needs no 2FA; approving does. And the constraint that will bite someone in January: the docs state you cannot stage a brand-new package, so the first release of a package that is not on the registry yet is not something this path covers.
The objections in the discussion comments cluster in exactly that gap — self-hosted GitHub Enterprise runners, Azure Pipelines and Bitbucket with no npm OIDC integration, monorepo releases that would need approvals in batches, and people on ARM Linux or passkey-only setups who cannot easily enroll a second factor at all.
The claim, and what would falsify it
For most teams the July change costs nothing this quarter, and January 2027 is the real date. The binding constraint then will not be your token policy. It will be whether your CI provider can mint an OIDC token npm accepts. If you publish from a self-hosted runner, Azure Pipelines, Bitbucket, or anything else outside the three cloud providers the docs enumerate, the OIDC half of npm's recommended migration is not available to you today — what is left is staged publishing with a named human in the loop.
That claim is wrong the moment the trusted publishing docs add self-hosted runner support, which the page already lists as planned. Watch that page rather than the changelog — the constraint that decides your migration lives in the docs, not the announcement.
This is the line item from our production checklist that nobody budgets: publishing credentials with correct permissions and an audit trail, arriving late and with a deadline attached.
What to do this week
- List every write-enabled granular access token on the account and check the bypass flag. It defaults to false, so the exposed tokens are the ones someone turned it on for deliberately.
- Run
npm --versionandnode --versionon the publish runner. Trusted publishing needs 11.5.1 and 22.14.0; staged publishing needs 11.15.0 and 22.14.0. If you are below both, that upgrade is the first line item, not the last. - Identify the runner. GitHub-hosted, GitLab.com shared, or CircleCI cloud means the OIDC path is open today. Anything else means planning for staged publishing and a named person with a working second factor.
- Any package that has never been published to the registry: get its first version out before you retire the token. You cannot stage a brand-new package.
- Public package built from a private repo: expect no automatic provenance, and stop counting on it in your supply-chain story.
The verdict is split by runner. On the three supported providers, move to trusted publishing now — the discussion describes it as short-lived with no stored token, which is one fewer long-lived secret in your CI settings, and for public packages built in public repos on GitHub Actions or GitLab the provenance attestation is generated for you. Everywhere else, the five months between now and January are not for migrating a token. They are for deciding whether you change CI providers or accept a human back into a release pipeline you spent years automating.
Sources
- Restricting npm bypass-2FA granular access tokens
- Upcoming changes to npm 2FA-bypass granular access tokens (GATs)
- npm install-time security and GAT bypass2fa deprecation
- About access tokens — npm Docs
- Trusted publishers — npm Docs
- Staged publishing — npm Docs
- npm 12 Disables Install Scripts by Default to Reduce Supply Chain Risk
Turn this into a plan for your team.
One week, fixed fee: a working session with your team, a prioritized use-case backlog, and an ROI model for the opportunities worth chasing.