Engineering & deliveryField notes
Tamper-proof logging: why database logs do not count in an audit
3 min read
The sentence always comes in the same tone, half surprised, half annoyed: “But we log everything.” Usually that is true. There is a table, it is called audit_log or history, it gets filled on every change, and it is impressively large.
And still the conversation with the auditor ends with that log not being accepted as evidence.
The distinction that matters
A log is a record. Evidence is a record nobody can change unnoticed.
That sounds like a nuance and is the entire point. A log table in the same database the application writes to is reachable with the same permissions as the business data. Whoever can change the record can usually also change the entry describing the change. An auditor has to assume exactly that is possible — not out of distrust in your team, but because otherwise their own audit would be worthless.
Four properties that make the difference
Immutability. Entries are appended, never overwritten, never deleted. No UPDATE, no DELETE — not for administrators either, and not “just this once, because of the migration”.
Completeness. Every business-relevant change produces an entry, in the same transaction as the change itself. A log that can fail on error has gaps exactly where things got interesting.
Domain meaning. The entry describes what happened in business terms, not which column was written. “Credit limit raised to 50,000, approved by sales management, based on the annual agreement” is evidence. “UPDATE customer SET limit=50000” proves something happened, not why.
Attribution. Every entry carries the identity that applied at the time of the action — not the user behind that ID today, and certainly not a shared technical account.
A test you can run yourself
Take any case from last quarter and answer three questions without asking a developer:
- Who changed it last, and on whose approval?
- What did it look like on a specific earlier date?
- Could anyone manipulate those two answers without it being noticed?
If one question stays open, you have a record, not evidence. The provability check asks these questions systematically across ten typical audit situations.
Why this is surfacing now
Two developments meet. Evidence duties are getting concrete: NIS2 requires not just measures but their effectiveness, and the reporting deadlines leave no time for manual forensics. At the same time software is built faster and with fewer handovers, so less documentation appears as a by-product — a point the consolidation of engineering roles makes visible.
Both point the same way: whatever the system does not capture, nobody will reconstruct later.
How to retrofit it without rebuilding everything
The expensive option is a full rebuild. The workable one starts with a selection: almost every company has one to three processes where the history question actually gets asked — approvals, prices, permissions, payments. Those get an immutable, domain-worded history. The rest stays as it is.
Technically the direct route is an append-only store whose write path is separated from the application, plus events named in business terms. That is where event sourcing comes in — not as an architectural fashion, but because it makes exactly this kind of history the default. It is not the only way, and we say so when it is oversized.
What you end up with
Not more logs. The ability to answer an uncomfortable question in minutes instead of person-days — in a form that still holds when someone doubts it. What that looks like in practice is shown in “Who promised what?”, where exactly this gap created half a year of effort.
← Back to insightsArticles on this topic
Engineering & deliveryNote
Bolt-on logging: where is the truth?
AI takes the burden of human vagueness off us. So why do we place a second vagueness — a log — next to our core processes?
Engineering & deliveryFoundation
Tenant separation that survives the security questionnaire
One forgotten filter is a reportable incident. Why isolation in application code is not evidence — and which models enterprise buyers accept.
Engineering & deliveryField notes
Production readiness in the AI factory: what to check when agents write the code
Requirements are agent-readable, the arc42 is maintained, the pipeline is green. The old question — does it run? — has become trivial. The new one: how do we know a change is right when nobody read every line?