Summary
The current bb update flow verifies release archives against sha256sums.txt, which protects against corruption but not against a release-host compromise where both the archive and checksum file are replaced.
This issue proposes a minimal trust-hardening change:
- keep the current release archives, checksum file, and GitHub provenance attestations
- add a signed checksum manifest artifact to each release
- teach
bb update to verify the checksum manifest signature before trusting it
Current State
Relevant current behavior:
- release workflow builds cross-platform archives and publishes
sha256sums.txt
- release workflow already generates GitHub provenance attestations
bb update downloads sha256sums.txt, downloads the release archive, compares the archive hash to the checksum entry, and replaces the installed binary
This is better than no verification, but the updater currently trusts an unsigned checksum file fetched from the same release source as the artifact.
Problem
If an attacker can modify the official release contents, they can replace:
- the release archive
sha256sums.txt
The current updater would still accept the malicious archive because the checksum file itself is not authenticated.
GitHub provenance attestations help with manual verification and auditability, but they are not currently the trust signal used by bb update.
Proposed Change
Implement a minimal hardening step while leaving most of the current system unchanged.
Release pipeline
Keep the existing release process, and add one new artifact:
sha256sums.txt.sig or sha256sums.minisig
The release workflow should:
- continue generating
sha256sums.txt
- sign the checksum manifest with a dedicated signing identity
- upload the signature artifact with the release
- continue generating GitHub provenance attestations
Updater
Change bb update from:
- download checksum file
- trust checksum file
- verify archive against checksum
- replace binary
to:
- download checksum file
- download checksum signature
- verify checksum file signature using an embedded public key
- verify archive against checksum
- replace binary
Scope
What should stay the same:
- release archive names and formats
sha256sums.txt
- current archive extraction and binary replacement flow
- existing GitHub provenance attestations
What should change:
- release workflow signs the checksum manifest
- updater verifies the signed manifest before using it
- docs explain the updater trust model more clearly
Why This Approach
This keeps the implementation small and targeted.
Checksums remain useful for integrity.
Signatures add publisher authentication for the updater.
Attestations remain useful for provenance, human verification, CI, and enterprise/audit scenarios.
This avoids redesigning the updater around attestation APIs while still materially improving trust.
Security Notes
This does not fully solve a malicious-publisher or compromised-signing-key scenario.
It does improve the common and important case where the release host or release publication path is compromised but the signing authority is not.
To reduce remaining risk over time:
- separate signing authority from release publication credentials
- prefer a dedicated signing identity or service
- keep self-update explicit and user-invoked
- continue recommending package-manager installs where appropriate
Acceptance Criteria
- release workflow publishes a signed checksum manifest alongside
sha256sums.txt
bb update refuses to trust unsigned or invalidly signed checksum manifests
bb update continues verifying archive hashes before replacement
- existing GitHub provenance attestations remain in place
- installation/update docs explain the distinction between checksums, signatures, and attestations
Open Design Choice
Pick one signing mechanism for the checksum manifest, for example:
minisign
cosign
- another simple verifier appropriate for embedding in the Go client
Preference should go to the smallest reliable implementation that keeps updater bootstrap complexity low.
Summary
The current
bb updateflow verifies release archives againstsha256sums.txt, which protects against corruption but not against a release-host compromise where both the archive and checksum file are replaced.This issue proposes a minimal trust-hardening change:
bb updateto verify the checksum manifest signature before trusting itCurrent State
Relevant current behavior:
sha256sums.txtbb updatedownloadssha256sums.txt, downloads the release archive, compares the archive hash to the checksum entry, and replaces the installed binaryThis is better than no verification, but the updater currently trusts an unsigned checksum file fetched from the same release source as the artifact.
Problem
If an attacker can modify the official release contents, they can replace:
sha256sums.txtThe current updater would still accept the malicious archive because the checksum file itself is not authenticated.
GitHub provenance attestations help with manual verification and auditability, but they are not currently the trust signal used by
bb update.Proposed Change
Implement a minimal hardening step while leaving most of the current system unchanged.
Release pipeline
Keep the existing release process, and add one new artifact:
sha256sums.txt.sigorsha256sums.minisigThe release workflow should:
sha256sums.txtUpdater
Change
bb updatefrom:to:
Scope
What should stay the same:
sha256sums.txtWhat should change:
Why This Approach
This keeps the implementation small and targeted.
Checksums remain useful for integrity.
Signatures add publisher authentication for the updater.
Attestations remain useful for provenance, human verification, CI, and enterprise/audit scenarios.
This avoids redesigning the updater around attestation APIs while still materially improving trust.
Security Notes
This does not fully solve a malicious-publisher or compromised-signing-key scenario.
It does improve the common and important case where the release host or release publication path is compromised but the signing authority is not.
To reduce remaining risk over time:
Acceptance Criteria
sha256sums.txtbb updaterefuses to trust unsigned or invalidly signed checksum manifestsbb updatecontinues verifying archive hashes before replacementOpen Design Choice
Pick one signing mechanism for the checksum manifest, for example:
minisigncosignPreference should go to the smallest reliable implementation that keeps updater bootstrap complexity low.