Skip to content
VeritioDocs

Verify a hash chain

Kind
tutorial
For
developer · operator · governance
Verified against
@veritio/core@0.4.7

Start with the two intact records from Record your first audit event. This exercise changes a copied record and removes another one; it never mutates the store.

src/examples/tutorial/tamper.ts
import { verifyAuditRecords } from '@veritio/core'
import { recordTutorialChain } from './record-and-verify'
const records = await recordTutorialChain()
const changed = records.map((record, index) =>
index === 1
? { ...record, event: { ...record.event, metadata: { ...record.event.metadata, role: 'admin' } } }
: record,
)
const dropped = records.slice(1)
console.log(JSON.stringify({
changedRecord: verifyAuditRecords(changed),
droppedRecord: verifyAuditRecords(dropped),
}, null, 2))
Terminal window
bun src/examples/tutorial/tamper.ts

The checked fixture prints:

verified output
{
"changedRecord": {
"ok": false,
"index": 1,
"reason": "hash_mismatch"
},
"droppedRecord": {
"ok": false,
"index": 0,
"reason": "sequence_mismatch"
}
}

The first result changes metadata.role from viewer to admin without recomputing the stored record hash. Verification stops at array index 1 with hash_mismatch because the current canonical record bytes no longer produce the stored hash.

This is not a warning. A consumer must treat the record set as unverified and investigate the source, transport, or storage boundary that supplied it.

The second result removes sequence 1. The remaining record still says it is sequence 2, so verification stops at array index 0 with sequence_mismatch.

Removing a record from the middle of a longer chain can instead surface a sequence or previous-hash mismatch at the next surviving record. The first returned failure identifies the earliest inconsistency the verifier can prove.

For each ordered record, the verifier checks the supported algorithms and canonicalization label, tenant scope, expected gapless sequence, expected previous hash, and recomputed record hash. It returns { ok: true } only when every supplied record passes.

Integrity verification proves consistency of the supplied record bytes and links. It cannot prove that the application reported a truthful real-world event, that the actor was authorized, or that an omitted chain was never created elsewhere. Those remain application, identity, and operational trust questions.

Continue with the byte-level hash-chain explanation or use the verifier error reference.