Publish to npm via trusted publishing instead of NPM_TOKEN - #48
Publish to npm via trusted publishing instead of NPM_TOKEN#48mikelittle wants to merge 1 commit into
Conversation
npm is now configured as a trusted publisher for this repo, so the OIDC exchange replaces the stored token. Upgrades npm to a version that supports trusted publishing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| node-version: 20 | ||
| registry-url: 'https://registry.npmjs.org' | ||
|
|
||
| # Trusted publishing via OIDC requires npm >= 11.5.1; Node 20 ships npm 10. |
There was a problem hiding this comment.
Latest NPM version is 12.0.2 and it requires atleast Node.js 22.22.2 https://github.com/npm/cli/blob/51c2bf81fa2c31547d0fec44fff2aaac3d9a9862/package.json#L265, so this will error out. We should use node-version: 24 here.
| node-version: 20 | |
| registry-url: 'https://registry.npmjs.org' | |
| # Trusted publishing via OIDC requires npm >= 11.5.1; Node 20 ships npm 10. | |
| node-version: 24 | |
| registry-url: 'https://registry.npmjs.org' | |
There was a problem hiding this comment.
altis-cli/.github/workflows/ci.yml
Line 19 in efd7995
| @@ -21,6 +22,10 @@ jobs: | |||
| node-version: 20 | |||
| registry-url: 'https://registry.npmjs.org' | |||
There was a problem hiding this comment.
It seemsregistry-url may stop the OIDC login from happening. When actions/setup-node is given registry-url, it always writes this line into .npmrc:
//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}
Now that we've removed the secret, NODE_AUTH_TOKEN is empty and older versions of the action even filled it with a dummy placeholder value. Either way npm sees an auth line, assumes we've already logged in with a token, and never does the OIDC exchange with npm. The publish then fails with ENEEDAUTH or a 404. People hit this on npm 11.14.1:
- registry-url writes _authToken line that breaks npm Trusted Publisher OIDC when no NODE_AUTH_TOKEN is set actions/setup-node#1551
- actions/setup-node registry-url interferes with OIDC trigger — example workflow fails with ENEEDAUTH when no NODE_AUTH_TOKEN npm/documentation#1960 (the example in npm's own docs has the same problem)
This has since been fixed, but only in setup-node v7 — actions/setup-node#1558 removed the dummy NODE_AUTH_TOKEN export, and it shipped in https://github.com/actions/setup-node/releases/tag/v7.0.0 (which also added official Trusted Publisher docs). We're on @v4, so we don't have it.
We can fix this in one of two ways:
- Upgrade the action to v7 and keep
registry-url:
- uses: actions/setup-node@v7
with:
node-version: 24
registry-url: 'https://registry.npmjs.org'- Or just drop
registry-url—registry.npmjs.orgis the default anyway, and--access publicstill works:
- uses: actions/setup-node@v4
with:
node-version: 24| ## One-time setup: trusted publishing | ||
|
|
||
| Publishing needs an npm access token stored as a repository secret named | ||
| `NPM_TOKEN`: | ||
| Publishing authenticates to npm as a | ||
| [trusted publisher](https://docs.npmjs.com/trusted-publishers) via OIDC — no | ||
| token or repository secret is required. | ||
|
|
||
| 1. On [npmjs.com](https://www.npmjs.com/) → **Access Tokens** → **Generate New | ||
| Token** → **Granular Access Token** (recommended) with **Read and write** | ||
| permission scoped to the `altis-cli` package. Use an **Automation** token so | ||
| it bypasses 2FA in CI. | ||
| 2. In GitHub: **Settings → Secrets and variables → Actions → New repository | ||
| secret**, name it `NPM_TOKEN`, and paste the token. | ||
| The workflow grants `id-token: write` (for the OIDC exchange) and upgrades npm | ||
| to a version new enough to support trusted publishing. |
There was a problem hiding this comment.
The new section says no token or secret is needed, which is true, but it doesn't say what someone does need to set up. If the trusted publisher config is ever lost, or someone sets this up for another package, there's nothing here to follow.
Worth spelling out, because npm matches these fields exactly and they're case-sensitive:
One-time setup: trusted publishing
Publishing authenticates to npm as a trusted publisher via OIDC — no token or repository secret is required.
A package admin configures this once on npmjs.com:
- Go to the
altis-clipackage → Settings → Trusted publisher → GitHub Actions.- Organization or user:
humanmade- Repository:
altis-cli- Workflow filename:
release.yml(exactly, including the.yml)- Environment: leave blank.
All fields are case-sensitive and must match exactly, or the publish is rejected.
The workflow grants
id-token: write(for the OIDC exchange) and uses a Node version whose bundled npm supports trusted publishing (npm 11.5.1+).
One thing to watch on step 5: the repo has no GitHub environments configured, so if anything is entered in npm's Environment field the publish will fail.
Also worth adding a line that the old npm automation token should be revoked on npmjs.com — this PR stops using it, but the token itself is still live until someone deletes it.
| @@ -42,5 +47,3 @@ jobs: | |||
|
|
|||
| - name: Publish to npm | |||
| run: npm publish --provenance --access public | |||
There was a problem hiding this comment.
Under trusted publishing, npm generates provenance on its own. From [npm's trusted publishers docs](https://docs.npmjs.com/trusted-publishers):
"When you publish using trusted publishing from GitHub Actions or GitLab CI/CD, npm automatically generates and publishes provenance attestations for your package."
"This happens by default—you don't need to add the
--provenanceflag to your publish command."
The docs list three conditions for the automatic behaviour: publishing via trusted publishing (OIDC), from a public repository, and a public package. All three are true for altis-cli, so we'd still get provenance with just:
- run: npm publish --access publicWe don't necessarilty need to change it thoug, keeping the flag is harmless and makes the intent obvious to anyone reading the workflow. I'm just flagging it only so we know it's no longer doing any work.
npm has been connected as a trusted publisher, so auth happens over OIDC and
the NPM_TOKEN repository secret is no longer needed.
Note: also upgrades npm to a version that supports trusted publishing.
🤖 Generated with Claude Code