feat(release): sign binaries (SLSA L3) and container images (cosign) — OpenSSF Phase 3#531
Merged
Merged
Conversation
…s with cosign Closes the OpenSSF Scorecard Signed-Releases check (0/10 -> 10/10) and boosts CII-Best-Practices toward Silver/Gold criteria for cryptographic release signing. Two complementary supply-chain primitives, both Sigstore-backed: 1. SLSA Level 3 provenance for binary release zips ----------------------------------------------------- * New build-job output `hashes` = base64(sha256sum *.zip). * New `provenance` job in release.yml calls slsa-framework/slsa-github-generator/.github/workflows/ generator_generic_slsa3.yml@v2.1.0 with upload-assets: true. * It binds every release zip's sha256 to a single Sigstore-signed in-toto attestation (multiple.intoto.jsonl) and uploads it to the GitHub release alongside the zips. * SLSA generator is intentionally pinned by tag (not SHA): the SLSA verifier validates the workflow ref against its own allow-list of signed releases; SHA-pinning would break verification. Noted this exception in a comment and in Whats-New.md. 2. Cosign keyless signing for container images ----------------------------------------------------- * container-image.yml now installs sigstore/cosign-installer@v3.9.2 (SHA-pinned) and signs the published multi-arch manifest after podman manifest push. * Signs by digest (resolved via `podman manifest inspect | jq -r .digest`), not by tag -- atomic vs racy on subsequent pushes. * `cosign sign --recursive` covers the manifest plus each per-platform image under it. Both the tagged image and `latest` are signed. * Reuses the existing GHCR token via `cosign login` to avoid asking for a new secret. Docs ----------------------------------------------------- * SECURITY.md gains a "Verifying release artifacts" section with copy-pasteable slsa-verifier and cosign-verify commands. * Fixed the stale codeql-analysis.yml badge reference in SECURITY.md (the workflow is codeql.yml). Will be smoke-tested on the next real release tag. The Scorecard check itself looks at past releases, so it will start counting from the first release cut after this lands. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
Phase 3 of the OpenSSF Scorecard hardening effort. Closes the Signed-Releases check (0/10 → 10/10) and lays groundwork toward CII-Best-Practices Silver/Gold (which both require cryptographic release signing).
Note
The check looks at past releases, so the score will reflect 10/10 only after the next tagged release inherits these workflows. The plumbing itself is complete.
What changed
1. SLSA Level 3 provenance for binary release zips
buildjob outputhashes = base64(sha256sum *.zip).provenancejob in.github/workflows/release.ymlcalls the officialslsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0withupload-assets: true.sha256to a single Sigstore-signed in-toto attestation (multiple.intoto.jsonl) and uploads it to the GitHub release alongside the zips.slsa-verifier.Important
The SLSA generator workflow is intentionally pinned by tag, not SHA. The SLSA verifier validates the workflow ref against its own allow-list of signed releases; SHA-pinning would break verification. This is the only documented exception to the project's SHA-pinning rule. A comment in
release.ymland a note indocs/Whats-New.mdflag this for future readers.2. Cosign keyless signing for container images
container-image.ymlnow installssigstore/cosign-installer@v3.9.2(SHA-pinned).podman manifest push, resolves the multi-arch manifest tag to its content digest viapodman manifest inspect | jq -r '.digest'and signs by digest withcosign sign --recursive(atomic vs. racy when signing by tag).--recursivecovers the manifest plus each per-platform image under it.vX.Y.Z) andlatestare signed.cosign login— no new secret required.3. Docs
SECURITY.md— added a Verifying release artifacts section with copy-pasteableslsa-verifier verify-artifactandcosign verifycommands. Also fixed a stalecodeql-analysis.ymlbadge reference (actual workflow iscodeql.yml).docs/Whats-New.md— Phase 3 entry under Unreleased, including the SLSA tag-pinning rationale.Verification (manual, post-merge)
The actual signing/provenance generation only runs on tagged release pushes. Plan:
v0.44.2-rc1) to exercise the path end-to-end.idpscim-*.zipand.sha256files (existing behavior)multiple.intoto.jsonl(new — SLSA provenance)SECURITY.md; expect `PASSED: SLSA verification passed` and a cosign verify with a valid Fulcio cert.cosign verify ghcr.io/slashdevops/idp-scim-sync:v0.44.2-rc1with the OIDC issuer matcher.scorecard --repo=...locally and confirm Signed-Releases moves toward 10/10 (will fully tick over once a non-RC release is cut).Test plan (CI)
Buildworkflow passes on this PR (no behavior change for non-release pushes)CodeQLpassesScorecard analysisruns without the previous "imposter commit" error (fixed in PR fix(ci): pin scorecard-action and codecov to commit SHAs (not tag-object SHAs) #530)Follow-ups
main, CII Silver application (this PR unlocks the signing prerequisite)🤖 Generated with Claude Code