DocsVerify a bundle
Verify a bundle
This is the part to try first. It runs entirely offline — no account, no network, no package registry — because every exported bundle embeds its own dependency-free verifier. Evidence that needs the vendor alive to check is not evidence.
The embedded verifier
node -e "const b=require('./evidence.json');require('fs').writeFileSync('verify.mjs',b.verifier)"
node verify.mjs ./evidence.jsonThe verifier recomputes every hash from the raw events, re-links the chain, validates each checkpoint signature against the public keys in the bundle, and checks the RFC 3161 countersignatures. It names the exact sequence number at the first discrepancy — “something is wrong” is useless in a hearing. Skeptical readers should read the ~400 lines, or diff them against any other bundle's copy, before running it. With npm available, npx auditant verify ./evidence.json --offline is the same verifier.
What a clean record looks like
Auditant — verification report ──────────────────────────────────────────────────────────────── Log tenant_acme/prod Events 4183 ✓ VERIFIED — chain intact, checkpoints signed and timestamped Chain verified: 4183 events, sequence 0–4182 Anchored through sequence 4182, countersigned by a timestamp authority
✗ TAMPERED — this record has been altered
FAIL seq 4182: Content altered at 4182: stored bb1074a2c9e1…,
recomputed 0e41f7d3ba58…Exit codes
0 verified and anchored 1 tampered, or the bundle could not be read 2 usage error 3 chain intact, but nothing anchors it — internally consistent, externally unproven
What verification proves — and what it doesn't. It proves the records were not altered since their checkpoint anchored; the exposure window equals the checkpoint interval, five minutes by default. It does not prove completeness: an action that never reached Auditant is not in the log, and no signature can say otherwise. Coverage is a property of your deployment, reported separately and honestly.