feat(release): adopt npm OIDC trusted publishing with provenance#1011
feat(release): adopt npm OIDC trusted publishing with provenance#1011kylemcd wants to merge 1 commit into
Conversation
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
03a5f27 to
f635535
Compare
f635535 to
5ac4ce1
Compare
Replace the long-lived NPM_TOKEN with short-lived OIDC trusted publishing and provenance. Split release.yml into version/build/publish/release jobs so id-token: write is isolated to a publish job that runs nothing but `yarn npm publish` (no install, no build, no dependency scripts) — the post-TanStack architecture. - Bump Yarn 4.9.1 -> 4.16.0 for scoped-package OIDC (behavior-preserving) - Publish via Yarn native OIDC; provenance attestations on every package - Registry-diff publish gate + fail-loud pre-flight for unenrolled packages - Preserve git tags + GitHub Releases via changesets/action (release job) - Add repository metadata to all packages (required for provenance) - Add trusted-publisher enrollment script; document OIDC publishing and the new-package bootstrap in RELEASES.md KNO-13137 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5ac4ce1 to
d118806
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit d118806. Configure here.
| # build/publish/release jobs. Read-only, unauthenticated. | ||
| - name: Detect unpublished packages | ||
| id: detect | ||
| run: node .github/scripts/list-unpublished-packages.mjs |
There was a problem hiding this comment.
Exit prerelease SHA mismatch
High Severity
After the auto exit-prerelease step bumps versions and pushes a new commit, the version job keeps running and Detect unpublished packages reads those updated local package.json files. build, publish, and release check out the original workflow github.sha, so they can build and publish different versions than the gate decided on.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit d118806. Configure here.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1011 +/- ##
=======================================
Coverage 63.55% 63.55%
=======================================
Files 208 208
Lines 9924 9924
Branches 1280 1280
=======================================
Hits 6307 6307
Misses 3592 3592
Partials 25 25 |



Description
Replaces the long-lived
NPM_TOKENinrelease.ymlwith npm OIDC trusted publishing + provenance, and restructures the release pipeline so the short-lived OIDC token is isolated to a job that runs nothing butyarn npm publish. Implements KNO-13137.Why. Today one static
NPM_TOKENcan publish every@knocklabspackage from anywhere if it leaks. OIDC swaps it for a token minted per run that expires in minutes and only works from this repo'srelease.yml, and provenance cryptographically links each published tarball to the exact commit + workflow run. The job split is the post-TanStack architecture: that compromise worked because the release job held publish power while also runningyarn install/build, so malicious dependency code read the token from runner memory. Here, install/build run in a job with no publish power, and theid-tokenjob runs no untrusted code.How —
release.ymlis now four jobs:id-tokenversionbuildyarn build:packages, uploadsdist(runs dependency scripts)publishyarn npm publish→ OIDC + provenancereleasechangesets/actionAlso in this PR:
enableScripts: trueandnpmMinimalAgeGate: 0pinned in.yarnrc.ymlto preserve pre-bump behavior;npmPublishRegistryset toregistry.npmjs.org..github/scripts/list-unpublished-packages.mjs) sobuild/publish/releaseonly run when there are new versions, plus a fail-loud pre-flight that points a new (unenrolled) package at the bootstrap runbook instead of a cryptic npm auth error.repositorymetadata (incl.directory) added/fixed on all 9 packages — required for provenance.scripts/configure-trusted-publishers.mjs(yarn release:configure-trust) to enroll trusted publishers, and the OIDC publishing + new-package bootstrap runbook folded intoRELEASES.md.Preserved (no functional regression): npm dist-tags (
latest/canary/rc),workspace:→ version substitution,--tolerate-republish, prerelease/canary→main promotion logic, git tags (incl. private example apps), and GitHub Releases with changelog notes.Validated locally:
build,type:check,lint,format:check, and the full test suite (878 tests) pass on Yarn 4.16;yarn --immutablepasses with the committed lockfile;yarn npm publishsubstitutesworkspace:ranges and engages--provenancewith no install. The OIDC handshake itself is exercised on the first real release (going direct tomain, no canary pre-flight).Todos
Out-of-repo rollout (npm org admin), not code changes:
npm login→yarn release:configure-trustproduction-releaseenvironment in GitHub settingsNPM_TOKENsecret (kept until then as a one-revert rollback)