Skip to content

Add OIDC trusted publishing + staged npm releases via GitHub Actions#447

Closed
patocallaghan wants to merge 4 commits into
mainfrom
patoc/oidc-staged-publishing
Closed

Add OIDC trusted publishing + staged npm releases via GitHub Actions#447
patocallaghan wants to merge 4 commits into
mainfrom
patoc/oidc-staged-publishing

Conversation

@patocallaghan

Copy link
Copy Markdown
Member

Why?

Moves npm publishing onto short-lived, per-run OIDC credentials with a human approval step, removing the need for a stored long-lived npm token.

How?

Adds a release-triggered GitHub Actions workflow that authenticates to npm via OIDC (no token) and uses npm's staged publishing, so each release is queued for a maintainer to approve before it goes live.

Opened as an alternative for discussion against the existing migration:

The difference: this layers a human staged-approval gate (npm stage publish) on top of OIDC, rather than publishing directly on release.

Generated with Claude Code

jasonpraful added a commit that referenced this pull request Jun 15, 2026
…privilege)

Pull in security hardening from #447: SHA-pinned actions, env-var
indirection for release tag (script-injection fix), top-level least-privilege
permissions, persist-credentials: false, disabled package-manager cache,
concurrency + timeout, default-branch ancestry gate, dist-tag resolution,
and npm staged publishing via OIDC trusted publishing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jasonpraful added a commit that referenced this pull request Jun 15, 2026
* chore: migrate npm release from CircleCI to GitHub Actions

Use OIDC trusted publishing for npm releases instead of token-based auth.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: harden release workflow (OIDC staged publish, SHA pins, least-privilege)

Pull in security hardening from #447: SHA-pinned actions, env-var
indirection for release tag (script-injection fix), top-level least-privilege
permissions, persist-credentials: false, disabled package-manager cache,
concurrency + timeout, default-branch ancestry gate, dist-tag resolution,
and npm staged publishing via OIDC trusted publishing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: keep m4pro.medium runner, restore Socket Firewall check, trim workflow comments

- Revert CircleCI resource_class back to m4pro.medium (M4)
- Restore Socket Firewall registry verification in install-dependencies
- Remove redundant inline comments from release.yml (keep SHA version pins)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: drop workflow_dispatch trigger from release workflow

Release is now triggered only by publishing a GitHub Release; remove the
manual dispatch input and its now-dead github.event.inputs.tag fallbacks.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix: pin test/publish to the SHA validated in validate (tag-mutability TOCTOU)

validate emits the resolved, ancestry-checked SHA; test and publish check
out that SHA instead of re-resolving the mutable tag by name, closing the
window where a force-updated tag could ship a malicious build with provenance.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
patocallaghan and others added 4 commits June 23, 2026 10:37
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…d runtime

Apply the fixes validated on the passport-intercom and cli publish
workflows:
- verify: use fetch-depth: 0 and drop the manual `git fetch --depth=1`,
  so the default-branch ancestry check has the history it needs (the
  double-shallow version could only pass when the tag was the branch tip)
- add a top-level concurrency group so overlapping releases serialize
  instead of racing for a dist-tag
- add timeout-minutes: 15 to stage-publish

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pin to 9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 (v7.0.0).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@patocallaghan patocallaghan force-pushed the patoc/oidc-staged-publishing branch from 8a88a21 to 3631286 Compare June 23, 2026 09:37
@patocallaghan

Copy link
Copy Markdown
Member Author

Closed as redundant. main already has the full OIDC + staged-publishing release workflow at .github/workflows/release.yml, merged in #360 (2026-06-15). It includes everything this PR adds:

  • OIDC trusted publishing (id-token: write, no NPM_TOKEN)
  • npm stage publish --tag "$DIST_TAG" with prerelease→beta routing
  • the default-branch ancestry guard + pinned SHA, and npm ≥ 11.15.0
  • and chore: migrate npm release from CircleCI to GitHub Actions #360 removed .circleci/config.yml, retiring the old token-based publish job

This PR adds a second publish.yml that also triggers on release: published, so merging it would double-publish on every release. No further action needed here — the staged-publishing migration for this repo is already on main.

~ Automated via Claude

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