Skip to content

ci(release): generate provenance in an isolated reusable workflow (SLSA L3) - #35

Merged
jmgilman merged 1 commit into
masterfrom
build/slsa-attest
Jun 28, 2026
Merged

ci(release): generate provenance in an isolated reusable workflow (SLSA L3)#35
jmgilman merged 1 commit into
masterfrom
build/slsa-attest

Conversation

@jmgilman

Copy link
Copy Markdown
Contributor

Summary

Moves both provenance attestations (binary checksums + container image) into a new reusable workflow attest.yml so signing runs in an isolated OIDC context the build job can't reach — the SLSA Build L3 isolation requirement — while still using GitHub's attestation API (gh attestation verify keeps working; the signer-workflow is now attest.yml).

This is PR 3 of 3 of the template-go-api session-015 migration (PR 1 #30 and PR 2 #31 are merged). It supersedes #32, which GitHub auto-closed when its stacked base branch was deleted after #31 merged; this branch is rebased directly onto master.

What changed

  • .github/workflows/attest.yml (new) — reusable workflow that attests binary checksums and/or image provenance from its own runner/OIDC identity; includes its own GHCR login for the image-referrer push.
  • release.ymlbinary-release-assets drops id-token/attestations and uploads checksums.txt as an artifact; a new attest-binaries job calls attest.yml. The inline image-provenance step moves to a new attest-image job. cosign signing and the syft SBOM attestation stay in-job. Verify commands point at attest.yml.
  • ghd.toml, stage_ghd_release_assets.py (+ test), release-dry-run.ymlsigner_workflow/expected_signerattest.yml.
  • Docs — README release path (SLSA-L3 explanation), DELETE_ME library-only deletion list.

Baked-in fixes from the downstream shakeout

Validation

attest.yml + release.yml + release-dry-run.yml parse cleanly; job DAG well-formed; stage_ghd_release_assets.py unit suite passes (6/6, incl. wrong-signer rejection and the attest.yml-signer case). The Kusari cache: false hardening from PR 2 is inherited.

The tag-only attest/publish path can't be reached by release-dry-run — validated by the forced prerelease-tag rehearsal after this lands.

🤖 Generated with Claude Code

…SA L3)

Move both provenance attestations (binary checksums + container image) into a
new reusable workflow `attest.yml`. A reusable workflow runs with its own OIDC
identity the calling build job cannot reach -- the SLSA Build L3 isolation
requirement -- while provenance still lands on GitHub's attestation API, so
`gh attestation verify` keeps working (the signer-workflow is now attest.yml).

- attest.yml (new): isolated attest job; attests binary checksums and/or image
  provenance; includes its own GHCR login for the image referrer push.
- release.yml: the binary job uploads checksums as an artifact and a new
  attest-binaries job calls attest.yml; the inline image-provenance step moves to
  a new attest-image job; cosign signing and the syft SBOM attestation stay
  in-job. Verification commands point at attest.yml.
- ghd.toml / stage_ghd_release_assets.py (+ test) / release-dry-run.yml:
  signer_workflow -> attest.yml.
- Docs: README release path, DELETE_ME library-only deletion list.

Baked-in fixes from the downstream session-015 shakeout: attest-binaries grants
packages:write (a reusable workflow cannot request more than its caller grants,
and the shared attest job declares it) [#29], and attest.yml logs in to GHCR
before the image attestation push [#33].

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jmgilman
jmgilman merged commit 2d57b10 into master Jun 28, 2026
11 checks passed
@jmgilman
jmgilman deleted the build/slsa-attest branch June 28, 2026 03:34
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