Audit chains explained without the crypto hype
Strip away the marketing and a tamper-evident log is a very old, very boring idea that fits on a napkin. Worth understanding, because the boring version is the one that holds up.
A vendor once spent eleven minutes of a forty-minute call explaining that their audit log was “blockchain-secured”. Somebody on our side asked, politely, what that meant in terms of what an attacker could and could not do. The answer was a diagram with a distributed ledger on it and no attacker in it at all.
The frustrating thing is that underneath the marketing there was almost certainly a perfectly sound mechanism, and it is a mechanism worth understanding, because once you see it you stop being impressed by the wrapping and start asking the two questions that matter. This piece is an attempt to explain the boring version properly, so you can evaluate anybody’s claims about it, including ours.
The problem, stated plainly
You have a log. Entries get appended to it. Later, somebody wants to rely on that log as evidence.
The threat is not that somebody reads the log. It is that somebody changes it after the fact. Specifically, three edits:
- Modify an entry so it says something different from what happened.
- Delete an entry so an event disappears.
- Insert an entry so an event that never happened appears to have happened, at a convenient time.
An ordinary database table defends against none of these. If you have write access, you can update a row and there is no residue. Database audit logging helps, but now you have the same problem one level down: what protects the audit log of the audit log.
Access control is the first and best answer, and it is genuinely most of the value. Make the table append-only at the permission level, keep the credentials that could alter it out of reach of the systems that write to it, ship copies somewhere with a different trust boundary. Do that first. Cryptographic chaining is not a substitute for any of it.
But access control has a limit, and the limit is that it protects against outsiders and gives you nothing against an insider with legitimate privileges, or against yourself. And “or against yourself” is the interesting one, because the whole point of evidence is to be believed by somebody who does not trust you. An auditor, a regulator, a customer, a court. If your only defence is “we did not change it”, your evidence is exactly as strong as your reputation.
The mechanism, on a napkin
Here is the entire idea.
When you write an entry, you compute a hash over the entry’s contents together with the hash of the previous entry. You store that hash with the entry. The next entry does the same, including your hash. Each entry is therefore cryptographically dependent on every entry before it.
entry 41 { action: "criteria_gate_passed", ... } prev = 9f2c...a10 hash = H( canonical(entry_41) + prev ) -> 4d8b...77eentry 42 { action: “status_transition”, … } prev = 4d8b…77e hash = H( canonical(entry_42) + prev ) -> c015…2a9
entry 43 { action: “merge_allowed”, … } prev = c015…2a9 hash = H( canonical(entry_43) + prev ) -> 81ff…b34
prev no longer matches, so 43 is wrong too. The break is visible and it is located. That is the whole trick.That is it. That is the mechanism people wrap in eleven minutes of blockchain slides.
Two details do real work and are worth naming.
Canonicalisation. You have to hash a deterministic serialisation of the entry. If your JSON key order can vary, or a timestamp can be formatted two ways, you will get spurious verification failures and eventually somebody will “fix” it by loosening the check. The most common way a chain quietly stops meaning anything is a canonicalisation bug that nobody wanted to debug.
Verification has to actually run. A chain that is never verified is decoration. Verification should be a scheduled job that walks the chain and screams, plus an on-demand check you can run in front of somebody who is asking. If the only time your chain has ever been verified is in a unit test written by the person who built it, you have a data structure, not a control.
Tamper-evident is not tamper-proof
This is the distinction that most marketing blurs and the one you should hold onto.
A hash chain does not prevent modification. Anyone with write access to the store can modify entry 41. They can then recompute 42, 43 and everything after it, and the chain will verify perfectly. All they need is the ability to rewrite the tail.
What the chain gives you is that a partial edit is detectable, and that a complete rewrite requires touching everything after the edited point. It converts a quiet surgical change into a loud comprehensive one. That is a meaningful raising of the bar, and it is also much less than “immutable”, which is the word vendors reach for.
What a chain does not do
- Prevent an insider from rewriting the log
- Prove an entry is true, only that it is unaltered
- Prove an event was recorded at all
- Prove when something happened, by itself
- Replace access control or backups
What it does do
- Make partial edits detectable and locatable
- Force a forger to rewrite the whole tail
- Let a third party verify without trusting you
- Detect corruption and silent data loss
- Give a cheap, portable integrity claim
To close the rewrite gap you need something the log’s owner cannot control. The standard move is to periodically publish the current head hash somewhere outside your own trust boundary: a customer-visible endpoint, a counterparty, a timestamping service, a signed email to yourself. Once an external party has recorded that at 14:00 on Tuesday the head was 81ff...b34, no rewrite of anything before that point can go unnoticed by them, because the recomputed head will not match what they hold.
This is called anchoring, and it is the honest version of what “blockchain” is gesturing at. The reason public chains get invoked is that they are one convenient place to publish a value that you cannot later change. They are not the only one, and for most enterprise purposes they are a poor one, because they add operational and regulatory surface for a property that a countersigning arrangement or a third-party timestamp gives you with far less noise.
Signing is a separate question
Chaining tells you the log has not been altered. It says nothing about who wrote each entry. Those are different properties and they are often conflated.
If entries are signed by the writer’s key, you get attribution that survives the entry being copied out of the store: a recipient can verify that this entry was produced by that identity, without trusting the database it came from. That is genuinely useful for evidence that has to travel, which most evidence eventually does.
The cost is key management, and key management is where good intentions go to die. Rotation, revocation, what happens to old entries when a key is retired, where the signing key lives so that a compromise of the application does not hand an attacker the ability to forge history. If you are not prepared to run that properly, a signed chain with a key sitting in an environment variable next to the database credentials is theatre. Chain first, sign when you have somewhere real to keep the key.
What to ask a vendor
Reduced to the questions I actually use.
- What exactly is hashed, and is the serialisation canonical? Can I compute a hash myself from the exported record and get the same value?
- Can I export the chain and verify it independently, with my own tool, without your software?
- Is the head anchored anywhere outside your control? How often, and where?
- Who inside your organisation could rewrite the tail, and what stands in their way?
- What is the completeness claim? Is every automated action guaranteed to produce an entry, or only the ones that go through a particular path?
- How long is it retained, and what happens to it if we leave?
Question two is the one that separates real from decorative. If verification only works inside the vendor’s product, the property you are buying is “trust us”, with extra steps. An exported chain that a hostile third party can verify with fifty lines of script is a much stronger position, and it is not hard to provide.
Question five is the one most people forget and the one that usually matters most in practice, because an unbreakable record of a partial population is a partial record with a strong integrity guarantee. That is worth something, but it is not what anyone thinks they are buying.
Why this matters more with agents in the loop
You could reasonably say all of the above has been true since the seventies, and it has. The reason it is getting attention now is volume and authorship.
When a human moved a ticket, the log entry was one of a few hundred a month and there was a person who remembered it. When agents are moving tickets, gating merges, opening pull requests and updating statuses, the volume goes up by an order of magnitude and the number of humans who could testify to any individual event goes to zero. The log stops being a convenience and becomes the only witness.
An only witness needs to be able to demonstrate that it has not been coached. That is the whole argument for chaining, and it is enough of an argument on its own without importing a decade of cryptocurrency vocabulary. GroundTruth chains its automated-change records for exactly this reason, and the mechanism is the boring one described above rather than anything more exotic.
Where this breaks down
Several honest limits.
The largest one: integrity is not truth. A chain guarantees that what was written has not changed. It says nothing about whether what was written was accurate when it was written. If the process that generates entries has a bug, or an agent misreports its own action, you get a perfectly verifiable record of a false statement, and the verification stamp makes it more persuasive than it deserves to be. Chained logs increase the cost of lying later. They do nothing about being wrong now, and the second failure is far more common.
Second, the operational reality of verification failures is worse than the theory suggests. When a chain does break, the overwhelmingly likely cause is a bug, a botched migration, a replication artefact, or a clock problem, not an attacker. Teams that have not thought this through get their first break at 2am, discover they have no procedure, and quietly disable the check. Decide in advance what a break means, who is called, and how a legitimate repair is recorded so that the repair itself is evidenced rather than hidden.
Third, chains and deletion obligations are in direct tension. If you are obliged to erase certain data on request, and that data is inside a hashed entry, you cannot remove it without breaking the chain. The workable answer is to keep personal data out of chained entries in the first place, storing a reference and hashing that, so a deletion removes the referenced payload and leaves the chain intact. This has to be a design decision up front. Retrofitting it into a chain that already carries payloads is genuinely painful, and I have watched a team spend a quarter on it.
Fourth, anchoring is only as good as the counterparty’s record-keeping. If you publish your head hash to an endpoint nobody ever reads or retains, you have the ceremony without the property. The anchor has to be somewhere that will still have the value, and will still be independent of you, at the moment you need it.
And finally, none of this makes anybody compliant with anything. It is a control that supports a claim about evidence integrity. Whether that claim is relevant, whether it is tested, and whether the surrounding programme is adequate are questions about your organisation, not about your hash function.
The takeaway
A tamper-evident audit chain is a hash of each entry that includes the hash of the previous one. It makes partial edits detectable, forces a forger to rewrite everything downstream, and lets someone who does not trust you verify the record themselves. It does not prevent tampering, does not prove truth, and does not need a distributed ledger.
Ask for canonical hashing, independent verification, external anchoring, and an honest answer about completeness. Keep personal data out of the chained payload. Verify on a schedule and have a procedure for the day it fails.
The next piece moves from the mechanism to the audience, and looks at the questions auditors are starting to ask specifically about code an agent wrote, several of which have no comfortable answer yet.