Trust, Provenance, and What "Verified" Means
"The image is signed" ends more security discussions than it should. SolarWinds was signed. Correctly, by the vendor's own key, on an artifact the vendor genuinely produced. Every verification a customer could perform would have passed, because the signature was answering a question nobody should have been satisfied by.
The Concept Explained
The word "verified" collapses three separate questions that have to be kept apart, because different mechanisms answer each and they fail independently.
INTEGRITY Has this changed since it was published?
answered by: a digest
AUTHENTICITY Who published it?
answered by: a signature
TRUSTWORTHINESS Should I run it?
answered by: policy, applied to claims about how it was made
A signature proves that the holder of a particular key asserted something about a particular artifact, and that the artifact has not changed since. It proves nothing about the quality of the artifact, the intent of the signer, or whether the process that produced it was clean. A compromised build system signs malicious output with a completely valid signature. "Signed" and "safe" are different claims, and conflating them is the single most common error in this field.
How It Works
What each mechanism actually gives you
A digest (a content hash) gives integrity, and only against changes after the digest was computed. It says "this is the same bytes." It says nothing about who produced them or whether they should exist. Codecov was detectable by digest comparison precisely because the attacker modified an artifact after publication.
A signature binds an identity to a digest. It adds "and this identity asserted it." That identity might be a key file, or a workload identity issued at build time (Module 5). It still says nothing about what the artifact does.
Provenance is a different kind of claim entirely: a statement about how the artifact was produced. Which source revision, which builder, which inputs, which parameters. Where a signature says who, provenance says how, and that is the question the SolarWinds compromise turns on.
Digest "these are the bytes"
Signature "and Acme's key asserted them"
Provenance "and they were produced by builder X, from commit abc123,
with these inputs, on this date, with no network access"
Only the third supports a policy statement like "reject anything not built by our build service from our repository," which is what would have made the SolarWinds injection visible.
An attestation is a signed claim
Put those together and you get the primitive Module 5 covers in depth:
An attestation is a signed statement about an artifact. It has a subject (the artifact, identified by digest), a predicate (the claim being made), and a signature (who is making it).
The predicate can be anything a verifier finds useful:
- Provenance: how it was built
- SBOM: what is inside it
- Test results: what passed
- Review: who approved it
- Scan results: what was found, and when
This is the shape that makes the whole model composable. Different parties assert different things about the same artifact, and a verifier decides which claims it requires, from which identities, before allowing a deployment. That decision is your policy, and it is the thing that has to exist for any of it to matter.
The verification gap
Here is the failure mode that makes most supply chain programmes ineffective, and it is worth being blunt about it:
Producing attestations is not verification. Something has to check them.
Organisations routinely sign every image, generate provenance for every build, attach an SBOM to every artifact, and then deploy without checking any of it. The pipeline emits claims into a void. An auditor sees signing enabled and marks it satisfied. An attacker who compromises the build system produces exactly the same claims, correctly signed, and nothing rejects them.
The uncomfortable questions worth asking of any existing setup:
- What happens if an unsigned image is deployed? If the answer is "it deploys," you have signing, not verification.
- What identity is required on the signature? If any valid signature passes, an attacker who can sign anything passes.
- What happens when the verification service is unavailable? If deployments proceed, the control is optional (Lesson 7.2).
Module 7 exists entirely for this gap.
Trust anchors: you always trust something
Verification never eliminates trust. It relocates it to something smaller and more deliberate.
Verifying a signature means trusting the key, or the identity provider that issued the signing certificate. Verifying provenance means trusting the build service that produced it. Verifying an SBOM means trusting the tool that generated it, and the build system it ran in.
"Is this image safe?"
-> verify signature -> trust the signing identity
-> verify provenance -> trust the build service
-> trust the build svc -> trust its operator, its own supply chain...
This is the recursion from Lesson 1.2, and the goal is not to terminate it. The goal is to arrive at a small, explicit, well-defended set of trust anchors instead of an enormous implicit one. Moving from "we trust every publisher of every transitive dependency" to "we trust our build service and our identity provider" is an enormous reduction in attack surface, even though it is not zero.
Being able to state your trust anchors out loud is a good measure of whether a programme is real.
The dangerous version of this is a control that looks like verification and is not. Checking that an image has a signature without checking whose it is. Requiring provenance without checking which builder produced it. Attaching an SBOM without validating it describes the artifact being deployed. Each satisfies a checkbox, each produces evidence for an audit, and each is trivially satisfied by an attacker who controls the build. Policy has to name the expected identity, not merely require the presence of a field.
What "verified" should mean in your organisation
The useful output of this lesson is a sentence your team can actually write down. Something in this shape:
An artifact is verified for production if it carries provenance issued by our build service, attesting that it was built from a commit on a protected branch of a repository we own, and that provenance is signed by an identity we recognise, checked at admission time, with deployment refused if the check cannot be performed.
Every clause is a decision: which builder, which repositories, which identities, checked where, and what happens on failure. A programme without that sentence is generating artifacts and hoping. A programme with it has something to implement, test, and audit.
In Production
- Write the verification statement first. It determines every tool choice afterwards, and it exposes disagreement early.
- Check identity, not presence. "Has a signature" is not a control; "signed by this identity" is.
- Decide the failure mode deliberately. Fail closed for production admission; anything else means the control is advisory (Lesson 7.2).
- Enumerate your trust anchors. If nobody can list them, the programme's actual boundary is unknown.
- Distinguish producing from verifying in reporting. "We sign 100% of images" and "we verify 100% of deployments" are very different statements, and only the second stops anything.
- Keep provenance and SBOM separate in your head. Provenance is how, SBOM is what. Different predicates, different uses, different failure modes.
Tradeoffs and Decision Framework
Strict identity policy against operational friction. Requiring a specific builder identity is strong and breaks every legitimate path you forgot about, including emergency rebuilds. Enumerate the exceptions deliberately rather than weakening the rule.
Fail closed against fail open. Fail closed means a verification outage stops deployments, including fixes during an incident. Fail open means the control is optional under exactly the conditions an attacker would create. Fail closed with a documented, audited break-glass path is the defensible position.
Few strong claims against many weak ones. One well-verified provenance attestation is worth more than a dozen unverified predicates. Add claims when something will check them.
Trust anchor breadth. Accepting many signing identities is flexible and enlarges the set of parties who can produce something you will run. Fewer anchors is stricter and creates coordination work.
Common Mistakes
Treating "signed" as "safe." It certifies origin, and a compromised origin signs malicious artifacts correctly.
Producing attestations nothing verifies. Evidence for auditors, protection for nobody.
Checking presence rather than identity. Any valid signature passing means an attacker's valid signature passes.
Failing open on verification errors. The control disappears in exactly the circumstances that matter.
Confusing provenance with an SBOM. How it was made against what is in it. Both useful, not interchangeable.
Assuming verification removes trust. It relocates trust to a smaller set of anchors, which is the actual win.
No written definition of verified. Without it, every team implements a different bar and the aggregate guarantee is the weakest one.