skip to content

In an in-toto attestation statement, what do the four top-level fields hold?

level: juniorimportance: should knowfreq 58%

answer

  1. the payload layer, not the signature
  2. says what it is about, and what it claims
  3. artifacts identified by hash, not by name
  4. a URI names the claim's schema
  5. the claim body sits under that URI

basics

~20 s

An in-toto statement carries _type (the statement format version), subject (the artifacts the claim is about, each identified by a cryptographic digest), predicateType (a URI naming the schema of the claim), and predicate (the claim's own content).

solid answer

~40 s

The statement is the payload layer of an in-toto attestation and it is deliberately small. `_type` is a fixed URI, `https://in-toto.io/Statement/v1`, telling a verifier this is a statement and which version of the format it follows. `subject` is an array; each entry has a `name` for humans and a `digest` map of algorithm to hash value that identifies the exact bytes the claim is about — the digest binds, the name never does. `predicateType` is a URI such as `https://slsa.dev/provenance/v1` that says what kind of claim follows and which schema to parse it with. `predicate` is that claim's body. Everything domain-specific lives in the predicate, so provenance, a test result or an SBOM can all ride the same subject-matching and verification path.

go deeper

for a junior

Be ready to name the four fields and say in one line what each is for, and to state that the digest, not the name, is what ties a claim to an artifact.

for a middle

Explain why the statement layer is generic: subject binding and format version are shared, while everything type-specific lives under a predicateType URI that a verifier dispatches on.

for a senior

Show the verification order you would actually implement — format version, subject digest match against bytes in hand, then predicate — and say what you do when no subject entry matches.

for a principal

Own the argument for why an open predicate-type set is worth the governance cost: one transport and one join key across every kind of claim, at the price of your policy having to enumerate which types and issuers count.

## Where the statement sits An in-toto attestation has three nested layers, and mixing them up is the usual source of confusion: 1. **The envelope** — the signed wrapper (DSSE). It holds the serialized payload, a payload type, and signatures. Nothing about *what* is claimed lives here. 2. **The statement** — the payload itself. It binds *which artifact* to *what kind of claim*. 3. **The predicate** — the body of the claim, whose shape is defined by whoever owns the predicate type. The statement is the generic layer: it is the same four fields no matter whether the claim is build provenance, a test report, or an inventory of components. ## The four fields ```json { "_type": "https://in-toto.io/Statement/v1", "subject": [ { "name": "api-server.tar.gz", "digest": { "sha256": "9b2c...e41f" } } ], "predicateType": "https://slsa.dev/provenance/v1", "predicate": { "buildDefinition": { "...": "..." } } } ``` **`_type`** is a constant URI identifying the statement format and its version. It is not the type of the claim — that is `predicateType`, and swapping the two in your head is the most common beginner error. Its practical job is version negotiation: a verifier that only understands one statement version rejects anything else outright rather than guessing at unfamiliar fields. **`subject`** is an **array** of entries. Each entry has: - `name` — a human label, typically a file name or a logical artifact name. It is convenience only. Two unrelated builds happily produce `app.jar`, and nothing about a name identifies bytes. - `digest` — a map from hash algorithm to the hex-encoded digest of the artifact, for example `{"sha256": "..."}`. Two distinctions matter and interviewers probe both. Several **entries in the array** mean the statement covers several artifacts — one build job that emits three bundles can attest all three in one statement. Several **keys inside one entry's digest map** are alternative hashes of *the same* artifact under different algorithms, so a verifier can pick one it trusts and supports. The verifier's rule is always the same: compute the digest of the bytes you actually hold and look for that exact value under an algorithm you accept. Matching on `name` is not verification. **`predicateType`** is a URI that acts as both a namespace and a schema pointer. `https://slsa.dev/provenance/v1` says "the predicate below is SLSA v1 provenance; parse it with that schema." The set of predicate types is deliberately **open** — anyone may define one — which is why the framework outlived its original purpose. Provenance is simply the most famous member of the set; SBOM documents, verification summaries, test results and vulnerability reports are all published as predicate types. **`predicate`** is the claim body, matching the schema that `predicateType` names. Some predicate types define no fields at all, in which case the type itself is the whole assertion. ## Why the split earns its keep The statement separates two questions that consumers need answered independently: - *Which bytes is this about?* → `subject` - *What is being claimed about them?* → `predicateType` + `predicate` That split means one piece of verification code handles every attestation type: check the signature, confirm the statement version, match the subject digest against the artifact in hand, then dispatch on `predicateType` to whatever policy knows about that kind of claim. Adding a new claim type requires no change to the transport, the signing, the storage, or the subject-matching logic. It also means a policy engine can require *several different* attestations about the same subject digest — provenance plus a test result plus a review record — and correlate them purely by digest, because the digest is the join key across all of them. ## What the statement does not do It does not carry a signature: the statement is what gets signed, not what does the signing. It does not assert that the predicate is *true* — it is a structured assertion, and whether you believe it depends on who signed it and whether your policy accepts that issuer for that predicate type. And a statement covering artifact A tells you nothing about artifact B, even if the same build produced both, unless B's digest is also in the subject array. ## Reading one in an interview Given a fragment, a strong candidate narrates it in order: this is a v1 statement; it covers these N artifacts by digest; the claim is of this type; and here is what the predicate says. A weak one jumps straight into the predicate and never checks that the subject matches the artifact under discussion.

  • Why does a subject entry carry a digest map rather than a single hash?
    The map is keyed by algorithm — `sha256`, `sha512` and so on — so the same artifact can be identified under more than one hash, and a verifier picks an algorithm it trusts and implements. Those are alternatives for one artifact. Several *artifacts* mean several entries in the `subject` array, which is a different thing entirely.
  • Is a statement still meaningful if the predicate body is empty?
    Yes. Some predicate types define no fields, so the type URI itself is the whole assertion — "this class of claim holds for these bytes". The weight is carried by the subject digest binding and by who signed the envelope; the predicate only adds detail for types that have detail to give.
  • Does `_type` tell you whether the attestation is provenance?
    No. `_type` identifies the statement format and version and is the same constant on every in-toto statement. The kind of claim is `predicateType`. A verifier checks `_type` to decide whether it understands the envelope's payload shape at all, then dispatches on `predicateType` to decide which policy applies.

Think of a shipping label: the tracking number identifies the exact parcel, a form code says which kind of declaration is attached, and the form itself holds the details. The parcel is identified by number, never by the words scribbled on the box.

saying these in an interview costs you the question

  • Says the subject name identifies the artifact
  • Thinks predicateType is the claim rather than its schema
  • Believes provenance is the only possible predicate
  • Assumes the statement itself carries the signature
  • Reads multiple digests in one entry as multiple artifacts

context