Tamper-evident logs: how hash chaining makes a record provable

6 min read

An audit log held by the party being audited is only as credible as that party. Hash chaining fixes this by linking each record to a digest of the one before it, so any alteration to history invalidates every subsequent link. It does not prevent tampering and does not prove a record was true when written. What it proves is that the sequence you are reading is the sequence that was written.

The problem with ordinary logs

Standard application logs are mutable by anyone with database or filesystem access, which includes the operator and anyone who compromises the operator. That is acceptable for debugging, where the reader and the writer are the same party and there is no adversary.

It is not acceptable as evidence, where the reader is a regulator, an auditor or a court, and the writer has an obvious incentive in how the past reads. The question those readers ask is not "what does your log say" but "why should your log be believed".

How the chain works

Each entry includes a cryptographic digest computed over its own contents together with the digest of the preceding entry. The entries form a chain in which every link commits to everything before it.

Change a value in entry 400 and its digest changes. Entry 401 committed to the old digest, so the chain now breaks at 400 and stays broken through to the end. To hide the edit you would have to recompute every subsequent entry, which is why the chain is usually keyed with an HMAC: without the key you cannot produce valid successor digests, so silent rewriting is not merely laborious but infeasible.

What it does not give you

Being precise about the guarantee matters, because overclaiming here is easy and gets caught.

  • It does not prevent tampering. It makes tampering detectable after the fact.
  • It does not prove a record was accurate when written. Garbage in is garbage that is provably unaltered.
  • It does not by itself prove when an entry was written. That needs an external time anchor.
  • It does not help if nobody ever verifies. An unverified chain is an ordinary log with extra fields.

Anchoring and independent verification

Two additions turn the chain from a claim into something a third party can rely on. The first is periodic anchoring: publishing the current head digest somewhere outside your control, so you cannot later present a wholly rewritten history that is internally consistent.

The second is a verifier that does not depend on the system that produced the log. If the only way to check a trail is to run the vendor's software, the vendor is still the trust anchor. A standalone tool that re-implements the hash rule from the specification lets an auditor verify an exported trail without running or trusting the product. Bulwark ships one for exactly this reason.

Verifying a trail in practice

What an auditor actually does with an exported trail:

  • Recompute each entry digest from the entry contents.
  • Confirm each entry commits to the recomputed digest of its predecessor.
  • Check the head digest against whatever external anchor was published.
  • Check sequence numbers for gaps, since deletion of a whole tail is the remaining attack.
  • Spot-check entries against an independent source, because integrity is not accuracy.

Frequently asked

Is a hash-chained log the same as a blockchain?

It shares the linking idea and drops the rest. There is no distributed consensus, no network of validators and no token. For audit trails the consensus machinery solves a problem you do not have, at a cost you would rather not pay.

Can I not just use write-once storage?

WORM storage is a good complementary control and a weaker standalone one, because it proves the storage layer was configured not to allow overwrites, which is a claim about your infrastructure. A hash chain produces evidence that travels with the exported data itself.

What happens if the chain does break?

You learn that the trail cannot be relied on from the break onward, which is itself an important finding. A broken chain is usually a bug or a botched migration rather than malice, but it means the affected span no longer serves as evidence.

Does hash chaining slow down logging?

Marginally. Computing an HMAC over a record is inexpensive relative to the I/O of writing it. The real design constraint is ordering, since the chain requires a defined sequence, which shapes how you shard a high-volume trail.

Bulwark does this in production

Agent registry, scope enforcement, human approvals and a hash-chained evidence trail you can verify without trusting us. Free Developer tier, 100,000 governed decisions a month, no card required.

Related guides