Chain-of-Custody Offline
Chain-of-custody proves an unbroken sequence of governance from start to end. The receipt chain creates custody proof that can be verified offline without trusting any external service.
What does chain-of-custody prove?
The chain-of-custody proves four key properties about governance:
- ■Continuity: No gaps in the sequence from POLICY_LOADED to final receipt
- ■Integrity: No receipt has been modified after signing
- ■Authority: All receipts signed by the governance boundary's key
- ■Ordering: Events occurred in the sequence recorded
How does hash-linking create custody?
Each receipt contains the hash of the previous receipt. This creates a chain where modifying any receipt breaks all subsequent links.
Receipt #1 Receipt #2 Receipt #3 ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ counter: 1 │ │ counter: 2 │ │ counter: 3 │ │ event: LOADED │ │ event: MEASURE │ │ event: DRIFT │ │ prev: 00000... │───▶│ prev: abc12... │───▶│ prev: def34... │ │ this: abc12... │ │ this: def34... │ │ this: ghi56... │ │ sig: [signed] │ │ sig: [signed] │ │ sig: [signed] │ └──────────────────┘ └──────────────────┘ └──────────────────┘ If Receipt #2 is modified: - Its this_receipt_hash changes - Receipt #3's prev_receipt_hash no longer matches - Chain validation fails at Receipt #3
What is the offline validation process?
A verifier can prove custody without network access using only the evidence bundle:
- 1.Load receipts: Read all receipts from bundle in counter order
- 2.First receipt: Verify prev_hash equals 64 zeros (genesis)
- 3.Each receipt: Verify signature using boundary public key
- 4.Chain link: Verify prev_hash equals previous receipt's this_hash
- 5.Counter: Verify counter is previous + 1 (no gaps)
- 6.Chain head: Verify final receipt matches chain_head declaration
Why can't this be faked?
Creating a false custody chain requires one of these, each of which is computationally infeasible or detectable:
Forge Signature
Requires the boundary's Ed25519 private key. Without it, signature verification fails immediately.
Find Hash Collision
Creating a different receipt with the same hash would require breaking SHA-256. No known practical attack exists.
Insert/Delete Receipt
Any insertion or deletion breaks the counter sequence or hash links. Gap detection catches this immediately.
Replace Entire Chain
Requires the signing key to create valid signatures. Also must match any external anchors/checkpoints.
What about clock manipulation?
Timestamps can be manipulated if the boundary system clock is compromised. The chain provides ordering guarantees regardless:
- ■Counter ordering: Proves sequence regardless of timestamps
- ■TSA tokens: External timestamp authority provides trusted time
- ■DEGRADED_LOCAL: Receipts without TSA are flagged, verifier notes this
- ■External anchors: Checkpoint to immutable stores bounds manipulation window
Frequently asked questions
What if I lose some receipts?
The chain will have a gap. Verification will fail with COUNTER_GAP. This is detectable and cannot be hidden—the verifier knows exactly which receipts are missing.
Can two valid chains exist?
Forks can exist if the signing key creates multiple chains with the same genesis. External checkpointing (anchors) prevents this by committing to a specific chain state at known times.
How long can a custody chain be?
There's no technical limit. Very long chains should use checkpoint segmentation for practical verification performance. Each segment verifies independently.