Which can test an attestation's predicate body: policy-controller's ClusterImagePolicy, Kyverno verifyImages, or a Notation trust policy?
answer
- Envelope signature versus payload contents
- predicateType present is not body checked
- One embeds a policy language, one has conditions
- A signature verifier cannot read claims
- Subject digest must match the image
basics
~20 sThe first two. A ClusterImagePolicy attaches a CUE or Rego policy to a named predicate type, and Kyverno evaluates conditions over predicate fields. A Notation trust policy verifies signatures only and has no language for predicate contents.
solid answer
~50 sSigstore's policy-controller lets a `ClusterImagePolicy` list `attestations`, each naming a `predicateType` and carrying a CUE or Rego policy evaluated against the decoded predicate, so you can require that, say, the builder identity in a provenance predicate equals your trusted builder. Kyverno's `verifyImages` rule does the equivalent: an `attestations` block names the predicate type and lists `conditions` matched against fields inside the body. Notation is a signature verifier: its trust policy expresses registry scopes, trust stores, trusted certificate identities and a verification level, and it can confirm a signed artifact is authentic, but it has no expression language for the contents of an attestation predicate. Two things are easy to conflate here. Requiring that an attestation of a given predicate type *exists* is much weaker than constraining what it *says*, and either is meaningless unless the verifier also checks the statement's subject digest matches the image being admitted.
code
json · 14 lines{
"_type": "https://in-toto.io/Statement/v1",
"subject": [
{ "name": "registry.example/api",
"digest": { "sha256": "9f2a...c31" } }
],
"predicateType": "https://slsa.dev/provenance/v1",
"predicate": {
"buildDefinition": { "buildType": "..." },
"runDetails": {
"builder": { "id": "https://example.com/build-workflow@main" }
}
}
}go deeper
Know that an attestation is a signed statement with a predicate type naming the kind of claim and a predicate holding the claim itself, and that checking it exists is different from checking what it says.
Be able to walk the four depths: envelope signature, signer identity, subject digest binding, predicate condition, and say which of the three verifiers can reach which depth and by what mechanism.
Demonstrate that you would stack signer identity with a predicate condition and a subject check in one rule, and explain the compromised-build-system path each layer closes that the others do not.
Own the consequence for tool selection: a requirement that mentions the inside of an attestation eliminates signature-only verifiers, and discovering that after an estate-wide rollout is an expensive reversal.
## What is actually being checked An attestation is a signed statement about an artifact. In the in-toto format it has four parts: `_type` identifying the statement format, `subject` listing artifacts with their digests, `predicateType` a URI naming the schema of the claim, and `predicate` the claim body itself. The signature is not inside the statement — the statement is the payload of a signed envelope, signed separately. That layering is the whole reason this question exists, because a verifier can stop at any of four depths: 1. **Envelope signature valid** — the payload has not been altered. 2. **Signer acceptable** — the identity behind that signature is one you named. 3. **Subject binds** — the `subject` digest equals the digest of the image you are about to run. 4. **Predicate body satisfies a condition** — the claim inside actually says what you require. Stopping at 1 and 2 gives you `signed by someone acceptable`. Only step 4 turns an attestation into a policy input, and only step 3 stops a perfectly valid attestation for a *different* artifact being replayed against this one. ## Implementation by implementation **Sigstore policy-controller.** A `ClusterImagePolicy` can list `attestations` entries, each with a name, a `predicateType`, and a `policy` whose `type` is `cue` or `rego` with the policy body inline. The decoded predicate is handed to that policy, so an arbitrary structural assertion over the body is expressible — a field equality, a set membership, a required list. This is the most expressive of the three because it embeds a general-purpose policy language. **Kyverno.** A `verifyImages` rule can carry an `attestations` block naming the predicate type and a set of `conditions` evaluated against fields inside the decoded predicate, in Kyverno's own expression style. Less general than dropping in Rego, entirely sufficient for the common shapes: this field equals that value, this field is in this list. **Notation.** Its trust policy is about *trust*, not about claims: registry scopes, trust stores of CA certificates, trusted certificate identities, verification level. It establishes that a signed artifact is authentic and unexpired against a CA you installed. It does not decode predicate bodies or express conditions over them. If your requirement is `the provenance must name this source repository`, a Notation trust policy alone cannot assert it — you would need whatever consumes the attestation to do that check elsewhere. ## Why presence-only checks are weak `An SBOM attestation must exist` sounds like a control and is not one. Whoever can sign the image can also attach an attestation of any predicate type saying anything at all; the check passes. It is worth something as a hygiene gate — it catches images built by a pipeline that never generated one — but it is not an integrity control. The same applies to exploitability statements: a VEX document's status is one of `not_affected`, `affected`, `fixed`, or `under_investigation`, and a `not_affected` claim is required to carry a justification. A verifier that only confirms a VEX attestation is present cannot tell a justified `not_affected` from an unjustified assertion; a verifier that can read the predicate can require the justification field to be there. ## Combining the layers The useful policies stack the checks. A single admission rule that says: the image must carry a provenance attestation whose envelope is signed by the release workflow identity, whose `subject` digest is this image's digest, and whose predicate names the expected builder — closes a compromised-build-system path that no single layer closes on its own. The signer identity stops an outsider from fabricating the attestation; the predicate condition stops a legitimately signed build from an unexpected builder or source; the subject binding stops a valid statement about a different artifact being pointed at this one. ## Choosing If your requirements are all of the form `signed by an acceptable identity`, any of the three does the job and you should pick on operational grounds. The moment a requirement mentions something *inside* an attestation, you have narrowed the field to implementations with a predicate expression language, and that constraint is worth surfacing early rather than discovering after a verifier has been rolled out estate-wide.
- Why is requiring that an SBOM attestation exists a weak control on its own?Because whoever can sign the image can attach an attestation of that predicate type containing anything, and the check still passes. Presence proves a pipeline step ran, not that the inventory is accurate or complete. It becomes a control only when combined with a constrained signer identity and, where it matters, conditions on what the body says.
- What must a verifier check about the statement's subject, and what goes wrong if it does not?It must confirm the subject digest equals the digest of the artifact being admitted. Otherwise a genuine, correctly signed attestation about some other image can be presented for this one, and the policy passes on evidence that was never about the thing you are running. It is the attestation equivalent of verifying a signature over the wrong bytes.
- Can a Notation trust policy be made to require that a build came from a specific builder?Not by itself. It can require that the artifact carries an authentic signature from a certificate identity you trust under a CA you installed, which indirectly says a particular signer vouched for it. It has no way to decode a provenance predicate and assert that a field inside it names a given builder; that check has to live in something with a predicate expression language.
saying these in an interview costs you the question
- Says checking the predicateType is the same as checking the predicate
- Assumes every signature verifier can also evaluate attestations
- Forgets to bind the attestation subject digest to the admitted image
- Treats the predicate as trustworthy without validating who signed the envelope
- Claims an attestation proves the claim is true rather than that someone asserted it