Product1 publisher2 min readPublished
npm keeps accepting write tokens after you switch on OIDC trusted publishing
Trusted publishing swaps a stored npm token for a short-lived OIDC one, and it needs npm CLI 11.5.1, Node 22.14.0 and a hosted runner. The CLI falls back to the old token whenever the OIDC path is absent.
The Product Desk · Product desk

What happened
- npm's trusted publishing lets a CI/CD workflow authenticate to the registry over OpenID Connect, which npm says removes the need for long-lived npm tokens, with each publish using a short-lived signed credential.
- The feature requires npm CLI 11.5.1 or later and Node 22.14.0 or higher, so any migration starts with a version check on whatever runner builds the release.
- Self-hosted runners are not currently supported, and npm's documentation lists support for them as planned for future releases.
- Configurations created after Sep 03, 2026 default to allowing npm stage publish, and permitting direct npm publish is a choice the maintainer has to make at setup.
Compiled by The Product DeskSomething wrong?How this is made
Why it matters
- decision The last step is manual. Because the registry still honours tokens, someone has to decide to revoke the write credential, and until they do two credentials can still publish the package.
- constraint A team whose release job runs on its own runners is stuck with the long-lived token this quarter, so token rotation stays a scheduled human task for them while hosted-runner teams drop it.
- cost The cost lands on each repository: a runner image new enough for npm 11.5.1 and Node 22.14.0, plus an id-token permission added to each publishing workflow, for packages that may not have been touched in a year.
- exposure Someone auditing a package's supply chain cannot tell from a successful build which credential published it. The answer sits in the repository's secret store, and the registry's settings screen does not show it.
A maintainer who set up a trusted publisher in April and one who sets one up this week do not get the same publisher. npm's documentation says configurations created before May 20, 2026 were automatically set to allow `npm publish` only [11], and configurations created after Sep 03, 2026 are set to allow `npm stage publish`, with direct publishing a box you tick [13]. Between those dates you had to select at least one allowed action yourself [12]. What staging does is covered on a separate page [19].
The prerequisite list is short: npm CLI 11.5.1 or later, Node 22.14.0 or higher [3], and `id-token: write` in the workflow's permissions block, which the documentation calls "The critical requirement" [14]. npm's own GitHub Actions example pins `node-version: '24'`, two major versions above that floor [15][18], and turns off the setup-node cache with the comment "never use caching in release builds" [15]. GitLab pipelines need an `id_tokens` entry with `aud` set to "npm:registry.npmjs.org" [16]. On CircleCI you set `NPM_ID_TOKEN` and the CLI handles the exchange [17].
Whether any of that improves anything depends on the fallback order. The npm CLI detects an OIDC environment and uses it for authentication before falling back to traditional tokens [5], and the registry goes on accepting tokens and manual publishes for a package that has a trusted publisher configured [4]. Publishes that were working keep working, which is the point of an additive feature, and a green release job leaves open which credential did the publishing.
Two questions sort the decision for a given package: whether the release job runs on a hosted runner at GitHub Actions, GitLab CI/CD or CircleCI [8], and whether anything other than CI ever publishes it. Hosted runner, CI-only releases: the migration is finished when the write token is deleted and the re-run tag still publishes, and the manual rotation chore goes with it [21]. Hosted runner, occasional human publishes: the token that stays belongs to a person, and I'd name it after that person. Self-hosted runner: nothing to do yet [7]. A package released from two providers can register both, up to ten trusted publishers each [9].
What to watch
- Self-hosted runner support, which npm lists as planned, would remove the one exemption maintainers can currently point to.
- A per-package setting that refuses token-based publishes outright would turn an additive feature into an enforceable policy.
- Whether npm adds providers beyond GitHub Actions, GitLab CI/CD and CircleCI to the publisher list.