What Changed on September 18
GitHub's September 18, 2026 changelog adds a new permission option for npm granular access tokens: Read and write (stage only). A workflow holding such a token submits a version with npm stage publish. The registry rejects a direct npm publish with that token even if 2FA bypass is configured on it. A maintainer then reviews the staged version and approves it with two-factor authentication.
Two details decide how much this helps you. First, the feature is opt-in: nothing changes for a token you already hold until you create a new one with the stage-only permission. Second, npm targets January 2027 to remove direct publishing through bypass-2FA tokens. The changelog states that as a target, not a switch-off date, so treat it as a planning deadline rather than a guaranteed cut-over.
Note what a stage-only token still can do. The changelog says it retains other package write permissions, and names moving dist-tags and deprecating versions. A stage-only token is a narrowed publish route, not a read-only credential. If an agent could move latest to an older version with it, that is still a release action your review has to cover.
Both the changelog and the npm staged publishing documentation require npm CLI 11.15.0 or later and Node.js 22.14.0 or later, 2FA enabled on the account, and publish access to the package. The documentation adds that the package must already exist on the registry. Record the installed CLI and runtime versions on every runner before you attribute a failure to the token.
Which Pipelines Are Affected
The route being retired is any automation that authenticates with a granular access token that has 2FA bypass enabled and runs npm publish directly. That covers classic CI release jobs, semantic-release or changesets bots, monorepo publish scripts, and any AI release agent that has been given an NPM_TOKEN secret so it can cut releases without a human present. The agent case deserves attention because the token is often created once, shared across several packages, and never listed in the agent's tool inventory.
Pipelines already on trusted publishing are outside this change. OIDC connections are owned by our npm trusted publisher audit, which covers the union-of-permissions problem and the staged-versus-direct decision per connection. This page owns the token route only: which tokens exist, what they can do, and how to move each one to a staged release or out of service. The documentation notes that staged publishing also works with OIDC and still requires a maintainer's 2FA approval; if you are choosing between the two routes, read both pages before deciding.
Build the Token Inventory
List every publish-capable token the way you would list every secret reaching a privileged step: from the registry side and from the consumer side, then join the two. On the npm side, review each maintainer account's granular access tokens and their permission type. On the consumer side, search CI secrets, agent configurations, and .npmrc files for token references. Name the reference, never the value.
git grep -n -E 'NPM_TOKEN|_authToken|npm publish' -- '**/.github/workflows/*' '**/.npmrc' '**/package.json' '**/release*.{js,mjs,sh,yml,yaml}'
One row per package and token. Last use comes from the pipeline's run history or the token's last-used field on npm, whichever you can date. Give every row an owner and a removal date, and treat a row without last-use evidence as active until you can prove otherwise.
| Package | Token reference and holder | Permission type | Last use | Replacement route |
|---|---|---|---|---|
| example/sdk | NPM_TOKEN_SDK, release.yml | Read and write, bypass 2FA | 2026-09-12, run 4812 | OIDC, staged; token retired after positive test |
| example/cli | NPM_TOKEN_CLI, AI release agent | Read and write, bypass 2FA | 2026-09-16, agent session log | Stage-only token; maintainer approves with 2FA |
| example/internal-tool | NPM_TOKEN_LEGACY, no active consumer found | Read and write, bypass 2FA | No evidence since 2026-03 | Retire; revoke and re-run the consumer search |
| example/docs-theme | NPM_TOKEN_DOCS, publish.sh | Read and write, 2FA required | 2026-08-30, manual | Unaffected by the bypass change; still decide stage-only or OIDC |
The rows are illustrative, not npm defaults. The point of the last column is that the answer differs per package: a token nobody uses should be revoked, not migrated, and a token that already requires 2FA is not touched by the January 2027 plan even if you decide to narrow it anyway.
Run a Stage-and-Approve Test
Use a dedicated test package with harmless content, kept out of real dependency graphs. The following is a proposed method, not a report of a test performed for this article. Because the documentation requires an existing package, create it once with an ordinary publish from a maintainer session before any token test. Then create a granular access token with the stage-only permission scoped to that package alone, and store it as the only registry credential on the test runner.
- Positive stage: bump to a fresh version and run
npm stage publishwith the stage-only token. Expect a staged version, and confirm withnpm stage list <package>that it is listed and not installable at that version. - Negative direct publish: with the same token and another fresh version, run
npm publish. Expect the registry to reject the attempt; record the sanitized error and verify the version is absent from the registry. - Review: inspect the candidate with
npm stage view <stage-id>and, if you need the tarball,npm stage download <stage-id>. Compare the contents with the source revision that produced it. - Approve: a named maintainer runs
npm stage approve <stage-id>or uses the Staged Packages tab and the Approve button on npmjs.com. Both paths require 2FA. Confirm the version is now installable and which dist-tag it received. - Residual write check: with the stage-only token, attempt a dist-tag move on the test package. The changelog says this remains permitted; record the observed result so your review covers it.
Keep the positive and negative cases identical except for the command. Classify a duplicate-version error, an outdated CLI, or a registry timeout as inconclusive, not as a passing negative. The sources do not say how long a staged version is retained or how to discard one, so note what you observe rather than assuming a rule.
package: @example/stage-test
token_ref: NPM_TOKEN_STAGE_TEST (stage only, scoped to one package)
cli: 11.15.0 node: 22.14.0
positive_stage: 0.0.3 staged, stage-id recorded
negative_publish: 0.0.4 rejected, not on registry
approval: npm stage approve, 2FA, approver named
approved_state: 0.0.3 installable, dist-tag latest
dist_tag_move_with_token: permitted (observed)
decision_for_production: stage-only token for example/cli
Decide per Package: OIDC, Stage-Only Token, or Retire
Retire the token when the inventory shows no consumer or a consumer you can delete. Revoke it, re-run the consumer search, and watch the next scheduled release for a failure that reveals an undocumented user. This is the cheapest outcome, and it is worth checking first for tokens created before your organization adopted CI.
Move to OIDC when the release runs from a CI provider npm supports for trusted publishing and you can name the repository, workflow, and environment. Do that migration under the audit on the trusted publisher page, and revoke the token only after the OIDC route has passed its own positive and negative tests. Two working routes for one package is the state you are trying to leave.
Keep a stage-only token when the publisher cannot use OIDC, for instance an AI release agent that runs outside a supported CI identity, or a self-hosted job you are not ready to move. The agent submits a candidate; a maintainer approves with 2FA. Because the token still permits dist-tag moves and deprecation, pair it with the agent rollback and approval plan so an unexpected tag change has a defined response, and keep the wider tool boundary in the zero-trust architecture guide for AI agents.
Whichever route you pick, write it into the inventory row with an owner and a date. Schedule one review after the migration and one in early January 2027 to confirm that no bypass-2FA token remains attached to an active pipeline. The goal is to reach npm's target month with every token either narrowed to staging, replaced by an identity, or gone, and with a test another maintainer can repeat on the same package.