Verifier Design
The offline verifier is a deterministic program that validates an evidence bundle and emits a structured verdict. It must be simple, auditable, and produce consistent results across implementations.
What are the core verifier responsibilities?
The verifier performs a strict sequence of validation steps. Each step must pass before proceeding. Failure at any step produces a specific error code.
- 1.Unpack bundle: Read ZIP contents without network access
- 2.Validate manifest checksums: SHA-256 of each file must match declared hash
- 3.Verify policy artifact: Recompute policy_id, validate issuer signature
- 4.Validate receipts: Schema, receipt_id, this_receipt_hash, signature per receipt
- 5.Check chain continuity: Counter gaps, prev_hash linkage, chain_head match
- 6.Verify policy consistency: All receipts reference same policy_id
- 7.Check required events: POLICY_LOADED, ENFORCED, etc. present if mandated
- 8.Emit verdict: PASS, PASS_WITH_CAVEATS, or FAIL with structured report
What verdict types exist?
The verifier emits one of three verdicts. Each verdict has specific semantics and triggers.
PASS
All validation steps succeeded. The bundle is internally consistent, properly signed, chain is intact, and policy was enforced as declared.
PASS_WITH_CAVEATS
All cryptographic validations passed, but some optional features are degraded. For example: local timestamps used instead of TSA, merkle anchoring skipped.
FAIL
One or more validation steps failed. The bundle should not be trusted. Report includes specific error_code and path identifying the failure.
What error codes are defined?
Error codes are machine-readable identifiers for specific failure conditions. Each code maps to a specific validation step failure.
// Manifest errors BUNDLE_CHECKSUM_MISMATCH // File hash doesn't match manifest MANIFEST_PARSE_ERROR // Manifest JSON is invalid // Policy errors POLICY_ID_MISMATCH // Computed policy_id != declared POLICY_SIGNATURE_INVALID // Issuer signature verification failed // Receipt errors RECEIPT_SCHEMA_INVALID // Receipt missing required fields RECEIPT_ID_MISMATCH // Computed receipt_id != declared RECEIPT_HASH_MISMATCH // this_receipt_hash computation failed RECEIPT_SIGNATURE_INVALID // Receipt signature verification failed // Chain errors COUNTER_GAP // Non-sequential counter values CHAIN_PREV_HASH_MISMATCH // prev_hash != previous this_hash CHAIN_HEAD_MISMATCH // chain_head doesn't match last receipt // Policy consistency errors POLICY_MISMATCH // Receipt references different policy REQUIRED_EVENT_MISSING // Mandated event type not in chain // Enforcement errors ENFORCEMENT_POLICY_MISMATCH // Action doesn't match policy mapping
What does the report output look like?
The verifier emits a structured report in JSON format. The report is deterministic: same bundle bytes produce identical report bytes.
{
"verdict": "PASS",
"report_hash": "sha256:abc123...",
"timestamp": "2024-01-15T10:30:00Z",
"bundle_hash": "sha256:def456...",
"checks": {
"manifest": "OK",
"policy_signature": "OK",
"receipts": {
"status": "OK",
"count": 42,
"validated": 42
},
"chain": "OK",
"drift_detected": true,
"enforcement_executed": true,
"merkle": "SKIPPED",
"anchor": "SKIPPED"
},
"caveats": [],
"errors": []
}What are the implementation requirements?
Verifier implementations must meet specific requirements to ensure interoperability and trust.
- ■No network calls: Zero external dependencies during verification
- ■Deterministic output: Same input bytes produce same output bytes
- ■Bounded resources: O(n) time and space where n is bundle size
- ■Minimal dependencies: Only crypto primitives and ZIP library
- ■Auditable code: Implementation should be readable and reviewable
Frequently asked questions
Can I use any programming language?
Yes. The specification is language-agnostic. Reference implementations exist in JavaScript, Python, and Go. Choose based on your deployment environment and security review capacity.
How do I handle very large bundles?
Stream processing is recommended. Read and validate receipts one at a time without loading the entire chain into memory. The chain is designed for sequential validation.
What if my implementation produces different results?
Run the conformance test suite. Differences typically stem from canonicalization bugs or signature verification edge cases. The test vectors will identify the divergence.