Skip to content

Receipts

A receipt is a signed record of one run: which agent ran, what it cost, and a SHA-256 hash of the run’s journal. Because the signature covers that hash, editing the event log after the fact makes the receipt fail verification. You issue a receipt for a run you own, and anyone can check it with the deployment’s published public key. Use receipts when an auditor or a customer needs evidence that does not depend on trusting your dashboard.

Signed receiptsA receipt signs the hash of the run's journal, so anyone can check what ran and that the record was not edited.
Completed runPOST …/receiptjournal_eventsordered event logSHA-256of the journalEd25519 signcanonical JSONrun_receiptsstored with the runJournal exportthe run's event logVerifierauditor · customer…/receipts/verifyno auth required/.well-known/pal-receipts
Swipe sideways to pan.

1. A run has finished

A receipt is requested for the run, scoped to the caller's tenant.

  • Control plane
  • Outside PAL
  • Data stores
Terminal window
# Issue and persist a receipt for a run ($TOKEN is a JWT or API key with runs:write)
curl -X POST http://localhost:8080/v1/runs/$RUN_ID/receipt \
-H "Authorization: Bearer $TOKEN"

The response is {payload, signature, algorithm}. The receipt is stored with the run, and issuing again for the same run replaces the stored one with a freshly signed receipt. Issuing is not refused for a run that has not finished: status records the state at issuance, so issue after the run is terminal.

The signature covers the canonical JSON of the payload: compact, with keys sorted alphabetically, so any JSON library that sorts keys reproduces the bytes.

Field Meaning
runId, tenantId, agentName Always present
agentVersion Digest of the agent’s current version; omitted when blank
status The run’s status at issuance
costUsd, tokensIn, tokensOut Accumulated cost and token counts
journalHash SHA-256 over the run’s journal_events rows in seq order, each hashed as seq|kind|payload plus a newline
issuedAt RFC 3339 timestamp
version Schema version, currently 1
softwareMeasurement Host-asserted launch measurement of the microVM; omitted for runs without one (Identity and secrets)
confidentialCompute Present only for confidential runs, with attested: false: the measurement is recorded, not verified

model and provider are reserved and currently always omitted. The journal is the record that durable execution replays on recovery, so one record backs both crash safety and provenance.

Algorithm When Who can verify
Ed25519 PAL_RECEIPT_ED25519_SEED is set (32 bytes, base64 or hex) Anyone with the published public key
HMAC-SHA256 The seed is unset, or invalid (the control plane logs the error and falls back) Only the deployment that holds the secret

Set the Ed25519 seed in any real deployment. The HMAC fallback is for dev.

The signing algorithm, key fingerprint and, for Ed25519, the public key are published without auth:

Terminal window
# Public key and fingerprint for offline verification
curl http://localhost:8080/.well-known/pal-receipts

You have three ways to check a receipt:

  1. The /proof page. The dashboard’s public page needs no sign-in. Paste the receipt.
  2. The API. POST /v1/runs/receipts/verify takes the receipt body and needs no auth. It returns {valid: true, runId, issuedAt, tenantId} or {valid: false, reason}.
  3. Locally. Fetch the public key once, canonicalize the payload, and run ed25519.Verify. This does not call your control plane.

When the run exists on the server, the verify endpoint compares the signature and the full payload against what it issued, so an edited costUsd or status carrying the original signature fails.

Full request and response shapes: REST API.