release: adopt sigstore (cosign) signing for release artifacts #413

Open
opened 2026-08-17 15:47:38 +00:00 by hexajon · 2 comments
Owner

Future enhancement, not launch-blocking.

Why. Releases currently ship checksums.txt plus checksums.txt.asc (PGP detached signature). Sigstore is where the ecosystem is heading: keyless signing via OIDC identity, signatures recorded in the Rekor public transparency log, no long-lived private key to protect or rotate, and users verify with cosign verify-blob against an identity instead of hunting for a public key.

What.

  • Sign checksums.txt (and/or each archive) with cosign sign-blob in the release pipeline. Publish the .sig plus certificate bundle as release assets.
  • Document verification (cosign verify-blob --certificate-identity ... --certificate-oidc-issuer ...) in the README and the releasing docs.
  • Decide whether the existing PGP .asc stays alongside (dual-sign) or is retired after a deprecation window.
  • Check goreleaser's native cosign support (signs: with cmd: cosign). This is likely just config, not custom scripting.
  • CI consideration: keyless signing needs an OIDC token from the CI provider. Verify what Forgejo Actions can offer, or fall back to a self-managed cosign key pair stored as a CI secret.

Acceptance criteria.

  • A release ships sigstore signature material for its artifacts.
  • Verification instructions are documented and work as written on a clean machine.
  • The PGP-vs-cosign coexistence decision is recorded (ADR or note in the releasing docs).
Future enhancement, not launch-blocking. **Why.** Releases currently ship `checksums.txt` plus `checksums.txt.asc` (PGP detached signature). [Sigstore](https://sigstore.dev/) is where the ecosystem is heading: keyless signing via OIDC identity, signatures recorded in the Rekor public transparency log, no long-lived private key to protect or rotate, and users verify with `cosign verify-blob` against an identity instead of hunting for a public key. **What.** - Sign `checksums.txt` (and/or each archive) with `cosign sign-blob` in the release pipeline. Publish the `.sig` plus certificate bundle as release assets. - Document verification (`cosign verify-blob --certificate-identity ... --certificate-oidc-issuer ...`) in the README and the releasing docs. - Decide whether the existing PGP `.asc` stays alongside (dual-sign) or is retired after a deprecation window. - Check goreleaser's native cosign support (`signs:` with `cmd: cosign`). This is likely just config, not custom scripting. - CI consideration: keyless signing needs an OIDC token from the CI provider. Verify what Forgejo Actions can offer, or fall back to a self-managed cosign key pair stored as a CI secret. **Acceptance criteria.** - A release ships sigstore signature material for its artifacts. - Verification instructions are documented and work as written on a clean machine. - The PGP-vs-cosign coexistence decision is recorded (ADR or note in the releasing docs).
Author
Owner

Unblocked: the CI migration this depends on landed, and the pipeline is live and green on the org runner (#47, first green run 2026-07-15). Findings for the signing design, from that work:

  • Keyless/OIDC cosign is OFF the table on this stack. Forgejo Actions on a self-hosted forgejo-runner provides no GitHub-Actions-style OIDC identity token for sigstore to bind to, and nothing on the roadmap changes that here.
  • That leaves KEY-BASED cosign: a cosign keypair I provision, private key stored as a repo or org Actions secret (the runner and secrets plumbing for that now exist and are exercised), public key published alongside the existing PGP key. Releases would then carry both PGP signatures (current, kept) and cosign signatures, plus SBOM attestations if desired.
  • goreleaser has first-class cosign hooks, so the implementation once decided is config plus runbook, not new machinery.

Two open questions gate any build work, and I have not settled either: (1) whether to provision a cosign keypair at all, and where its private half lives (repo secret, org secret, or offline with manual signing); (2) whether cosign coexists with PGP or eventually replaces it in the verification docs. Until those are settled this stays parked, and no code work is queued.

Unblocked: the CI migration this depends on landed, and the pipeline is live and green on the org runner (#47, first green run 2026-07-15). Findings for the signing design, from that work: - Keyless/OIDC cosign is OFF the table on this stack. Forgejo Actions on a self-hosted forgejo-runner provides no GitHub-Actions-style OIDC identity token for sigstore to bind to, and nothing on the roadmap changes that here. - That leaves KEY-BASED cosign: a cosign keypair I provision, private key stored as a repo or org Actions secret (the runner and secrets plumbing for that now exist and are exercised), public key published alongside the existing PGP key. Releases would then carry both PGP signatures (current, kept) and cosign signatures, plus SBOM attestations if desired. - goreleaser has first-class cosign hooks, so the implementation once decided is config plus runbook, not new machinery. Two open questions gate any build work, and I have not settled either: (1) whether to provision a cosign keypair at all, and where its private half lives (repo secret, org secret, or offline with manual signing); (2) whether cosign coexists with PGP or eventually replaces it in the verification docs. Until those are settled this stays parked, and no code work is queued.
Author
Owner

Parking this. Keyless/OIDC signing is impossible on the self-hosted runner. Key-based cosign duplicates the trust model of the PGP signing already shipping: a second long-lived private key to protect and rotate, bought for a modest verifier-UX win. Not worth the surface area right now.

Revisit triggers: keyless becomes possible on this stack (the runner grows an OIDC identity), or users actually ask for cosign/Rekor verification. Implementation stays cheap whenever that happens, because goreleaser has first-class cosign hooks, so it is config plus runbook.

Parking this. Keyless/OIDC signing is impossible on the self-hosted runner. Key-based cosign duplicates the trust model of the PGP signing already shipping: a second long-lived private key to protect and rotate, bought for a modest verifier-UX win. Not worth the surface area right now. Revisit triggers: keyless becomes possible on this stack (the runner grows an OIDC identity), or users actually ask for cosign/Rekor verification. Implementation stays cheap whenever that happens, because goreleaser has first-class cosign hooks, so it is config plus runbook.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sixfold-space/madtea#413
No description provided.