Skip to content

Verify a receipt#

Every agent run leaves a signed receipt when it ends (see Receipts). This page shows how to read it, and how to check it offline — its signatures, its place in the agent's chain and the steps it covers — with nothing but files.

Before you begin#

  • Any role in the workspace reads receipts.
  • astra on the computer that checks (Install the CLI). astra anemoi receipts verify needs no sign-in and no network.
  • For the downloads: ASTRA_TOKEN and WS as in the REST API page.

1. Read it#

Open the run and its Receipt tab: the run's version, policies' and input's and output's digests, Steps (Merkle root), Tokens · cost, the approvals it used, and the checks your browser made (machine signature, countersignature, chain). No receipt yet until the run ends; its machine sends it within seconds.

$ curl -sS "$WS/agents/researcher/runs/researcher-d2b797/receipt" -H "Authorization: Bearer $ASTRA_TOKEN" \
    | jq '{receipt: .receipt | {run, agent, agent_version, exit, totals, calls}, seq: .countersignature.claims.seq}'
$ curl -sS "$WS/agents/researcher/receipts?limit=10" -H "Authorization: Bearer $ASTRA_TOKEN" \
    | jq -r '.items[] | [.countersignature.claims.seq, .receipt.run] | @tsv'

receipts is the agent's chain, newest first (50 by default, at most 1 000).

2. Save the files#

File From Needed for
The receipt Download receipt, or GET $WS/agents/{agent}/runs/{run}/receipt Everything. Save it as served, byte for byte.
The cluster's keys GET $WS/identity/jwks (public) The countersignature. Save it once, when you trust the cluster, and reuse it.
The previous receipt Download the previous one, or the chain listing The chain link.
The exported steps Download the steps it covers, or GET $WS/tasks/{run}-0/trace?canonical=1&format=jsonl The Merkle root. While the machine still keeps them (7 days after the run is gone from it by default).
The node CA (PEM) optional Who issued the machine's certificate.
$ R=researcher-d2b797
$ curl -sS "$WS/agents/researcher/runs/$R/receipt" -H "Authorization: Bearer $ASTRA_TOKEN" -o $R.receipt.json
$ curl -sS "$WS/identity/jwks" -H "Authorization: Bearer $ASTRA_TOKEN" -o jwks.json
$ curl -sS "$WS/tasks/$R-0/trace?canonical=1&format=jsonl" -H "Authorization: Bearer $ASTRA_TOKEN" -o $R.trace.jsonl

3. Verify#

$ astra anemoi receipts verify researcher-d2b797.receipt.json --jwks jwks.json \
    --prev researcher-9c01aa.receipt.json --trace researcher-d2b797.trace.jsonl

It prints the receipt's run, agent and digest, then one line per check — ok, failed or skipped, with what it found — and verified or NOT verified. The exit status is 1 when a check failed.

Check Fails when
format It is not a version 1 receipt.
machine signature The receipt was changed after the machine signed it.
machine certificate The certificate does not name the machine, or (with --node-ca) was not issued by that CA. Skipped on a machine without a certificate.
countersignature It is not signed by a key of the JWKS, or it countersigns another receipt, machine key, run or machine. Without one: the cluster did not countersign it.
chain The receipt does not follow the one given (--prev) directly.
trace The lines are not the receipt's: their count or Merkle root differ.

What is not given is skipped, and said.

Flag Description
<receipt> The receipt (JSON, as served).
--jwks <file> The cluster's JWKS, saved.
--cluster <url> Fetch the JWKS from <url>/v1/identity/jwks now instead — the one step that is not offline. Not with --jwks.
--prev <file> The agent's previous receipt.
--node-ca <file> The node CA (PEM).
--trace <file> The exported steps: JSON lines, or the format=json export ({"lines": [...]}).
--json Print {ok, receipt_digest, checks: [{name, result, detail}]}.

astra anemoi receipt verify is the same command.