Verify a receipt end-to-end
Pull a real Khipu receipt from
szl-lake, validate its ECDSA-P256 DSSE signature against the org cosign key, then re-check it througha11oy /v1/verifyand read the doctrine posture from the a11oy policy gate.Headline number: 1 receipt → 1 cryptographic VALID in < 60 seconds, zero credentials.
This is the canonical first-touch recipe. It is the most important thing the cookbook does: it proves, on your own machine, that an SZL governance receipt is what it claims to be.
The signature checked here is real — not a placeholder. The a11oy Memory tick receipt (file a11oy_receipts.ndjson) in the live szl-lake dataset is signed with the organization cosign key published at .github/cosign.pub, and this recipe verifies it against that key with no founder credentials required.
Honest scope. The live HF Spaces still emit receipts whose
dsse_sigis the stringPLACEHOLDER(Sigstore CI signing is pending per Doctrine v11). The lake NDJSON receipt used below carries a genuine ECDSA-P256 signature that validates. Use the lake receipt for a true end-to-end proof; use the live Space tick to see the receipt shape.
Prerequisites
python3 -m pip install cryptography requests
# curl + jq for the optional live-Space stepsNo API key, no GHCR token, no founder credentials needed for the core verification.
Quickstart (the headline number)
import base64, json, urllib.request
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.asymmetric.utils import Prehashed
from cryptography.hazmat.primitives import hashes, serialization
LAKE = "https://huggingface.co/datasets/SZLHOLDINGS/szl-lake/resolve/main"
# 1. Pull one real receipt from the lake (canonical HF mirror).
line = urllib.request.urlopen(f"{LAKE}/khipu/a11oy_receipts.ndjson", timeout=30).readline()
r = json.loads(line)
# 2. Fetch the org verify key the receipt points to.
key_pem = urllib.request.urlopen(
"https://raw.githubusercontent.com/szl-holdings/.github/main/cosign.pub", timeout=30
).read()
pub = serialization.load_pem_public_key(key_pem)
# 3. Verify: ECDSA-P256 over the raw SHA-256 of the DSSE PAE (prehashed).
sig = base64.b64decode(r["dsse_sig"])
digest = bytes.fromhex(r["dsse_pae_sha256"])
pub.verify(sig, digest, ec.ECDSA(Prehashed(hashes.SHA256()))) # raises if invalid
print("VALID:", r["receipt_id"][:16], "signed by", r["dsse_keyid"])
# => VALID: 4c9c3f2b8d6452d9 signed by szlholdings-cosignIf pub.verify returns without raising, the receipt is authentic. Tamper with one byte of the payload or the signature and it raises InvalidSignature — that is the whole point.
Full walkthrough
Step 1 — Understand the receipt shape
A lake Khipu receipt is one NDJSON line. The signature-relevant fields are:
| Field | Meaning |
|---|---|
receipt_id | SHA-256 of the receipt body — also the actual_hash. |
lutar_anchor | Doctrine kernel commit (c7c0ba17) the receipt is pinned to. |
lambda, lambda_pass | The Λ score and gate result at emission time. |
dsse_payload_type | application/vnd.szl.khipu+json. |
dsse_pae_sha256 | SHA-256 of the DSSE Pre-Authentication Encoding — what the signature covers. |
dsse_sig | base64 ECDSA-P256 signature. |
dsse_keyid | szlholdings-cosign. |
verify_key_url | Points at .github/cosign.pub — the key above. |
DSSE (Dead Simple Signing Envelope, in-toto/ITE-5) binds the signature to the payload type as well as the bytes, via the PAE:
PAE = "DSSEv1 " ‖ len(type) ‖ " " ‖ type ‖ " " ‖ len(body) ‖ " " ‖ bodyThe SZL signer signs SHA-256(PAE), so verification is a prehashed ECDSA check — exactly what the quickstart does.
Step 2 — Verify the doctrine anchor matches the locked kernel
A receipt is only meaningful if its doctrine anchor is the locked one. Cross-check against the lake index:
idx = json.loads(urllib.request.urlopen(f"{LAKE}/lake_index.json", timeout=30).read())
assert r["lutar_anchor"] == idx["kernel_commit"] == "c7c0ba17", "doctrine drift!"
assert (idx["declarations"], idx["axioms"], idx["sorries"]) == (749, 14, 163)
print("doctrine OK:", idx["kernel_commit"], idx["declarations"], idx["axioms"], idx["sorries"])
# => doctrine OK: c7c0ba17 749 14 163Step 3 — Tamper test (prove the check has teeth)
bad = bytearray(sig); bad[10] ^= 0x01 # flip one bit of the signature
try:
pub.verify(bytes(bad), digest, ec.ECDSA(Prehashed(hashes.SHA256())))
print("UNEXPECTED: tampered sig accepted")
except Exception:
print("REJECTED tampered signature — as designed")Step 4 (optional, live) — Round-trip through a11oy /v1/verify
When the a11oy Space is warm, re-check a chain through the substrate:
curl -s https://szlholdings-a11oy.hf.space/api/a11oy/v1/honest | jq .kernel_commit
# => "c7c0ba17" (authoritative live doctrine probe)
curl -s -X POST https://szlholdings-a11oy.hf.space/api/a11oy/v1/verify \
-H 'content-type: application/json' \
-d "$(python3 -c 'import json,urllib.request;L="https://huggingface.co/datasets/SZLHOLDINGS/szl-lake/resolve/main";print(urllib.request.urlopen(L+"/khipu/a11oy_receipts.ndjson").readline().decode())')" \
| jq .Honest note. The a11oy and killinchu Spaces sleep on Hugging Face's free tier and may return "Space is in error" until warmed — open the Space URL once to wake it. The lake-based verification in Steps 1–3 needs no Space at all. The a11oy Memory and a11oy Sentinel roles ship inside a11oy — there are no standalone Spaces for them.
Step 5 (optional, live) — Read the verdict posture from the policy gate
# The a11oy Sentinel ships inside a11oy.
curl -s https://szlholdings-a11oy.hf.space/api/a11oy/v1/honest | jq '{doctrine, slsa}'
# => { "doctrine": "v11", "slsa": "L1 (honest)" }What you proved
- A receipt drawn from the public lake is cryptographically authentic under the org key.
- Its doctrine anchor equals the locked kernel (
c7c0ba17, 749/14/163). - Any tampering is rejected.
That is the SZL invariant receipts.in ≡ receipts.out, made concrete.
See also
- 02 — Deploy the SZL UDS bundle — run the organs that emit these receipts.
- 06 — Verify cosign + Rekor for SLSA L1 — verify the container that runs the organ.
- 08 — Receipt knot algebra — the topology of receipt chains.
- 12 — Doctrine ledger query — programmatic access to 749/14/163.
- Live: a11oy · killinchu (the two shipping flagships)
Cite this recipe
@misc{szl_cookbook_verify_receipt_2026,
title = {Verify a receipt end-to-end (SZL Cookbook recipe 01)},
author = {{SZL Holdings}},
year = {2026},
howpublished = {\url{https://github.com/szl-holdings/szl-cookbook/blob/main/recipes/01-verify-a-receipt-end-to-end.md}},
note = {Doctrine v11 LOCKED 749/14/163, kernel c7c0ba17. DOI 10.5281/zenodo.20434308}
}Doctrine v11 LOCKED — 749/14/163 — kernel c7c0ba17 · Λ = Conjecture 1 · SLSA L1 (honest)