Provenance format
The files an attested build emits — manifest.json, provenance.json, and the attestation evidence — field by field, including buildType, the parameter split, resolvedDependencies, and builder.id.
Kettle emits three artifacts alongside a build's outputs. This page is their shape. For what they are for and how they map onto SLSA and in-toto, see Provenance & Standards.
What Kettle Produces
A complete Kettle build generates three files. Each serves a different purpose in the verification chain.
manifest.json
The manifest is a human-readable summary of the build. It contains:
{
"git_commit": "a1b2c3d4e5f67890abcdef1234567890abcdef12",
"git_tree": "7890abcdef1234567890abcdef1234567890abcde",
"lockfile_hash": "23b2e23aa04c93c350cac09ac73636e4ecedf564...",
"input_merkle_root": "72a97c73d0c59905c89dc7da145a5ecc3d809be5...",
"toolchain": {
"rustc_hash": "e6abf55ab1859e7c990be77fd593f5166...",
"cargo_hash": "51de284e8bb0d03dcee595a0fb1cb3a952..."
},
"artifacts": [
{ "name": "my-app", "hash": "1d1ea25c371d4f6de8d6e3c26fdad2238..." }
]
}This is for humans to inspect and debug. When something goes wrong, you look here to understand what inputs were used and what outputs were produced. The git commit and tree hash let you identify the exact source. The lockfile hash lets you verify dependency pinning. The input Merkle root is the cryptographic commitment to all inputs combined.
provenance.json
The provenance is a SLSA v1.2 statement in in-toto format. This is the machine-readable, interoperable record. It follows the SLSA specification exactly, which means other tools in the ecosystem can consume it without custom parsing.
The structure has two main sections:
buildDefinition describes the inputs to the build:
{
"buildDefinition": {
"buildType": "https://example.com/attested-build/v1",
"externalParameters": {
"repository": "https://github.com/org/repo",
"ref": "refs/heads/main"
},
"internalParameters": {},
"resolvedDependencies": [
{
"uri": "git+https://github.com/org/repo@refs/heads/main",
"digest": { "gitCommit": "a1b2c3d4..." }
},
{
"uri": "pkg:cargo/serde@1.0.228",
"digest": { "sha256": "9a8e94ea..." }
}
]
}
}The buildType identifies how to interpret the parameters. It's a URI that should resolve to documentation explaining the build process.
The externalParameters are the top-level inputs controlled by the user: which repository to build, which ref to check out, which entry point to use. These are untrusted from SLSA's perspective and must be verified downstream.
The internalParameters are set by the build platform itself. In attested builds, this might include TEE configuration or platform version information.
The resolvedDependencies capture what was actually fetched during the build. Notice the distinction: externalParameters might say "build from refs/heads/main", while resolvedDependencies records that this resolved to commit a1b2c3d4.... The dependencies use Package URLs (PURLs) for standardized identification. A Cargo dependency looks like pkg:cargo/serde@1.0.228?checksum=sha256:9a8e94ea....
runDetails describes the build execution:
{
"runDetails": {
"builder": {
"id": "https://example.com/tee-builder/v1"
},
"metadata": {
"invocationId": "build-12345",
"startedOn": "2024-01-15T10:30:00Z",
"finishedOn": "2024-01-15T10:35:00Z"
}
}
}The builder.id is the critical field. It identifies the build platform and represents the transitive closure of everything you're trusting to faithfully run the build and record provenance. For attested builds, this ID represents the TEE-based build system with its specific security properties.
The metadata provides operational information: when the build ran, how long it took, and an identifier for this specific invocation.
Evidence
The evidence file contains the TEE attestation report, base64-encoded. This is what roots everything in hardware.
The attestation report is signed by the TEE using keys that chain back to the hardware vendor's root of trust. A verifier can check this signature against the vendor's certificate chain to confirm the report came from genuine hardware.
Critically, the first 32 bytes of the report's custom data field contain the SHA256 hash of the provenance document. This cryptographically binds the attestation to the provenance. You can't take an attestation from one build and attach it to provenance from a different build. The hash must match.
The verification chain works like this:
- Verify attestation signature against hardware vendor's certificate chain
- Extract provenance hash from attestation report
- Verify hash matches actual provenance document
- Verify provenance contents (inputs, outputs, builder ID)
- Verify artifact hashes match provenance subjects
If any step fails, the verification fails. This chain ensures that the provenance is exactly what was generated inside the attested TEE, not something fabricated afterward.
The Provenance Structure in Detail
Understanding the provenance structure helps when debugging builds or writing verification policies. Let's look at each field more carefully.
buildType
The build type is a URI that identifies how to interpret the build definition. It encapsulates the build process independent of what platform ran it.
"buildType": "https://kettle.confidential.ai/cargo-build/v1"The URI should resolve to documentation explaining: what the build process does, what externalParameters and internalParameters mean for this build type, and how to initiate a build given this definition. Different build types exist for different toolchains (Cargo vs Nix) or different build configurations.
externalParameters vs internalParameters
The distinction matters for verification. External parameters are untrusted. They come from outside the build platform: a user requesting a build, a CI trigger, a webhook. Verifiers must check these against expectations.
Internal parameters are set by the platform itself. They're trusted because the platform is trusted. A verifier doesn't need to check them individually, though they might be useful for debugging or reproducibility.
In practice, external parameters should be minimal. The more you put in external parameters, the more a verifier needs to check. Good build type design pushes configuration into the source repository (where it's covered by the source commit hash) rather than into external parameters.
resolvedDependencies
This field captures what was actually used during the build, not just what was requested. The distinction matters because many inputs resolve dynamically:
{
"resolvedDependencies": [
{
"uri": "git+https://github.com/org/repo@refs/heads/main",
"digest": { "gitCommit": "a1b2c3d4e5f67890abcdef1234567890abcdef12" }
},
{
"uri": "pkg:cargo/serde@1.0.228",
"digest": { "sha256": "9a8e94ea..." },
"name": "serde"
},
{
"uri": "pkg:cargo/tokio@1.35.0",
"digest": { "sha256": "7b4c89..." },
"name": "tokio"
}
]
}A request to build "refs/heads/main" resolves to a specific commit. A dependency on "serde ^1.0" resolves to a specific version. The resolved dependencies record these resolutions.
Each dependency is a ResourceDescriptor with several optional fields: uri identifies the dependency, digest provides cryptographic verification, name is human-readable, downloadLocation says where it was fetched from if different from the URI.
Completeness is best-effort at L3. Ideally, every artifact fetched during the build would be recorded. In practice, some builds fetch things that are hard to track. The goal is to capture enough that a security team can investigate if something goes wrong.
builder.id
The builder ID identifies the transitive closure of everything trusted to faithfully run the build. For attested builds:
{
"builder": {
"id": "https://kettle.confidential.ai/tee-builder/v1"
}
}This ID should resolve to documentation explaining: the scope of what the ID represents, the claimed SLSA Build level, the accuracy and completeness guarantees of the provenance fields, and any fields that are generated by tenant-controlled processes rather than the trusted control plane.
A consumer's verification policy specifies which builder IDs they trust. The policy might say "I trust builds from https://kettle.confidential.ai/tee-builder/v1 at SLSA L3" while rejecting builds from other platforms.
See also
- Provenance & Standards — what these documents claim and which standards they satisfy.
- How attested builds work — the phases that produce them.