Skip to content

Drop registry-url so npm actually runs the OIDC exchange#7

Merged
Acro merged 1 commit into
masterfrom
fix-oidc-npmrc
Jul 24, 2026
Merged

Drop registry-url so npm actually runs the OIDC exchange#7
Acro merged 1 commit into
masterfrom
fix-oidc-npmrc

Conversation

@Acro

@Acro Acro commented Jul 24, 2026

Copy link
Copy Markdown
Owner

The v3.0.0 publish run passed all five gates, signed a provenance statement, then died with E403 Forbidden - PUT /simple-builder. The log contains no OIDC or trusted-publishing lines at all — npm never attempted the token exchange and issued the PUT unauthenticated.

Mechanism

npm runs the OIDC exchange only when it finds no usable credential for the registry. registry-url makes setup-node write _authToken=${NODE_AUTH_TOKEN} into an .npmrc unconditionally, so whether that line is harmless turns entirely on how the variable expands:

NODE_AUTH_TOKEN .npmrc line becomes Result
undefined (no env: block) literal ${NODE_AUTH_TOKEN} reads as a credential → OIDC skipped → 403
empty string (env: naming a nonexistent secret) empty value reads as no credential → OIDC runs → publishes

The sibling repo await-parallel-limit publishes with provenance and no repo secrets on the second spelling, which is what confirmed the mechanism. #6 removed the env: block and thereby moved this repo onto the first — that change is what turned a working configuration into a 403.

Fix

Omit registry-url entirely. That removes the question rather than depending on an expansion rule, and npm defaults to registry.npmjs.org regardless. See actions/setup-node#1551.

Adds a guard step immediately before publish that strips any _authToken line and asserts no credential is configured — without echoing the value into the public log. Otherwise this class of failure only appears as an opaque 403 at the very end, after ~5 minutes of gates, looking like an npmjs.com permissions problem rather than a runner config one.

AGENTS.md records both spellings, and that npm install -g npm@latest is load-bearing: Node 22 ships npm 10, which has no OIDC support and fails with ENEEDAUTH — the error await-parallel-limit hit on its own first release attempt.

No source or test changes.

🤖 Generated with Claude Code

The 3.0.0 publish run passed all five gates, signed a provenance statement,
and then died with `E403 Forbidden - PUT /simple-builder`. The log contains
no OIDC or trusted-publishing lines at all: npm never attempted the token
exchange and issued the PUT unauthenticated.

npm runs the exchange only when it finds no usable credential for the
registry, and `registry-url` makes setup-node write
`_authToken=${NODE_AUTH_TOKEN}` into an .npmrc unconditionally. Whether that
line is harmless turns entirely on how the variable expands:

  - undefined (no `env:` at all) — the line survives as the literal string
    `${NODE_AUTH_TOKEN}`, which reads as a credential and suppresses OIDC
  - empty string (`env:` naming a secret that does not exist) — expands to an
    empty credential, npm falls through to OIDC and publishes

The sibling repo await-parallel-limit publishes with provenance and no
secrets on the second spelling, which is what confirmed the mechanism.
Removing the `env:` block, as the previous commit did, moved us onto the
first — so that change is what turned a working configuration into a 403.

Omit registry-url instead: it removes the question rather than depending on
an expansion rule, and npm defaults to registry.npmjs.org regardless. See
actions/setup-node#1551.

Add a guard step before publish that strips any _authToken line and asserts
no credential is configured, never echoing the value. Without it this class
of failure only surfaces as an opaque 403 at the very end, which reads like
an npmjs.com permissions problem rather than a runner config one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Acro
Acro merged commit 3dead7f into master Jul 24, 2026
8 checks passed
@Acro
Acro deleted the fix-oidc-npmrc branch July 24, 2026 20:51
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.

1 participant