What Makes an Audit Trail Evidence
The difference between a log your system vouches for and a record a third party can verify — and why erasure and integrity are not actually in conflict.
Most systems described as having an audit trail have a log. The distinction only becomes expensive at the moment it matters: a dispute, an examination, or a regulatory request, where the question is not what your system says happened but what can be shown to have happened.
The weakness of an ordinary log
An ordinary audit log is a table your application writes to. Anyone with database access can alter a row, and nothing about the remaining records would reveal it. Its integrity rests entirely on trust in the operator — who is usually the party with the most interest in the outcome.
Chaining
A hash-chained log commits each entry to the one before it. Altering an earlier record invalidates every subsequent link, so tampering becomes detectable by anyone holding the chain rather than only by the operator.
Three implementation details determine whether this actually holds:
Sequence assignment must be serialised. If two events can be appended concurrently without coordination, the chain forks — and a forked chain fails verification permanently, on honest data.
The hashed content must be an explicit allowlist. Hashing whatever fields happen to exist means the committed projection changes silently whenever the schema does. The set of hashed fields should be declared, and changing it should be a deliberate, visible act.
Timestamp format is part of the contract. The chain hashes a rendered string. Reformatting timestamps — even “simplifying” how they are read back — invalidates every chain written before the change, in a commit that looks harmless.
Verification by the holder
Chaining is only useful if someone other than the operator can check it. A verification interface that lets any party holding a completed record confirm the sequence independently is what converts the log from an assertion into evidence.
Erasure and integrity together
These appear to conflict, and are often implemented as though one must be sacrificed. They coexist if personal data is held encrypted and outside the hashed payload from the start. An erasure request destroys the key, rendering the data unrecoverable, while every hash in every chain still verifies.
The constraint is that this has to be designed in. Retrofitting it means rewriting every historical event to remove data the chain already commits to — which is not a migration, it is a rebuild.
