Attested Builds

Attested builds are a new approach to verifiable software distribution. Source code is compiled inside hardware-isolated environments that produce cryptographic proof linking binaries to their exact inputs.

Provenance Format and Standards

The evidence chain described in Architecture is only useful if its artifacts can be consumed by tools other than Kettle. A proprietary format would put attested builds in a silo. Only Kettle's own verifier could read them, and the rest of the supply-chain ecosystem (registries, scanners, deployment systems, audit tools) would have to integrate against a custom schema. Kettle therefore expresses provenance using two existing standards. The in-toto attestation framework provides the outer signed-statement structure, and SLSA Provenance v1.2 is the predicate carried inside it. This page describes how those formats are populated and how they map onto the SLSA Build levels.

in-toto Statement Layer

in-toto defines a generic envelope for statements about software artifacts. A statement names a set of subjects (the artifacts the claim is about, identified by digest), declares a predicateType (the schema of the claim), and carries the claim itself in the predicate field. Rather than wrapping the Statement in a separate signature envelope, Kettle commits the SHA-256 digest of its canonical serialization into the attestation report's report_data field, so the hardware-signed report is itself the binding evidence on the Statement. The concrete shape of a Kettle Statement is shown under SLSA Provenance Predicate.

Subjects are identified by content digest, not filename, so a Statement is bound to specific bytes rather than a reusable label. The predicate type is a URI identifying the schema by which the predicate field should be interpreted. The framework is deliberately extensible. SBOMs, code-review attestations, test-result attestations, and vulnerability scans all reuse the same outer structure with different predicate types, and a single artifact can accumulate multiple in-toto Statements over its lifecycle. Kettle emits one such Statement per build, with the SLSA Provenance v1.2 predicate type, and binds it to hardware via the attestation report described under TEE Environment Setup.

SLSA Provenance Predicate

The SLSA Provenance v1.2 predicate has two top-level sections: buildDefinition describes what was built, and runDetails describes how the build executed. An abbreviated example illustrates the fields Kettle populates:

{
  "_type": "https://in-toto.io/Statement/v1",
  "subject": [
    { "name": "my-app",
      "digest": { "sha256": "1d1ea25c371d4f6de8d6e3c26fdad2238..." } }
  ],
  "predicateType": "https://slsa.dev/provenance/v1",
  "predicate": {
    "buildDefinition": {
      "buildType": "https://kettle.confidential.ai/cargo-build/v1",
      "externalParameters": {
        "repository": "https://github.com/org/repo",
        "ref": "refs/heads/main"
      },
      "internalParameters": {
        "tee_platform": "sev-snp",
        "kettle_version": "0.4.0"
      },
      "resolvedDependencies": [
        { "uri": "git+https://github.com/org/repo@refs/heads/main",
          "digest": { "gitCommit": "a1b2c3d4..." } },
        { "uri": "pkg:cargo/serde@1.0.228",
          "digest": { "sha256": "9a8e94ea..." } }
      ]
    },
    "runDetails": {
      "builder": { "id": "https://kettle.confidential.ai/tee-builder/v1" },
      "metadata": {
        "invocationId": "build-12345",
        "startedOn":  "2026-01-15T10:30:00Z",
        "finishedOn": "2026-01-15T10:35:00Z"
      }
    }
  }
}

Three fields carry most of the security-relevant content:

  • buildType. A URI that fixes the schema of externalParameters and internalParameters. Different toolchains (Cargo, Nix, Bazel) and different build configurations get different build types, so verifiers can apply build-type-specific policy without parsing free-form fields.
  • externalParameters vs. internalParameters. External parameters are inputs supplied from outside the trusted control plane (which repository to build, which ref to resolve, which entry point to invoke), and a verifier must check these against expectations because they are attacker-influenceable. Internal parameters are set by Kettle itself inside the CVM (target platform, Kettle release, build-time configuration) and are trusted because the platform that emits them is trusted. Pushing build configuration into the source tree (where it is covered by the source commit digest) rather than into externalParameters reduces what a verifier has to police.
  • resolvedDependencies. Every input fetched during the build, recorded as a ResourceDescriptor with URI, digest, and (optionally) name and download location. Dependencies use Package URLs (PURLs), e.g. pkg:cargo/serde@1.0.228, so verifiers can cross-reference them against registries or vulnerability databases without bespoke parsers. The distinction between externalParameters (what was requested) and resolvedDependencies (what was actually fetched) is load-bearing: a request for refs/heads/main resolves to a specific commit, and the resolution is what the attestation witnesses.
  • builder.id. A URI identifying the build platform. Crucially, this represents the transitive closure of everything a verifier is trusting to faithfully run the build and emit accurate provenance, including the TEE platform, the Kettle release, and the measurement allow-list policy. Verifier policy is typically expressed as "accept builds with builder.id X at SLSA Build level L."

SLSA Build Levels

SLSA's Build track defines three levels of supply-chain integrity, summarised by the SLSA specification:

LevelSummaryKey requirements
L1Provenance existsEach artifact has provenance describing how it was built. May be unsigned. Catches mistakes, trivial to forge.
L2Hosted build platformProvenance is signed by a hosted build platform. Forging requires an explicit attack rather than a configuration error.
L3Hardened buildsBuild platform has strong tamper-resistance. Builds are isolated from one another. Signing keys are inaccessible to user-defined build steps.

Attested builds, as implemented by Kettle, target SLSA Build L3 with hardware enforcement of the L3 requirements:

L3 requirementHow Kettle satisfies it
Provenance generated by build platform's trusted control planeThe Kettle orchestrator runs in a separate VM on the host and launches a fresh CVM for each build, so the user-supplied build never executes alongside the control plane and cannot interfere with provenance assembly (see Build Execution and Provenance).
Provenance signed by build platformThe SHA-256 digest of the provenance is committed to the attestation report-data field, and the report is signed by the TEE platform attestation key (e.g. AMD VCEK) which chains to the CPU vendor's root of trust.
Builds isolated from one anotherEach build runs in its own fresh CVM, and cross-build interference is precluded by hardware memory encryption rather than by soft policy.
Signing keys inaccessible to user-defined build stepsThere is no in-guest signing key. The platform attestation key is held by the CPU's security processor and is unreachable from any guest software, including user-supplied build steps.

Hardware enforcement of these requirements is the substantive difference from a typical L3 implementation. The build platform's signing identity is not a software key sitting on a build host but the platform attestation key, held in silicon and reachable only via the platform's attestation interface. A compromised build script, a privileged operator on the host, and a malicious other tenant on the same machine all face the same wall.

Build Outputs Recap

Each Kettle build emits three artifacts whose roles map onto the format above:

  • provenance.json. The in-toto Statement described above, with the SLSA Provenance v1.2 predicate, serialized in canonical JSON. Contains the source commit and tree digest, the lockfile digest, the toolchain digests, and the input_merkle_root over all of them. This file's SHA-256 digest is what the attestation report's report-data field commits to.
  • evidence. The raw TEE attestation report. The report-data field carries SHA-256(provenance.json) (over the canonical JSON form), and the signature chains to the CPU vendor's root of trust. This is what roots the rest of the chain in hardware.

References