Skip to content

feat(upgrade): verify the sigstore signature on checksums.txt - #158

Merged
jkyberneees merged 4 commits into
mainfrom
feat/sigstore-upgrade
Oct 18, 2026
Merged

jkyberneees merged 4 commits into
mainfrom
feat/sigstore-upgrade

Conversation

@jkyberneees

Copy link
Copy Markdown
Contributor

Summary

bodek upgrade now checks the release's Sigstore signature before it trusts any checksum, matching odek's signed upgrades (odek #325). A matching checksum proves nothing when checksums.txt comes from the same, possibly tampered, release.

  • Verifier (cmd/bodek/upgrade_sigstore.go, standard library only, ported from odek): checks checksums.txt.bundle against the embedded Sigstore root and Rekor key:
    • the certificate chains to the Fulcio root at the time Rekor logged it;
    • the identity is pinned to https://github.com/BackendStack21/bodek/.github/workflows/release.yml@refs/tags/<exact tag>, the GitHub Actions OIDC issuer and this repository;
    • the message signature and digest match checksums.txt;
    • the Rekor hashedrekord entry is bound to the same digest, signature and certificate, and its signed entry timestamp and inclusion proof (with checkpoint) verify.
  • Upgrade flow: signature, then SHA-256, then install. A release without a bundle is refused, and so is any verification failure. --skip-signature falls back to checksum-only with a warning, for when the embedded root goes stale after a Sigstore rotation. bodek upgrade --help documents it, and unknown flags are now rejected.
  • API fallback: the HTML fallback's asset list now includes the bundle.
  • Downloads: an asset over the 256 MiB cap is named as oversized instead of being silently truncated (found in review).
  • Docs: README (install, usage, troubleshooting with the cosign verify-blob command), AGENTS.md, and a note next to the cosign pin in release.yml.

The release workflow already signs checksums.txt, so no pipeline change is needed.

Limits

The signature pins the tag being installed, not freshness: a compromised feed can still offer an older genuine release that is newer than the installed one (a dev build accepts whatever signed release the feed names). This is documented, as in odek. CT and RFC 3161 timestamps are not checked; the Rekor signed entry timestamp supplies the verification time.

Testing

  • The real v1.20.3 checksums.txt and bundle pass under the production trust root, and are refused for another tag, after tampering, and under a different root.
  • Synthetic bundles from an in-test CA cover each refusal (identity, issuer, repository, chain, signature, log binding, SET, proof, checkpoint, media type).
  • End-to-end upgrade tests: signed, unsigned (refused), --skip-signature, a bundle from another release (refused), and a failed bundle download.
  • An adversarial review found no way to install an unsigned binary. One suggested check (proof log index equals entry log index) was rejected because Rekor v1 shards its log, so the real bundle's indices legitimately differ.
  • make fmt, make vet, make lint (0 issues), make test (race) all pass.

🤖 Generated with Claude Code

jkyberneees and others added 4 commits October 18, 2026 08:52
bodek upgrade now verifies checksums.txt.bundle (Fulcio chain, release.yml
identity pinned to the exact tag, Rekor SET and inclusion proof) with the
standard library before trusting any checksum; a release without a bundle
is refused. --skip-signature falls back to checksum-only with a warning.
Ported from odek's verifier.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A body past the 256 MiB cap was silently truncated and surfaced as a
misleading checksum or signature failure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bodek f5d4d98 Commit Preview URL

Branch Preview URL
Oct 18 2026, 06:53 AM

@jkyberneees
jkyberneees merged commit e570f00 into main Oct 18, 2026
9 checks passed
@jkyberneees
jkyberneees deleted the feat/sigstore-upgrade branch October 18, 2026 06:56
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