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.

API Overview

Base URL: https://build.confidential.ai

The Kettle API is Lunal's implementation of attested builds. It lets you submit source code and get back an attested build with provenance. Each build produces compiled artifacts alongside cryptographic provenance and attestation, so you can verify exactly what was built, from what source, and with which toolchain.

Provide either a git repo URL or a base64-encoded source archive as the source. Cargo and Nix projects are supported via auto-detection (a Cargo.lock or flake.lock is required).

Builds are asynchronous. You submit a build, then track its progress and download the result using the job_id returned by the submit call:

  1. POST /build — submit a build, get back a job_id.
  2. GET /build/{id}/events — stream progress as Server-Sent Events (SSE).
  3. GET /build/{id}/result — download the build outputs once the build completes.
MethodEndpointDescription
GET/healthLiveness check — returns ok
POST/buildSubmit a build, returns a job_id
GET/build/{id}/eventsStream build progress via SSE
GET/build/{id}/resultDownload build outputs (gzipped tarball)

Nonce

Every build is bound to a client-supplied nonce — a hex-encoded value of at most 16 bytes. The nonce is embedded into the attestation report so you can later prove the attestation was produced for your request and not replayed. Generate a fresh random nonce per build and keep it; you pass it to kettle verify when checking the result.

// Generate a 16-byte random nonce as hex
const bytes = new Uint8Array(16);
crypto.getRandomValues(bytes);
const nonce = Array.from(bytes)
  .map((b) => b.toString(16).padStart(2, "0"))
  .join("");

Single-build CVM

Each confidential VM accepts exactly one build. After a build has been accepted, further POST /build calls return 409 Conflict. Provision a fresh instance for each build.

Quick Start

# Build from a git repo
curl -X POST https://kettle-anthropic-api-demo.lunal.dev/build \
  -F "repo_url=https://github.com/owner/repo" \
  -F "ref=main" \
  -o build.tar.gz

# Build from a ZIP file
curl -X POST https://kettle-anthropic-api-demo.lunal.dev/build \
  -F "source=@source.zip" \
  -o build.tar.gz

# 3. Download the result tarball
curl https://build.confidential.ai/build/$JOB/result -o build.tar.gz