Skip to content

Publish to npm via trusted publishing instead of NPM_TOKEN - #48

Open
mikelittle wants to merge 1 commit into
mainfrom
remove-npm-token-secret
Open

Publish to npm via trusted publishing instead of NPM_TOKEN#48
mikelittle wants to merge 1 commit into
mainfrom
remove-npm-token-secret

Conversation

@mikelittle

@mikelittle mikelittle commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

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

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>
Comment on lines 22 to +25
node-version: 20
registry-url: 'https://registry.npmjs.org'

# Trusted publishing via OIDC requires npm >= 11.5.1; Node 20 ships npm 10.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

node-version: 20
will need to be updated to 24 also.

@@ -21,6 +22,10 @@ jobs:
node-version: 20
registry-url: 'https://registry.npmjs.org'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

This has since been fixed, but only in setup-node v7actions/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:

  1. Upgrade the action to v7 and keep registry-url:
      - uses: actions/setup-node@v7
        with:
          node-version: 24
          registry-url: 'https://registry.npmjs.org'
  1. Or just drop registry-urlregistry.npmjs.org is the default anyway, and --access public still works:
      - uses: actions/setup-node@v4
        with:
          node-version: 24

Comment thread RELEASING.md
Comment on lines +50 to +57
## 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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  1. Go to the altis-cli packageSettingsTrusted publisherGitHub Actions.
  2. Organization or user: humanmade
  3. Repository: altis-cli
  4. Workflow filename: release.yml (exactly, including the .yml)
  5. 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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 --provenance flag 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 public

We 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants