Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ADR 0005 — Sigstore + SBOM on every release

  • Status: Accepted
  • Date: 2026-07-05
  • Phase: 14 (per docs/IMPLEMENTATION-PLAN-v0.1.0.md)
  • Deciders: repository maintainers
  • Related: ADR 0006 (cargo-vet audit chain) — complementary provenance layer.

Context

Enterprise adoption in 2026 gates on three provenance artefacts a consumer can verify without trusting the maintainer’s private key material:

  1. SBOM (Software Bill of Materials) enumerating every transitive dependency the release was built against. Consumers diff it against their own Cargo.lock closure to detect drift.
  2. Cryptographic signature binding the SBOM to a verifiable identity — proving the artefact was produced by this repository’s release pipeline and not tampered with.
  3. Reproducible verification — the consumer’s verify step returns green or red with no manual judgment call.

The EU Cyber Resilience Act (CRA) enters effective enforcement across 2026 for products sold to EU customers. US Executive Order 14028 and its follow-on OMB memoranda already require SBOMs from federal software supply chains. Both name CycloneDX and SPDX as acceptable formats. Sigstore’s keyless model — signatures pinned to OIDC identities rather than long-lived key material — is the modern default, adopted by Kubernetes, npm, PyPI (Trusted Publishers), and others.

Before this ADR the workspace shipped only:

  • SPDX SBOM via anchore/sbom-action@v0 (introduced pre-plan).
  • Unsigned SBOM. No consumer-side verification possible.

Decision

Every release now ships:

  • sbom.spdx.json — SPDX 2.3 SBOM of the release ref.
  • sbom.cyclonedx.json — CycloneDX 1.5 SBOM of the release ref.
  • <file>.sigstore.json for each SBOM — a keyless Sigstore bundle (signature, certificate and transparency-log proof) produced by cosign sign-blob --yes --bundle. Releases up to v0.0.14 shipped <file>.sig and <file>.crt instead; cosign v3 made the bundle the required output in v0.0.15.

Signing runs on the github-release job of .github/workflows/release.yml. The job already carries the id-token: write permission required for GHA-issued OIDC tokens that sigstore’s Fulcio CA consumes.

Consumer runbook: pkg/VERIFY.md. Maintainer convenience: make verify-release TAG=v0.1.0.

Trust root

The verified certificate identity is pinned to:

  • Workflow: https://github.com/sebastienrousseau/rlg/.github/workflows/release.yml
  • Ref pattern: refs/tags/v[0-9]+.*
  • OIDC issuer: https://token.actions.githubusercontent.com

If a signature verifies against any other identity — a forked workflow, a non-tag ref, a different repo — it is untrusted regardless of what it claims to sign. This narrow trust root is the actual guarantee.

What is not signed

  • Published .crate artefacts on crates.io. crates.io does not currently accept sigstore signatures for uploaded crates. When it does (Trusted Publishers for Cargo is under active work upstream), a follow-up ADR will extend this policy.
  • The GitHub Release source tarball auto-generated by softprops/action-gh-release. That tarball is provided by GitHub and derives from the same tag commit, which is itself cryptographically signed by the maintainer (see CONTRIBUTING.md). Double-signing adds no independent guarantee.
  • Individual binaries. rlg is a library-first workspace; the three CLI binaries (rlg, rlg-mcp, rlg-report) install via cargo install, which builds from the signed SBOM’s manifest. A separate binary-signing pipeline lives on the roadmap once distribution channels (Homebrew, AUR, Scoop) come online.

Consequences

  • CI cost. ~90 s per release (SBOM generation + signing + upload). Negligible.
  • Contributor cost. None on the write path. On the verify path, pkg/VERIFY.md is the runbook and make verify-release is the one-shot convenience.
  • Zero maintainer key material. OIDC-based signing binds signatures to the workflow, not to a person. No key rotation ceremony, no offline signing ritual.
  • Public transparency log. Every signature is recorded in sigstore’s Rekor transparency log. Consumers can audit the log independently.

Alternatives considered

  • Detached PGP signatures (traditional model). Rejected — requires long-lived key material, key servers, and a rotation ceremony. Every predecessor project that adopted PGP is now migrating away.
  • In-toto attestations. Considered as a stronger provenance claim (attests the build steps that produced the artefact, not just the artefact bytes). Deferred: the marginal value over sigstore-signed SBOM is negligible for a library workspace of this size, and tooling maturity is uneven. Revisit at v0.2.0.
  • Reproducible builds. Bit-for-bit deterministic release artefacts. Not in scope for a Cargo-based workspace where the build environment (rustc version, host libc) is not the SBOM’s responsibility.

References