Skip to content

Require OIDC for npm publication - #22

Merged
raghubetina merged 1 commit into
mainfrom
codex/cli-oidc-only-publish-20260807
Aug 7, 2026
Merged

Require OIDC for npm publication#22
raghubetina merged 1 commit into
mainfrom
codex/cli-oidc-only-publish-20260807

Conversation

@raghubetina

Copy link
Copy Markdown
Contributor

Summary

  • remove NODE_AUTH_TOKEN and the persistent npm secret path from the publication job
  • require the exact GitHub-hosted runner, protected npm environment, OIDC permission, Node/npm toolchain, and single next publish command
  • reject any Actions secret or authentication-token reference in the release workflow
  • verify the release toolchain on every pull request before a protected release tag can be created
  • document exact npm trust-list identity, secret-free recovery, and unpublished-candidate immutability boundaries
  • preserve @firstdraft.com/cli@0.1.0, API contract 0.2, progress behavior, the next publication channel, and the unchanged latest tag

Verification

  • exact Node v24.18.0 and npm 11.16.0 checks
  • npm ci --ignore-scripts
  • npm audit (0 vulnerabilities)
  • npm run check (typecheck, lint, format, 150 tests, pack check, packed executable smoke)

Release boundary

The protected release workflow now authenticates to npm only through its exact trusted-publisher relationship and a short-lived GitHub OIDC credential. Package-level token disallow remains optional defense-in-depth and is not claimed here. This pull request does not merge, create a release tag, publish npm, move latest, or deploy anything.

Remove the obsolete persistent npm credential before the first ordinary release. Make the trusted-publisher identity, approval environment, toolchain, and secret-free workflow fail closed so authentication cannot fall back to a token.
@raghubetina
raghubetina merged commit d37d8b6 into main Aug 7, 2026
4 checks passed
@raghubetina

Copy link
Copy Markdown
Contributor Author

Post-merge retrospective. Removing NODE_AUTH_TOKEN and the persistent npm secret in favor of OIDC trusted
publishing, with the workflow additionally rejecting any Actions secret or auth-token reference, pinned to
the exact GitHub-hosted runner and protected npm environment with a single next publish command. The
negative check (CI fails if a token reference reappears) is what keeps the migration from silently
regressing when someone copies an old workflow snippet. The 2026-08-07 npm trust report in the firstdraft
evidence chain records the OIDC-only publication working with registry signature and provenance, so this
PR's design has an observed success on the record. Nothing to flag.

@raghubetina

Copy link
Copy Markdown
Contributor Author

This PR deletes a secret, and understanding why that is an upgrade is core modern release security.

The old way: a long-lived npm automation token lives in GitHub Actions secrets as NODE_AUTH_TOKEN. It
works, and it is a standing liability: anyone or anything that can read the secret (a compromised
dependency in the workflow, an over-permissioned collaborator, a leaked log) can publish as you, from
anywhere, until someone remembers to rotate it.

The new way: OIDC trusted publishing. The workflow run authenticates to npm with a short-lived identity
token that GitHub mints for that specific run, and npm is configured to accept publishes only from that
exact repository and workflow. There is no stored credential to steal; the "credential" is the workflow
identity itself, expiring in minutes. Supply-chain attacks that harvest tokens get nothing.

The two reinforcements are as instructive as the switch. The workflow pins the trusted context (exact
GitHub-hosted runner, protected environment with required reviewers, one publish command to one dist-tag),
because OIDC trust is only as narrow as the context you bind it to. And a CI check rejects any reappearance
of a token reference, so the migration cannot be undone by a copy-pasted snippet from an old tutorial.
Security migrations need that tripwire; entropy always drifts toward the pattern with more StackOverflow
answers.

If you publish gems or packages anywhere, this pattern (rubygems and npm both support trusted publishing)
is one afternoon of setup for a permanently smaller attack surface.

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