Skip to content

fix(ci): harden npm trusted publishing (OIDC) in release workflows#130

Merged
PAMulligan merged 2 commits into
mainfrom
ci/harden-npm-trusted-publishing
Jun 18, 2026
Merged

fix(ci): harden npm trusted publishing (OIDC) in release workflows#130
PAMulligan merged 2 commits into
mainfrom
ci/harden-npm-trusted-publishing

Conversation

@PAMulligan

Copy link
Copy Markdown
Contributor

Summary

Hardens npm Trusted Publishing (OIDC) in both release workflows so automated and manual publishes reliably authenticate tokenlessly. Fixes the manual workflow's ENEEDAUTH and the automated workflow's npm warn Unknown user config "always-auth".

Changes

Commit 1 — fix(ci): OIDC hardening (release-please.yml + publish-npm.yml)

  • Replace npm install -g npm@latest with a pinned npm install -g npm@^11, then assert npm ≥ 11.5.1 (sort -V guard) and prepend the freshly-installed npm's global bin to PATH via $GITHUB_PATH, so the publish steps cannot silently fall back to Node's bundled npm 10.x. The job now fails loudly instead of publishing under an OIDC-incapable npm.
  • Add a "Sanitize npm config for OIDC" step that strips the deprecated always-auth key and the placeholder _authToken from the .npmrc that actions/setup-node generates ($NPM_CONFIG_USERCONFIG), keeping the registry= line OIDC needs.
  • Document that each package's npm trusted publisher is bound to the repo + the exact workflow filename, so renaming either file breaks publishing until the npm trusted-publisher config is updated to match.
  • Stays tokenless — no NPM_TOKEN. Permissions unchanged (id-token: write; plus contents: write for release-please).

Commit 2 — ci(deps): action bumps to Node 24 majors (separate, revertible)

  • actions/checkout v4→v7, actions/setup-node v4→v6, pnpm/action-setup v4→v6, googleapis/release-please-action v4→v5.

Why this fixes the failures

  • ENEEDAUTH (manual): publish was running under Node 22's bundled npm 10.x, which predates OIDC, so npm never attempted trusted publishing and fell back to the empty placeholder token. Pinning + asserting + forcing the upgraded npm onto PATH guarantees npm publish runs under ≥ 11.5.1.
  • always-auth / OIDC (automated): actions/setup-node@v4 writes always-auth=false into its generated .npmrc; npm ≥ 11 rejects it as unknown config. The sanitize step removes it (and the placeholder token); setup-node@v6 also stops writing it at the source.

Test plan

  • Both workflows parse as YAML (js-yaml).
  • No @v4 action refs remain; bumped versions confirmed.
  • Needs a real run to confirm end-to-end: next release publish (release-please.yml on merge to main) authenticates via OIDC with no always-auth warning; manual publish-npm.yml dispatch (after temporarily repointing the package's trusted publisher to publish-npm.yml) publishes without ENEEDAUTH.

Notes

  • No committed .npmrc exists anywhere in the repo (root, widget/, create-claudius/, worker/, docs/) — the always-auth warning came solely from setup-node's runtime-generated file, which the sanitize step cleans in-job.

🤖 Generated with Claude Code

Paul Mulligan and others added 2 commits June 18, 2026 16:44
Both release-please.yml and publish-npm.yml could run `npm publish` under
Node's bundled npm (10.x), which predates OIDC trusted publishing and fails
with ENEEDAUTH, and they inherited a deprecated `always-auth` key from the
.npmrc that actions/setup-node generates (npm >= 11 warns "Unknown user
config always-auth").

- Replace `npm install -g npm@latest` with a pinned `npm install -g npm@^11`,
  then assert npm >= 11.5.1 and prepend the freshly installed npm's global bin
  dir to PATH so the publish steps cannot silently fall back to bundled npm.
- Add a "Sanitize npm config for OIDC" step that strips `always-auth` and the
  placeholder `_authToken` from setup-node's generated .npmrc, keeping the
  `registry=` line that OIDC needs.
- Document that each package's npm trusted publisher is bound to the repo and
  the exact workflow filename, so renaming these files breaks publishing until
  the trusted-publisher config is updated to match.

Stays tokenless: no NPM_TOKEN secret is introduced. Job permissions
(id-token: write, plus contents: write for release-please) are unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
GitHub is force-migrating Node 20 actions to Node 24. Bump to the latest
majors that run on Node 24:

- actions/checkout            v4 -> v7
- actions/setup-node          v4 -> v6
- pnpm/action-setup           v4 -> v6
- googleapis/release-please-action  v4 -> v5

Verified against our usage: release-please-action v5's only breaking change is
the Node 24 runtime (outputs and config/manifest interface unchanged);
setup-node v6 honours our explicit `cache: pnpm` and no longer writes the
deprecated always-auth key at the source; pnpm/action-setup v6 still accepts
`version: 9`; checkout v7's fork-PR restriction does not apply to our
push-triggered runs.

Kept separate from the OIDC hardening commit so it can be reverted on its own
if any action's new major changes behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@PAMulligan PAMulligan self-assigned this Jun 18, 2026
@PAMulligan PAMulligan added the bug Something isn't working label Jun 18, 2026
@PAMulligan PAMulligan moved this from Todo to Done in PMDS Open Source Roadmap Jun 18, 2026
@PAMulligan PAMulligan added this to the Quality & Hardening milestone Jun 18, 2026
@PAMulligan
PAMulligan merged commit 494292f into main Jun 18, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

Development

Successfully merging this pull request may close these issues.

1 participant