AWRA OpsHub Search

An Audit Trail Your Admin Can Delete

The interesting part of audit-log integrity is cryptographic. The important part is a question with a one-word answer: who can delete a record? We shipped the wrong answer to that, and this is what we did about it.

Security & Compliance Washingtone Aura 11 min read

For most of this product's life, an administrator could open the audit page, tick a range of entries, and delete them. Including the entries recording what they had done in the previous hour. Nobody exploited it, as far as we can tell, and it was there for an entirely mundane reason: the trail gets noisy, and tidying it looked like housekeeping. It was still indefensible, and no amount of surrounding rigour fixed it.

We took the button out on 13 August 2026. This post is about why that mattered more than the cryptography we shipped alongside it, and about the four or five questions worth asking any vendor whose brochure says "audit-ready".

A log and an [audit trail](/glossary/audit-trail) are different objects

They look identical on a screen: a list of things that happened, with names and timestamps. The difference is entirely in who controls them, and it decides what each one is worth in an argument.

A log

  • Exists to help somebody debug or reconstruct.
  • Can be trimmed, rotated or cleaned up when it gets large.
  • Is maintained by the same people whose actions it records.
  • Answers "what happened?" when everyone involved is cooperating.
  • Is perfectly adequate — for the job of being a log.

An audit trail

  • Exists to be read by somebody who does not trust the account of events they were given.
  • Cannot be curated by the parties it describes, or curation is the only fact it establishes.
  • Has to survive the interest of whoever would prefer it read differently.
  • Answers "what happened?" specifically when someone is motivated to say otherwise.
  • Is worthless the moment the audited party holds the delete key.

Almost every operational system ships the first and markets the second. The tell is that the delete is usually not hidden — it sits in the interface, described as retention or cleanup, and nobody in the buying process ever asks who can press it.

A trail the audited party can erase does not record what happened. It records what they were content to leave.

Why removing the button beats controlling it

The obvious fixes are worse than they look, and we considered all three before choosing the boring one.

Option one

Gate the delete behind a higher permission

Which higher permission? The threat is not a storekeeper — it is somebody with administrative access. Restricting the delete to owners restricts it to precisely the person most able to cause the problem, and hands them a defence: the capability was authorised.

Option two

Log the deletion

Now you have an entry saying entries were deleted, in the same table, deletable by the same person. This is turtles all the way down, and it stops one level short of where it needs to.

Option three

Remove the capability

No permission model to reason about, no meta-log, nothing to review. Records leave through a retention schedule and through nothing else. Less code than either of the above, and the only one that holds when the actor is the administrator.

The third is not clever. That is its main virtue. Controls that depend on the attacker not holding the relevant permission are not controls when the attacker is an administrator, and administrative misuse is the scenario an audit trail exists for. Everything else is served adequately by a log.

What a hash chain adds, precisely

With the delete gone from the application, one route remains: somebody with direct access to the database. That is what the chain is for, and it is worth being exact about what it does, because this is where integrity marketing usually stops being accurate.

Every entry carries a keyed hash computed over its own content and the hash of the entry before it, in a chain private to your organization. Three properties fall out of that one arrangement:

  1. Edit an entry, and its own hash stops matching

    Rewrite a deletion as an update, swap an actor name, tidy an address — the content no longer produces the hash stored beside it. The verifier reports the exact entry.

  2. Delete an entry, and the next one points at nothing

    The following entry still holds the hash of the record that used to precede it. The trail reads continuously to a human; the link does not resolve.

  3. Insert an entry, and the arithmetic fails

    Positions are consecutive within your organization. A spliced record either collides with a position already taken or leaves a hole where one should be.

Repairing any of that means recomputing the hashes for every entry from the tampered one to the present. That requires the keying material, which is derived from application configuration rather than stored in the tables being protected. Getting into the database is therefore not sufficient — which is the entire point, because "somebody got into the database" is the scenario.

And what it does not add

