Software Supply-Chain Integrity: SLSA Provenance and Signing
A reference architecture for build provenance, hermetic builds, and cryptographic signing that makes a tampered artifact detectable before it reaches production.
The problem we are actually solving
A container image or a language package is, cryptographically speaking, an anonymous blob until someone attaches a claim to it and that claim is checked. The supply-chain incidents that matter — a compromised build server injecting a backdoor, a dependency substitution attack, a maintainer account takeover pushing a malicious point release — all share one property: the artifact that ends up running in production cannot be distinguished from a legitimate one by inspecting the artifact alone. You need a record of how it was built, signed in a way that cannot be forged or silently stripped, and a consumer that refuses to run anything lacking that record.
This is the problem SLSA (Supply-chain Levels for Software Artifacts) frames as a ladder rather than a binary. Level 1 is 'we have a build log.' Level 3 is 'the build ran in a hardened, isolated, non-persistent environment that generates provenance the build service itself cannot forge, because the build definition and the provenance generation are outside the control of the code being built.' Most organisations that claim to 'do SLSA' are actually at level 1 or 2 and calling it level 3 — the distinction is not cosmetic, because level 2 still trusts the build operator not to lie, and an attacker who compromises the build operator is exactly the threat model you are defending against.
The architectural question, then, is not 'how do we sign artifacts' — signing is the easy 20%. It is: what is the trust boundary, who or what is allowed to assert a claim inside it, and what happens at every point downstream when that claim is missing, malformed, or points to a build environment that no longer meets the bar it once did.
Provenance as the load-bearing artifact
The core data model is not the signature — it's the attestation. An in-toto attestation is a signed statement of the form 'subject X (a digest, not a name or tag) has predicate Y (build provenance, an SBOM, a vulnerability scan result, a test report), asserted by Z.' Treating the artifact digest as the only stable identifier matters more than it sounds: tags are mutable, registries can be told to repoint a tag, and any control built on tag-based identity is trivially bypassed. Every gate in the pipeline — build, test, scan, deploy — should reference the digest and attach its own attestation to it, so that by the time an artifact reaches a deployment target it carries a chain of independently signed claims, not one big claim from the build system alone.
The build step that generates provenance has to run somewhere the code being built cannot influence its own attestation. In practice this means the build executes inside an ephemeral, single-use runner with no persistent credentials baked into the image, the provenance-signing identity is a workload identity scoped to that one build invocation, and the provenance generator is a separate, non-configurable component of the build platform — not a step defined in the repository's own CI YAML, because if the repo can define the step that signs its own build, a compromised repo can just skip the signing or fabricate the claim. This is the practical meaning of 'the provenance generation is isolated from the code under build,' and it's the single detail that separates a real SLSA level 3 pipeline from a checkbox exercise.
Hermetic builds close a second gap: a build that pulls arbitrary dependencies from the network at build time has provenance that only describes the top-level source, not what actually got linked in. A hermetic build resolves all dependencies against a pinned, content-addressed set (a lockfile with digests, a vendored module cache, or a local artifact mirror) before build execution starts, and the network is cut off during the build itself. The resulting provenance can then make a much stronger claim: not just 'this repo, this commit,' but 'this exact set of inputs, verifiable byte-for-byte.' An SBOM generated as a build-time by-product, rather than reconstructed later by scanning the finished artifact, is materially more trustworthy for the same reason — it reflects what was actually resolved, not what a static scanner guesses from package manifests.
Signing: keyless identity over long-lived secrets
The classic failure mode in artifact signing is the long-lived private key: it sits in a CI secret store, it gets reused across hundreds of builds, and its compromise is both catastrophic and often invisible, because a stolen signing key produces signatures indistinguishable from legitimate ones. Sigstore's keyless model addresses this by binding the signing identity to short-lived, workload-scoped credentials — an OIDC token issued to the specific CI job (asserting 'this is workflow X, on commit Y, in repo Z') is exchanged for an ephemeral certificate from a public certificate authority, used to sign, and then the key material is discarded. There is no long-lived secret to steal because there is no long-lived secret. Every signature is instead logged to a public, append-only transparency log (Rekor), so a forged or unexpectedly-issued certificate is discoverable by anyone monitoring the log for their own identity, the same trust model Certificate Transparency uses for the web PKI.
Keyless signing is the right default for open, CI-native pipelines, but it is not universally appropriate — a regulated environment, an air-gapped build system, or an organisation that needs signing authority independent of a third-party CA's uptime will reasonably choose an HSM- or KMS-backed key instead, accepting the operational cost of key custody and rotation in exchange for not depending on an external transparency ecosystem. The architecturally important choice isn't keyless-versus-KMS in the abstract; it's that whichever mechanism is chosen, the signing identity must be scoped as tightly as the build that produced it, and verification at every consumption point must check identity, not just 'a valid signature exists.' A signature from the wrong workflow, the wrong repo, or an expired certificate should fail closed exactly as hard as a missing signature — a verifier that accepts any structurally valid signature has built a system that only proves an artifact was signed by someone, which is close to no control at all.
Enforcement has to live at admission, not at audit. A policy engine at the deployment boundary — an admission controller in front of the orchestrator, or a gate in the artifact registry itself — should refuse to pull, deploy, or promote any digest lacking a provenance attestation that satisfies the required SLSA level, a passing vulnerability-scan attestation, and a signature from an expected identity. Anything softer than a hard gate degrades into a dashboard nobody reads until after an incident.
Failure modes, and what we would deliberately not build
The most common failure isn't a cryptographic break — it's scope creep in what gets covered. Teams sign the final container image and stop there, leaving the base image, the build toolchain, and any code-generation or vendoring step outside the chain of custody. An attacker who compromises a widely-used base image or a code generator used at build time produces a downstream artifact that passes every check, because the checks only ever looked at the top layer. A defensible architecture treats provenance as transitive: the attestation for a build should reference the attestations of its own inputs, at least for anything built in-house, so a compromise several layers down is still traceable rather than laundered away at the first re-packaging step.
A second failure mode is key or identity sprawl without a revocation story. If every team's pipeline gets its own signing identity with no central registry of which identities are currently trusted, an offboarded pipeline or a decommissioned build system becomes a standing, forgotten trust anchor. The operational discipline this requires — an inventory of trusted signing identities, a defined revocation and rotation cadence, alerting on signatures from identities that haven't been used recently or shouldn't exist anymore — is unglamorous and gets skipped under deadline pressure, which is exactly why it's worth calling out explicitly rather than assuming it falls out of the tooling for free.
What we would not do is build a bespoke, in-house provenance format and signing scheme. The value of SLSA and in-toto attestations is that they're a shared, externally scrutinised vocabulary — a verifier, an auditor, or a downstream consumer's tooling can reason about your artifacts without learning a private schema, and you inherit the ecosystem's scrutiny of the format's failure modes instead of discovering your own. Similarly, we would not treat SBOM generation as a separate, bolted-on compliance task run against a finished image; divorced from the build, it becomes an approximation exercise rather than a source of truth, and it invites the same trust-boundary problem the rest of this architecture exists to close.
Building something like this?
We engineer secure, regulated, and AI-driven systems at this depth. Tell us what you are building and we will help you architect it.
Start Your Project