ci: backport the workflow trust surface hardening - #19
Merged
Conversation
Backport of 513690f from main (#13) to the frozen 0.1 line. The three workflows this branch shares with main were byte-identical to main at the pre-hardening commit, so the change applied without conflict and the pins here now match main exactly. The release workflow on this branch still publishes: it holds `contents: write`, `packages: write`, and `id-token: write`, and uses them to push tags, publish to ghcr.io, and sign attestations. Leaving it on mutable major tags meant whoever could move `docker/build-push-action@v7` could publish a 0.1 release. Every action is now pinned to a full commit SHA with the version in a trailing comment; Dependabot updates the pin and keeps the comment. The two supporting changes come across as well: write scopes moved from the workflow default to the job that needs them in `release.yml` and `docs.yml`, and `persist-credentials: false` on every checkout except the release job, which pushes the nested `api/` module tag and breaks without it. That exception is recorded at the step and in AGENTS.md. This supersedes the Dependabot PR that proposed narrowing `actions/attest` and `docker/login-action` from `@v4` to a narrower — still mutable — tag. Verified: all 36 `uses:` in .github/workflows resolve to a 40-character SHA; each of the 14 distinct SHAs was cross-checked against the release tag named in its comment via the GitHub API; all three workflows parse as YAML; and the resulting `uses:` set is identical to main's.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backports
513690ff1from #13 to the frozen 0.1 line, and supersedes #18.Why this instead of #18
Dependabot opened #18 to move
actions/attest@v4→@v4.2.0anddocker/login-action@v4→@v4.5.2inrelease.yml. That swaps one mutabletag for a narrower mutable tag: it touches 2 of the 10 action references on this
branch and adds no real pinning guarantee, since a tag can still be moved.
release-0.1is not a dormant branch — itsrelease.ymlholdscontents: write,packages: write, andid-token: write, and uses them to push tags,publish to ghcr.io, and sign attestations.
mainclosed this gap in #13; therelease branch never received it.
What this does
The three workflows this branch shares with
mainwere byte-identical tomainat the pre-hardening commit, so513690ff1cherry-picked with noconflicts and the result matches
mainexactly.uses:acrossci.yml,docs.yml, andrelease.ymlnow reference a full commit SHA with the version in a trailingcomment. This also brings the two actions from ci(deps): bump the release-0-1-actions-updates group with 2 updates #18 to the versions
mainruns (
attestv4.2.1,login-actionv4.6.0) rather than the older pinsci(deps): bump the release-0-1-actions-updates group with 2 updates #18 proposed.
the single privileged job in
release.ymlanddocs.yml. Effectivepermissions are unchanged today; a job added later starts with nothing.
persist-credentials: falseon 9 of 10 checkouts. The release job is thedeliberate exception — it pushes the nested
api/module tag and breakswithout it. Recorded at the step and in AGENTS.md so a future Scorecard alert
is not "fixed" by breaking the tag push.
Deliberately out of scope
scorecard.ymlandsecurity.yml(also from #13) are not backported. Scorecardanalyses the default branch, and the govulncheck scheduled scan on
mainalready covers supported branches — neither belongs on the frozen line.
Test plan
uses:resolve to a 40-character SHAin its comment via the GitHub API (
git/ref/tags+ annotated-tag deref)uses:set is identical tomain's for the shared workflows