Here is the sentence we would want a buyer to hold on to, including when reading our own material: tampering becomes detectable, not impossible. Somebody with write access to your database can still destroy records. What they cannot do is make the destruction look like it never happened.

What each layer is actually good for

No delete path in the product

The load-bearing control. Closes the route an administrator can actually reach, which is the one that matters in practice.

The real control

Hash chaining per organization

Makes direct database interference visible, and names the entry. A second line, behind the first.

Detection

Export carrying the chain values

Lets a recipient verify linkage from the file alone. Your evidence stops depending on the vendor's continued cooperation.

Independence

Retroactive proof about the past

The chain starts the day it is built. Entries already in the table were sealed as they stood at that moment; it establishes a baseline, and says nothing about what happened before.

Impossible

Prevention of database-level destruction

Nothing in an application layer stops someone with credentials to the database from deleting rows. Detection is the honest goal.

Not on offer

External notarisation or a distributed ledger

No third party timestamps your entries. If your requirement is notarisation by someone who is not us, this is not that.

Not built

The two rows we most expect to be quoted out of context are the last three. If you are writing us into a tender response, quote those as well.

The backfill sentence, in full

When we turned this on, existing entries were hashed as they stood at that moment. If somebody had edited an entry the week before, the chain sealed the edited version and reports it as intact forever. That is not a flaw to be fixed — it is what any such scheme can do — but it is a sentence that must appear whenever a baseline date is mentioned, and it is missing from most vendor descriptions of the same mechanism.

The hard part was legitimate deletion

Anyone can chain records together. What determines whether the resulting integrity report gets read or ignored is how it handles the two things that are supposed to break it.

Retention has to be able to delete

Your retention policy exists to remove old history — ours defaults to keeping audit records for 730 days — and every removal necessarily orphans the link held by the record after it. If the verifier treated that as tampering, it would report the chain as broken every time the schedule ran, and within a month nobody would look at it.

So each purge records the span of positions it removed, into its own evidence entry, which is itself a sealed entry in the chain. The verifier reconciles the hole against the receipt. A hole with no receipt covering it stays reported, and that case is tested deliberately, because disguising interference as routine cleanup is the obvious move.

Data-protection erasure has to be able to rewrite

Honouring an erasure request means overwriting personal details inside historical entries. There is no version of that which leaves the content matching its hash — anonymising the record is precisely a content change.

Those entries are stamped as redacted at the moment it happens, and reported in their own category. And then the interesting decision: we deliberately do not recompute the hash afterwards, even though we easily could and the chain would look tidier for it.

If redacting a record also repaired its seal, then anybody who could edit a record could label their edit a redaction and walk away with an intact chain.

Leaving the hash broken is what keeps the label honest. The report reads "this record was altered, and it was labelled a redaction at the time" rather than "this record is fine". Those are different statements, and only one of them is true.

Five questions for whoever you are evaluating

These work on us too, and you should use them that way. Each one has a version we would fail — the fastest route to finding it is the follow-up rather than the question.

Ask these in the demo, not in the questionnaire

Who can delete audit records, and can you show me the screen where it would happen?

What you will usually hear

"Only administrators", or "it's controlled by permissions".

How to read it

Both of those are yes. Ask them to open the audit page and try. If the capability exists at all, the trail is a log — the threat model is an administrator, so restricting it to administrators restricts it to nobody.

If I edited a record directly in the database tonight, what would tell you tomorrow?

What you will usually hear

Silence, then something about database access being restricted.

How to read it

Access control is a different control. The question is detection. "Nothing would tell us" is an acceptable answer honestly given — it is the confident hand-wave that should worry you.

Can I export the trail so my own auditor can verify it without your help?

What you will usually hear

"Yes, you can export to CSV."

How to read it

Ask what is in the file. An export with no integrity values is a list of claims that has left the system that could substantiate them. Ask, too, whether the export itself is recorded.

What date does your integrity assurance start from?

