Conversation
Add a workflow that runs when a release is published: it downloads the Linux binary tarballs attached to the release, keyless-signs the raw binary inside each with cosign, and uploads a Sigstore bundle (.sigstore.json) plus a SHA-256 checksum back onto the release. Signing runs in the repository that owns the release so the OIDC identity recorded in the public Rekor transparency log is this repository.
docker-agent
left a comment
There was a problem hiding this comment.
Assessment: 🟢 APPROVE
The signing workflow is well-structured and follows cosign keyless-signing best practices. The cosign installer action is pinned to a commit SHA, set -euo pipefail is active, nullglob + a signed==0 guard correctly handles zero-assets scenarios, and COSIGN_YES suppresses interactive prompts. One low-severity defensive hardening opportunity is noted inline.
| # Sigstore bundle (protobuf spec) — verifiable by any Sigstore-conformant | ||
| # tool, not just the cosign CLI. Written as <name>.sigstore.json. | ||
| cosign sign-blob --yes --new-bundle-format \ | ||
| --bundle "${name}.sigstore.json" "$bin" |
There was a problem hiding this comment.
[LOW] No per-file existence check that .sigstore.json was written before bulk upload
After cosign sign-blob runs, the script increments signed but does not verify that ${name}.sigstore.json actually exists on disk before proceeding to the next iteration. The bulk gh release upload *.sigstore.json *.sha256 at the end relies on the glob expanding correctly.
Under the active set -euo pipefail, a non-zero cosign exit aborts the script — so the common failure path is covered. The gap is the theoretical edge case where cosign sign-blob exits 0 but fails to write the bundle (e.g., a disk-full or permission error on the temp dir). In that case nullglob would cause *.sigstore.json to expand to nothing at upload time, and gh release upload would receive no file arguments and either fail or upload nothing silently.
A defensive guard after cosign sign-blob would close this gap:
[ -f "${name}.sigstore.json" ] || { echo "::error::cosign did not write ${name}.sigstore.json"; exit 1; }
[ -f "${name}.sha256" ] || { echo "::error::sha256 file for ${name} not written"; exit 1; }
Add a workflow that runs when a release is published: it downloads the Linux binary tarballs attached to the release, keyless-signs the raw binary inside each with cosign, and uploads a Sigstore bundle (.sigstore.json) plus a SHA-256 checksum back onto the release.
Signing runs in the repository that owns the release so the OIDC identity recorded in the public Rekor transparency log is this repository.