Docs menu
Guides

Verify a capsule

Anyone holding a capsule or receipt can verify it — in the browser, on the command line, or as a library. Every path runs the same open-source verifier. The command line checks a ledger — digests, chain links, and producer signatures; the browser and the library check a receipt — the signature and the inclusion proof.

In the browser

The fastest way to check a single receipt or signed statement is the hosted verifier. Paste a receipt or statement (and a key, if you want the signature checked) and read the verdict and reasons. It is stateless — nothing you submit is stored.

Open verify.agentactioncapsule.org. The page runs the identical library you can install locally; for maximal privacy, verify locally instead.

On the command line

pip install capsule-emit
capsule-emit verify --store ledger.jsonl

  VALID
  VALID

2/2 VALID

capsule-emit verify recomputes every capsule's digest and chain link with the reference verifier from agent-action-capsule (which ships as a dependency, and whose own agent-action-capsule verify runs that structural check alone) and checks each producer signature it finds. A tampered record prints INVALID and the command exits 1. Neither check needs the network.

With the Go CLI: capsulectl

If you would rather not run Python, capsulectl is a standalone Go binary (built on capsule-emit-go) that seals and verifies its own artifact records — it does not read the Python ledger.jsonl above, so use it end to end. Only pre-releases exist so far: the latest pre-release has binaries for Linux (amd64, arm64) and macOS (arm64), with a SHA256SUMS file and a Sigstore bundle. Or install it from source with Go 1.27 or later (the command below). Then create a profile that pins the producer's public key, seal a request (format in the capsule-cli README), and verify:

go install github.com/action-state-group/capsule-cli/cmd/capsulectl@latest
capsulectl key generate --output producer.seed        # prints the public key
capsulectl profile create --name local --type jsonl --jsonl-path ./capsules \
  --signing-key-file producer.seed --trusted-key PRODUCER_PUBLIC_KEY_HEX
capsulectl seal --profile local --request request.json --output artifact.json
capsulectl verify --profile local --capsule artifact.json

{"capsule_identity":"passed","producer_signature_and_trust":"passed",
 "artifacts":{"payload":{"Verified":true},"agent_output":{"Verified":true}}, …}

capsulectl verify recomputes the capsule's identity, checks the producer signature against the key your profile pins, and checks each bound original. A changed byte, or a producer key the profile does not trust, fails the check and the command exits non-zero. No network is needed.

As a library

from scitt_cose import verify_receipt

r = verify_receipt(receipt, leaf_entry_hex=leaf,
                   log_public_key_pem=log_key)
print(r.ok)   # -> True

What a pass means

  • The signature is intact and made by the stated issuer key.
  • The leaf digest is provably included in the log at the proven tree size.
  • Optionally, the log has stayed append-only between two tree heads (consistency).

For the mechanics of each check, see how verification works.

Go deeper — implementation & usage docs in capsule-emit: Tutorial: reading your ledger ↗