Skip to content
All posts
SecurityEngineering

They Wanted an Audit Trail. With an Edit Button. I Am Not Okay.

March 22, 2026·Read on Medium·

A story about a spec, a red flag and the creative use of “administrator privileges.”

I have built a lot of things for a lot of clients. Payment gateways. Multi-tenant dashboards. Government portals with more approval layers than a bank loan. I have seen requirements that made me raise an eyebrow. A few that made me close my laptop and take a walk.

This one made me take a very long walk.

The brief was standard enough. Build a comprehensive audit trail for the system. Log every action. Every record change. Every login. Every approval. The works. Good. Audit trails are one of those features that serious systems should have and most don’t bother with until something goes wrong.

Then I got to the clause buried near the bottom.

“Administrators should be able to modify audit records when necessary.”

What??

Let’s Get the Technical Part Out of the Way

An audit trail is not a log file you clean up when the disk gets full. It is not a notepad. It is not a whiteboard someone can erase before the meeting.

An audit trail exists for one reason: to create an immutable record of what happened, who did it and when. The moment you allow someone to edit that record, it is no longer an audit trail. It is a story. And stories can be rewritten.

This is not my opinion. ISO 27001 says audit logs must be protected from modification. SOX compliance requires it. The entire concept of non-repudiation in information security is built on the assumption that records cannot be quietly altered after the fact.

If it can be changed, it is not an audit trail. It is a very official-looking document that means absolutely nothing.

I hope someone in that meeting room is reading this. Hello!!.

The Charitable Interpretations (I Tried, I Really Did)

I am a professional. I gave them the benefit of the doubt.

Maybe they mean soft deletes? Hiding records from the UI without destroying them from the database. Sure. That is defensible. Except the spec said modify, not archive.

Maybe they mean correcting human error? A typo in a note field, a wrong timestamp from a system bug. Fine. The answer to that is an amendment record. A new entry that references the original and adds the correction. You do not touch the original. You never touch the original. That is the entire point.

Maybe they just don’t understand what they’re asking for? Possible. Clients often describe what they want in business terms and leave the technical interpretation to you. Except this clause was specific. Deliberate. And when I asked for clarification on the use case, the answer was not “oh we just meant adding notes.”

The answer was: “Senior administrators need full control over the audit data.”

Full control. Over the audit data. Right.

Let Me Paint You a Picture

Imagine a system that tracks approvals. Budget approvals. Contract sign-offs. Procurement decisions. Every action logged with a timestamp and the user who performed it.

Now imagine that someone with “administrator” access can go into that log and change the record. Maybe they approved something they shouldn’t have. Maybe someone else approved something for them without authorization. Maybe the numbers in the original approval don’t match what actually got paid.

No problem. Pull up the audit record. Make a small adjustment. The log now says something different. The timeline is clean. Nobody can prove anything.

I am not saying that is what this client intended.

I am saying that is exactly what this feature would enable. And if you build a door, you do not get to be surprised when someone walks through it.

Audit Trails Exist to Protect People from Power

Let me say that again in its own line because it matters.

Audit trails exist to protect people from power. An editable audit trail protects power from people.

If a system has genuine oversight requirements. And any system touching public money, government procurement or multi-party approvals absolutely does. Then the audit trail is the last line of accountability. It is the thing that remains honest even when the humans involved are not.

The moment you let administrators edit it, you have handed the fox the key to the henhouse and asked him to also write the incident report.

I hope whoever wrote that clause into the spec is very proud of their creative writing skills. Truly. A remarkable contribution.

What You Actually Build Instead

Here is the counter-proposal I put on the table, in case anyone else finds themselves in this situation and needs language for a client meeting.

Append-only audit records. Every row in the audit table is final. No update queries. No deletes. If your application layer tries to run one, it fails. You can enforce this at the database level with triggers or at the application level with a read-only model binding. Both if you are serious.

// AuditLog model. Make it very clear.
protected static function booting(): void
{
static::updating(fn() => throw new \LogicException(
'Audit records are immutable. Create an amendment instead.'
));

static::deleting(fn() => throw new \LogicException(
'Audit records cannot be deleted. Ever. No.'
));
}

Amendment records instead of edits. If a genuine correction is needed for a system error, wrong metadata or misattributed action, you create a new record that references the original by ID and explains what is being corrected and why. The original stays untouched. The amendment is also immutable. You now have a complete, traceable correction history.

Cryptographic hashing per record. Hash the audit row contents and store the hash alongside the record. On read, verify the hash. If it does not match, something touched that record after it was created. That something now has a very interesting problem to explain.

protected static function booting(): void
{
static::creating(function (AuditLog $log) {
$log->integrity_hash = hash('sha256',
$log->user_id .
$log->action .
$log->model_type .
$log->model_id .
$log->created_at
);
});
}

Separation of visibility from editability. Administrators can filter, search and export audit records. They can annotate them with amendments. They cannot touch the original. This is not a limitation. This is the feature working correctly.

If a client cannot accept this counter-proposal and insists on raw edit access to audit records, that is information. Very useful information about whether you want to be the person who built this system when the investigators come knocking.

What I Actually Did

I documented the requirement in writing, proposed the above alternative in writing and requested a formal response in writing.

I use the word “writing” three times in that sentence on purpose.

They pushed back. They said the counter-proposal was “too restrictive” and that the system needed “flexibility.”

Flexible audit trails. That is a new one.

I have nothing further to add on what happened after that. What I will say is that a developer’s job is to build systems that work correctly. A system with editable audit records is not working correctly, regardless of what the spec says. Your signature on the code is on every line of it. The client moves on. The code remains.

Read the Spec Carefully

Most red flags in client work are not loud. Nobody shows up to the kickoff meeting twirling a moustache. It is usually a single clause. A throwaway line. A requirement that sounds almost reasonable until you think about it for thirty seconds.

Read the spec carefully. Ask uncomfortable questions. Propose alternatives that actually make technical sense. Document everything.

And if someone tells you they need full control over the audit data, the records specifically designed to hold people accountable, ask yourself one question.

Accountable to whom?

Because if the answer is “nobody, once the admins are done editing,” you now know exactly what kind of system you are being asked to build.

Whether you build it is up to you.

Have you been handed a spec that made your skin crawl? The comments are open. Let’s compare notes.

Found this helpful?

If this article saved you time or solved a problem, consider supporting — it helps keep the writing going.

Originally published on Medium.

View on Medium
They Wanted an Audit Trail. With an Edit Button. I Am Not Okay. — Hafiq Iqmal — Hafiq Iqmal