What you will usually hear

A confused pause, or "it's always been on".

How to read it

Any scheme like this has a start date and cannot speak about what happened before it. A vendor who has not thought about that has not thought about the mechanism either.

When your retention policy deletes old records, how does that differ from tampering?

What you will usually hear

"Retention is a normal process."

How to read it

It is, and it also produces exactly the same evidence as a deletion. If nothing is written down at the time, the two are indistinguishable afterwards — which means the integrity report cannot be believed in either direction.

What we would actually want tested

The reason we built it in this order is that the resulting claim can be exercised by a buyer rather than read. In a free workspace, four steps: do a handful of things worth recording, press Verify integrity, export the trail and confirm the rows link to one another in a spreadsheet, and then go looking for the delete button. The fourth is the one worth spending time on, because you can ask every other vendor on your shortlist the same thing.

Audit trail integrity — the straight answer

What AWRA OpsHub does today

  • No deletion path for audit records anywhere: not in the interface, not in the API, not behind an owner-level permission.
  • Keyed hash chaining per organization, so edits, deletions and insertions are detectable and reported against the exact record.
  • Verification over every record — not a sample — from the audit page in one click, and from the command line with a non-zero exit so it can be scheduled.
  • Streamed CSV and JSON export honouring the active filters and carrying the chain values, so a recipient can verify linkage from the file alone.
  • Retention purges that record the span they removed into a sealed receipt, so legitimate expiry is distinguishable from interference.
  • Erasure and anonymisation stamped and reported separately, with the hash deliberately left unrepaired.
  • Exports, impersonation and the verification runs themselves recorded as events in the trail.

What it does not do

  • Not tamper-proof and not immutable. Somebody with direct database write access can still destroy records; the guarantee is that they cannot make it look like nothing happened.
  • No retroactive assurance. The chain establishes a baseline from the day it was built for your organization.
  • No streaming push to a SIEM. Getting records into Splunk, Sentinel or Datadog means pulling an export today.
  • No continuous monitoring by us. Verification is on demand or on a schedule you wire up, and we will not imply we watch your chain for you.
  • Legal holds that preserve individual records inside an otherwise purged span are reconciled against a range rather than an exact manifest. A known refinement, stated rather than hidden.

Not ours, by choice

  • No external notarisation and no distributed ledger. If your requirement is a third party timestamping your records, that is a different product category.
  • This is a control, not an attestation. It should help you pass an assessment; AWRA holds no SOC 2 or ISO 27001 report today, and a hash chain is not a substitute for one.

Every claim in the first list is exercisable in a free workspace in about four minutes, which is the standard we would like to be held to and the one we would apply to anyone else.

This is scope, not a ceiling

What is not built today can still be built for you

Anything described above as not built is a statement about what ships in the standard product today — not a limit on what AWRA OpsHub can do for your organisation. Kenya's eTIMS integration and its maintained payroll engine are both in the product because clients needed them and commissioned them; neither appeared by itself, and the same door is open for the gap you just read about. Two honest qualifications so this is worth what it claims: a handful of gaps on this blog are deliberate refusals rather than missing work — a statutory ledger we will not sign our name to, a rule that would decide a tax question for you, a clinical or member-funds record that belongs in a regulated system — and where that is true the post says so in those words rather than calling it a gap. Everything else is a scope, a timeline and a price.

The operational work, which is what most commissions actually are

An extra approval stage in a chain that does not match the standard one, a custom field set on employees or assets that only your sector needs, an expiry that has to block an order rather than send an email, a report your board asks for in a shape nothing produces, or a scanner or weighbridge feeding the goods-in door. These are the commissions we are asked for most often and the smallest ones we quote — and unlike a revenue-authority pipeline, none of them waits on a regulator.

The module-shaped gaps, which are the ones this blog admits most often

