Skip to content

SLSA Compliance

SLSA (Supply-chain Levels for Software Artifacts) defines how much you can trust that an artifact was built from the source it claims, by the build it claims. This page states what bindy meets, what it does not claim, and how to check it yourself. The decision record is ADR-0010.

Status

SLSA v1.0 Build L3 for every release artifact: binary tarballs, install manifests, SBOMs and container images, from the release that ships ADR-0010 onward.

Artifact Provenance SBOM Signature
Binary tarballs (5 platforms) Build L3, slsa-github-generator generic generator bindy-<os>-<arch>.cdx.json, attested to the tarball Cosign keyless (.bundle)
install.yaml, scout.yaml, admission-policies.yaml Build L3, same provenance file n/a Covered by the provenance
SBOM files Build L3, same provenance file n/a Signed SBOM attestations
Container images (Chainguard, Distroless) Build L3, slsa-github-generator container generator, pushed to GHCR bindy-image-<variant>.cdx.json, attested to the image digest Cosign keyless

Not covered:

  • PR and main images (pr-*, main-*, latest) are CI images, not releases. They carry BuildKit provenance and SBOM attestations, are not signed, and are not Build L3.
  • Releases before ADR-0010 have Build L3 provenance for their binary tarballs only. Their images carry BuildKit provenance (not L3), and they ship no binary SBOMs.
  • Images rebuilt by rebuild-release-images.yaml (disaster recovery for releases older than v0.6.0) carry BuildKit provenance and a Cosign signature, not Build L3.

Build track requirements

Requirement (SLSA v1.0) Level How bindy meets it
Provenance exists L1 <version>.intoto.jsonl on every release; image provenance in GHCR
Hosted build platform L2 GitHub-hosted runners, builds defined in .github/workflows/build.yaml
Provenance is authentic L2 Signed with Sigstore keyless certificates for the generator workflow; recorded in Rekor
Provenance is unforgeable L3 Generated by slsa-github-generator reusable workflows in jobs separate from the build; the signing identity is never available to build steps
Build runs are isolated L3 Ephemeral GitHub-hosted runners per job; no state shared between runs except content-addressed artifacts and caches

The generators are referenced by tag (@v2.1.0), not commit SHA, because slsa-verifier checks the builder's tag. This is the one deliberate exception to the repository's SHA-pinning rule.

SBOMs

  • Format: CycloneDX JSON. Binaries: spec 1.5 from cargo-cyclonedx 0.5.9. Images: Syft's current CycloneDX output.
  • Content gate: make sbom-check fails the build unless an SBOM has a serial number, timestamp, generating tool, author, root component with name, version and purl, a name, version and purl for every package, and a dependency graph (the NTIA minimum elements). Supplier data on third-party crates is reported, not required: crates.io does not mandate it, and the purl names the distribution source.
  • Coverage: the binary SBOMs list the operator's full Rust dependency tree for each target platform. The image SBOMs list the base image's OS packages; Syft cannot read dependencies inside a Rust binary, so the binary SBOM of the same release is the source for those.
  • Integrity: every SBOM is a signed attestation (predicate type https://cyclonedx.org/bom) bound to the digest of the artifact it describes, and every SBOM file is also a subject of the release provenance.

Build inputs

  • Cargo.lock is committed and release builds pass --locked, so a release resolves exactly the reviewed dependency set.
  • cargo-audit runs on every PR, push and release; cargo-deny enforces the license, source and ban policies.
  • Base images are pinned by multi-arch digest in the Dockerfiles.
  • Every third-party GitHub Action is pinned by commit SHA, except the SLSA generators (see above).

Source controls

These are controls, not a SLSA Source-track level claim. Enforced on main by GitHub rulesets:

  • Changes land through pull requests; direct pushes, force pushes and branch deletion are blocked.
  • Commits must be signed (required_signatures), and CI verifies them.
  • Linear history is required.
  • The "PR Checks Passed" and "Verify Signed Commits" checks must pass.

Not enforced: a required number of approving reviews (the rulesets require 0, and there is no CODEOWNERS file), and organization admins can bypass the rulesets. Two-person review is therefore not a control bindy claims.

Not claimed

  • Hermetic builds. Builds fetch crates and base images from the network, constrained by Cargo.lock and digest pins.
  • Reproducible builds. Build Reproducibility describes how to rebuild and compare; no CI job enforces it yet.
  • Any SLSA Source-track level.

Verifying a release

From a checkout of this repository (tools: make slsa-verifier-install, make sign-verify-install, and the GitHub CLI):

VERSION=v0.8.0
gh release download "$VERSION" --repo firestoned/bindy \
  -p 'bindy-linux-amd64.tar.gz*' -p "${VERSION#v}.intoto.jsonl"

# 1. SLSA Build L3 provenance of the tarball (or any manifest or SBOM)
make verify-provenance ARTIFACT=bindy-linux-amd64.tar.gz VERSION=$VERSION

# 2. Cosign signature of the tarball
make verify-binary TARBALL=bindy-linux-amd64.tar.gz

# 3. The SBOM attestation bound to that tarball
make verify-sbom-attestation ARTIFACT=bindy-linux-amd64.tar.gz

# 4. An image, by digest
DIGEST=$(crane digest ghcr.io/firestoned/bindy:$VERSION)
make verify-image-provenance IMAGE=ghcr.io/firestoned/bindy@$DIGEST VERSION=$VERSION
make verify-sbom-attestation ARTIFACT=oci://ghcr.io/firestoned/bindy@$DIGEST
make verify-image IMAGE_TAG=$VERSION

Signed Releases has the same checks as plain cosign, slsa-verifier and gh commands.

Threats addressed

Mapped to the SLSA v1.0 threat model:

Threat Mitigation
Unauthorized change to source PR-only main, signed commits, required checks (no required approvals; see Source controls)
Compromised build process forges provenance Build L3: provenance generated and signed outside the build jobs
Artifact tampered after the build Provenance subjects and Cosign signatures pin every artifact's digest; slsa-verifier and cosign verify detect any change
Wrong or substituted dependency Cargo.lock + --locked, cargo-audit, cargo-deny, SBOM per artifact
SBOM swapped or edited SBOMs are signed attestations bound to their artifact's digest, and provenance subjects
Image tag moved to a different build Verify images by digest; install.yaml pins the operator image by digest

See Also