Verifiable receipts
When a headless agent finishes, you can ask the runtime for a signed receipt — tamper-evident, offline-verifiable proof of what actually ran. The receipt is signed over the run's journal hash, so any post-hoc edit to the run's event log invalidates the signature.
What a receipt attests
The receipt binds together the run's identity and the cryptographic hash of its event-sourced journal. Because the journal is the authoritative record of every step that executed, signing over its hash means the receipt attests to the exact sequence of steps that ran — not a summary that could drift from reality.
Payload fields
The signature (Ed25519 when LANTERN_RECEIPT_ED25519_SEED is set) covers the canonical JSON of a receiptPayload struct with these fields (alphabetically sorted keys, compact JSON, no whitespace):
agentName— always presentagentVersion— omitted when blankcostUsd— accumulated cost for the runissuedAt— RFC3339 timestampjournalHash— SHA-256 of the orderedjournal_eventsrowsmodel/provider— reserved; currently always omittedrunId— always presentstatus— the run's status at issuance (e.g.succeeded,failed,cancelled; issuing on a non-terminal run is not refused)tenantId— always presenttokensIn/tokensOut— prompt and completion token countsversion— schema version (currently1)confidentialCompute— present only for confidential runs (attested: false: the launch measurement is recorded, not verified)
The canonical JSON is produced by a three-step round-trip: marshal the struct, unmarshal into map[string]any, re-marshal (Go sorts map keys alphabetically on re-marshal). The result is compact JSON with keys in alphabetical order — reproducible offline with any JSON library that sorts keys.
Issuing a receipt
Issue and persist a signed receipt for a completed run:
POST /v1/runs/{id}/receiptThe receipt is an Ed25519 signature over the journal hash. It is persisted alongside the run, so it can be retrieved and re-verified later.
Verify with POST /v1/runs/receipts/verify (no auth required). If LANTERN_RECEIPT_ED25519_SEED is unset, the control plane falls back to an HMAC-SHA256 signature for dev. Set the seed in any real deployment.
Verifying offline
Verification needs no privileged access. The signing key's algorithm, fingerprint and (for Ed25519) public key are published at a well-known endpoint, so an external party can verify a receipt without calling back into your control plane:
GET /.well-known/lantern-receiptsAnyone holding an Ed25519 receipt and the public key published there can confirm the receipt was signed by this deployment's key. Matching the journal hash against the run's actual event log (i.e. nothing was altered after the fact) additionally requires the run's journal export. An HMAC-SHA256 receipt can only be checked by the deployment that holds the secret.
Why it matters
- Provenance. Cryptographic proof of exactly which steps a run executed.
- Tamper-evidence. Editing the journal after the fact invalidates the signature.
- Offline verification. The key fingerprint at
/.well-known/lantern-receiptslets external verifiers check a receipt without trusting (or contacting) your control plane.
Receipts share the same signing + verification machinery as run receipts elsewhere on the platform — see the API reference for the full request/response shape.