A price list with real discount authority, a customer-facing quotation that expires, a bill of materials or recipe costing, a staff advance that is issued, acquitted and chased, a member or unit ledger, a matching rule that holds a payment. Each of these is a build rather than a setting, and each has been quoted before — a bigger piece of work than a custom field, with a written spec and a date instead of a roadmap slide.

The report, document or pack nothing currently produces

The board pack in the shape your board actually asks for, a donor or funder layout, an invoice or receipt template carrying what your regulator or your customer expects, a dataset the report builder cannot reach yet. Usually the fastest thing on this list to deliver, because the data is already in the system.

Systems, rails and hardware you already run

The accounting package, CRM, online store, core banking or custom database you intend to keep — connected through our API so a fact is entered once and appears everywhere it is needed. Plus the physical edge: a scanner, a scale, a weighbridge or a till peripheral feeding the door it belongs to.

How it works: you describe the requirement, we return a written scope, timeline and cost, and once agreed it is built into your environment and maintained as part of the product. Nothing here waits on a regulator or a published specification, which is why operational builds are the ones we quote fastest. Tell us the requirement that would otherwise rule us out — that is a better first conversation than a demo.

Tell us what your operation needs

Our take

Ask who can delete before you ask how it is protected. If the answer is anybody inside the organization being audited, the cryptography is decoration — and if the answer is nobody, most of what remains is a solved problem. We had the wrong answer to the first question for a long time while doing reasonably well on the second, which is a fair description of most of this market.

The mechanics, the failure states and the questionnaire wording are on the audit trail integrity page. The related argument about why an authenticated, permission-gated approval already beats a drawn signature — which leans on the trail being trustworthy, and is the reason this work came first — is in The Approval That Needs No Pad.

Frequently asked questions

Can an AWRA administrator delete audit records?

No. There is no deletion path in the interface, in the API, or behind an owner-level permission — the capability was removed rather than restricted, because the threat model for an audit trail is administrative misuse and a permission gate does not address that. Records expire only through your configured retention policy, and each expiry writes a receipt naming the range removed.

Are AWRA audit logs immutable?

No, and we would not use that word. They are tamper-evident: each record is HMAC-chained to the one before it, so edits, deletions and insertions are detectable and reported against the exact record. Anyone with direct database write access can still destroy records. What they cannot do is make the destruction consistent, because the keying material is not in the database.

How far back does the integrity guarantee reach?

To the point the chain was established for your organization. Existing records were sealed as they stood at that moment, which sets the baseline from which tampering becomes detectable. It is not proof about the period before, and describing it that way to an auditor would be dishonest.

How is a retention purge different from tampering?

By a receipt written at the time. Each purge records the exact span of chain positions it removed into its own evidence record, which is itself sealed into the chain. The verifier reconciles a hole against those receipts and reports the chain as intact. A hole no receipt covers is still reported — that case is tested deliberately, because disguising interference as cleanup is the obvious move.

What happens to the chain when we honour an erasure request?

Anonymising a record rewrites its content, so it stops matching its hash. Those records are stamped as redacted and reported separately, and the hash is deliberately not recomputed. Repairing it would let anyone who can edit a record label their edit a redaction and walk away with an intact chain, which is exactly the move the mechanism exists to catch.

Can we verify an exported trail without AWRA?

Yes. The export carries each record's chain position, its own hash and the hash it links to, so a recipient can confirm that consecutive records chain to one another using the file alone. Recomputing the hashes from scratch would require the keying material, which we do not publish — the linkage check is what the file supports, and that is the property that matters when the file has left our system.

Does AWRA monitor our audit chain for tampering?

No. Verification is on demand from the audit page, or on a schedule you wire up — the command exits non-zero when the chain is broken so it can be attached to whatever already watches your infrastructure. We do not run a monitoring service over your chain and will not imply that we do.

Help Center

Need a quick answer while you read?

Run inventory, procurement, assets, sales, and field work with approved AWRA guidance for setup, migration, integrations, security, pricing, and support.

Search all approved AWRA public help articles.

Open Help Center