2.1 KiB
2.1 KiB
Receipt Verification Rules (v1)
Applies to receipts conforming to receipt_v1.schema.json.
Receipt verification
A verifier MUST:
- Parse JSON and validate against the schema.
- Recompute
canonical_json_bytes(percanonicalization.md) excluding signature fields. - Recompute
blake3andsha256; require they match the envelope fields. - If signature fields are present:
- Require
sig_alg == "ed25519". - Verify
signatureover UTF-8 bytes of the hexblake3string (vm-cloud convention). - Require
signer_pubmatches verification key.
- Require
- Return success only if all checks pass.
Chain verification
prev_blake3forms a singly-linked chain of receipts.- If a
HEADfile is maintained, verify:HEAD.created_atis ISO-8601.HEAD.blake3matches theblake3of the latest receipt.- The latest receipt’s
prev_blake3matches the previousHEAD.blake3(or null for genesis).
- For a sequence of receipts, iterate in order and ensure every
prev_blake3matches the prior receipt’sblake3; fail on the first discontinuity.
Merkle receipts (for external checkpoints)
When receipts are batched into Merkle proofs:
- Input ordering: preserve the chronological order of receipts as leaves (stable, prefix-based trees).
- Leaf hashing:
leaf = BLAKE3("VM-receipt-leaf-v1" || blake3_bytes)whereblake3_bytesis the 32-byte digest of the receipt body (not hex string; decode hex to bytes). - Node hashing:
node = BLAKE3("VM-receipt-node-v1" || left || right). - Odd count rule: duplicate the last node at each level when odd (standard Merkle padding).
- Root format: hex-encoded lowercase BLAKE3 of the final root node.
- Inclusion proof: sibling list from leaf → root, each sibling annotated with side ("left" | "right").
Fail-closed guidance
- Any missing or invalid
session_tokenin tool-executed receipts SHOULD be treated as unverifiable and rejected by consumers. - Signature presence is optional, but if present must verify; otherwise treat as invalid.
- Reject receipts whose
hash_algis not exactlyblake3+sha256.