Publish npm packages with OIDC instead of a token

The seven @getsigit/* package names now exist on npm with a trusted publisher pointing at this workflow, so the bootstrap token blocks that were there to get the first scope-cutover release out can go. Two things that are easy to miss: Trusted publishing needs Node >= 22.14.0 as well as npm >= 11.5.1. The workflow upgraded npm but left .nvmrc on 20, so OIDC would have failed even with everything configured correctly. Bumped it to 22. Nothing else reads .nvmrc, and the wrapper package compiles to es2016, so the build is unaffected. Dropped --provenance from both publish calls. Trusted publishing emits provenance attestations on its own, and npm's docs say not to pass the flag. id-token: write is still required and stays.

paydii committed Aug 31, 2026 at 18:26 UTC 12fbcb868f7f77813c33d8ce8b8a0f70c32d29bd
3 files changed +17 -18
.agents/AGENTS.md
+6
@@ -267,6 +267,12 @@ Publishing splits into two groups. **Language registries** each get their own ta
267 workflow: `release-crates`, `release-npm`, `release-nuget`, `release-pypi`. The `npm/`, `nuget/`,
268 and `pypi/` dirs hold their wrapper-package templates.
269
270 +npm and NuGet authenticate with OIDC (Trusted Publishing), so neither needs a stored token. On
271 +npm that is configured per package, not per org: all seven `@getsigit/*` names carry a trusted
272 +publisher pointing at `release-npm.yml`, and a package added later needs the same setup or its
273 +publish step will fail. OIDC also requires npm >= 11.5.1 and Node >= 22.14.0, which is why the
274 +workflow upgrades npm and why `.nvmrc` cannot drop below 22.
275 +
276 **OS package managers** all publish somewhere outside this repo and all need checksums from the
277 GitHub release, so `release-github` builds the binaries, attaches the assets, and then dispatches
278 `release-homebrew`, `release-scoop`, `release-winget`, and `release-aur`. A dispatch failure in one
.github/workflows/release-npm.yml
+10 -17
@@ -101,20 +101,16 @@ jobs:
101 node-version-file: .nvmrc
102 registry-url: "https://registry.npmjs.org"
103
104 - # Trusted Publishing (OIDC) needs npm >= 11.5.1; the version bundled with
105 - # Node 20 is older, so upgrade before publishing.
104 + # Trusted Publishing (OIDC) needs npm >= 11.5.1. .nvmrc pins the Node
105 + # version (>= 22.14.0, also an OIDC requirement); npm still needs
106 + # upgrading past whatever ships with it.
107 - name: Upgrade npm for Trusted Publishing
108 shell: bash
109 run: npm install -g npm@latest
110
110 - # BOOTSTRAP: the @getsigit/* packages don't exist yet, and npm can't
111 - # configure a Trusted Publisher for a package that has never been
112 - # published. So the first scope-cutover release authenticates with a
113 - # token. Once the packages exist, configure Trusted Publishing on npmjs.com
114 - # for each package and delete this env block to go fully tokenless.
111 + # Authentication is OIDC: each @getsigit/* package has a Trusted
112 + # Publisher pointing at this workflow, so there is no token to leak.
113 - name: Publish platform package to NPM
116 - env:
117 - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
114 shell: bash
115 run: |
116 cd npm
@@ -167,7 +163,7 @@ jobs:
163 exit 0
164 fi
165
170 - npm publish --access public --provenance
166 + npm publish --access public
167
168 publish-npm-base:
169 name: Publish base NPM package (@getsigit/sigit)
@@ -197,17 +193,14 @@ jobs:
193 node-version-file: .nvmrc
194 registry-url: "https://registry.npmjs.org"
195
200 - # Trusted Publishing (OIDC) needs npm >= 11.5.1; the version bundled with
201 - # Node 20 is older, so upgrade before publishing.
196 + # Trusted Publishing (OIDC) needs npm >= 11.5.1. .nvmrc pins the Node
197 + # version (>= 22.14.0, also an OIDC requirement); npm still needs
198 + # upgrading past whatever ships with it.
199 - name: Upgrade npm for Trusted Publishing
200 shell: bash
201 run: npm install -g npm@latest
202
206 - # BOOTSTRAP: token auth for the first @getsigit release (see the platform
207 - # job above). Drop this env block once Trusted Publishing is configured.
203 - name: Publish base package to NPM
209 - env:
210 - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
204 shell: bash
205 run: |
206 cd npm/sigit
@@ -228,4 +221,4 @@ jobs:
221
222 npm install
223 npm run build
231 - npm publish --access public --provenance
224 + npm publish --access public
.nvmrc
+1 -1
@@ -1 +1 @@
1 -20
1 +22