43 lines
2.1 KiB
Markdown
43 lines
2.1 KiB
Markdown
# Receipt Verification Rules (v1)
|
||
|
||
Applies to receipts conforming to `receipt_v1.schema.json`.
|
||
|
||
## Receipt verification
|
||
|
||
A verifier MUST:
|
||
|
||
1. Parse JSON and validate against the schema.
|
||
2. Recompute `canonical_json_bytes` (per `canonicalization.md`) **excluding** signature fields.
|
||
3. Recompute `blake3` and `sha256`; require they match the envelope fields.
|
||
4. If signature fields are present:
|
||
- Require `sig_alg == "ed25519"`.
|
||
- Verify `signature` over UTF-8 bytes of the **hex `blake3` string** (vm-cloud convention).
|
||
- Require `signer_pub` matches verification key.
|
||
5. Return success only if all checks pass.
|
||
|
||
## Chain verification
|
||
|
||
- `prev_blake3` forms a singly-linked chain of receipts.
|
||
- If a `HEAD` file is maintained, verify:
|
||
- `HEAD.created_at` is ISO-8601.
|
||
- `HEAD.blake3` matches the `blake3` of the latest receipt.
|
||
- The latest receipt’s `prev_blake3` matches the previous `HEAD.blake3` (or null for genesis).
|
||
- For a sequence of receipts, iterate in order and ensure every `prev_blake3` matches the prior receipt’s `blake3`; 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)` where `blake3_bytes` is 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_token` in 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_alg` is not exactly `blake3+sha256`.
|