AWRA OpsHub Search
Audit trail integrity

If somebody edits your audit trail, you will know.

Every entry AWRA records is sealed to the entry before it. Change one and its seal stops matching. Remove one and the next entry points at something that no longer exists. Verify the whole chain from the audit page in one click — and export it so somebody outside AWRA can check the same thing without taking our word for it.

1 click

Verify the entire chain from
the audit page. No ticket to us.

0 delete

Nobody can bulk-delete audit
history — not even an owner.

CSV + JSON

Streamed export carrying the seals,
verifiable without us.

Where this started

We shipped a button that let an administrator delete their own audit history. Then we took it out.

It was there for an honest reason — the trail gets noisy, and tidying it up felt like housekeeping. It was still indefensible. An audit trail the audited party can erase is not an audit trail, and no amount of surrounding rigour fixes that. So rather than gate it behind a permission or log the deletion, we removed the capability. This page describes what replaced it.

Until 13 Aug 2026

Select rows, press delete, gone.

Any administrator with access to the audit page could tick a range of entries and bulk-delete them. The entries that recorded their own last hour of activity were as deletable as any other. Nothing downstream would ever have noticed the absence, because there was nothing that could.

Now

History leaves one way, on a schedule you set.

There is no delete path from the interface, the API, or an administrator’s own account. Audit history expires only through the retention policy your organization configures — and each expiry writes a receipt naming the range it removed, so the gap it leaves is accounted for rather than mysterious.

Why this matters more than the cryptography. Hash chains are the interesting part of the engineering, but they are the second line of defence. The first is that the delete does not exist. A chain that detects a deletion nobody was able to make is a belt behind braces — and any vendor showing you the chain without telling you who can still delete rows is showing you the wrong half.

How a chain notices

Three ways to interfere with a trail, and what each one leaves behind.

Each entry carries a seal computed over its own content together with the seal of the entry before it. That single property is what makes all three kinds of interference visible: an edit invalidates a seal, a deletion orphans a link, and an insertion collides with the numbering. Recomputing the seals to cover any of it requires a key that lives outside the database — so getting into the database is not enough.

content_mismatch

Somebody edited an entry

A deletion is rewritten as an update, an actor name is swapped, an IP address is cleaned up. The entry still exists and still looks plausible — but its content no longer produces the seal stored beside it.

Entry #8815 — content_mismatch
expected b2aa…6f40, computed 91c7…04ba

broken_link

Somebody removed an entry

Delete an entry and the one after it is left pointing at a seal that no longer belongs to anything. The trail reads continuously to a human eye; the link says otherwise.

Entry #8816 — broken_link
links to b2aa…6f40, predecessor holds 7e05…31d8

sequence_gap

Somebody spliced the numbering

Positions are consecutive per organization. Removing entries leaves a hole in the count; inserting one has to collide with a position that is already taken. Either way the arithmetic stops working.

Entries #8817–#8819 — sequence_gap
3 positions absent, no retention receipt covers them

Read that last line carefully — it is the whole design. The verifier does not say “entries are missing”. It says entries are missing and nothing accounts for them. Legitimate removal exists: your retention schedule is supposed to delete old history. The difference between housekeeping and interference is whether a receipt was written at the time, which is the next section.

Deleting on purpose, and saying so

Two things legitimately break a seal. Both of them announce themselves.

A system that treats every discontinuity as an attack is a system whose integrity report is ignored within a month. Retention deletes old entries by design, and a data-protection erasure request rewrites entries in place by design. Both are supposed to happen. Both are made distinguishable from tampering at the moment they happen — never afterwards, and never by repairing the evidence.

Retention expiry

The purge writes down what it took.

When your retention schedule removes expired history, it records the exact span of positions it deleted into its own evidence entry — which is itself a sealed entry in the chain, so the receipt cannot be quietly removed to hide the removal. When the verifier later finds that hole, it reconciles it against the receipt and reports the chain as intact.

Entry#8820 · retention_purge
PolicyAudit logs · 730 days
Removedpositions 4,001–5,187
Sealedc4d8…12fa

A hole with no receipt covering it stays reported. That case is tested deliberately, because it is the one an attacker would try to disguise as routine cleanup.

Erasure & anonymisation

The entry is stamped — and the seal is left broken on purpose.

Honouring an erasure request rewrites personal details inside old entries, which by definition stops them matching their seals. Those entries are stamped as redacted and reported separately, so an auditor sees the difference between “this was anonymised on request” and “this was altered”.

Entry#2044 · redacted
ActorAnonymized
Stamped13 Aug 2026, 11:02
Sealleft as originally written

The obvious move — recompute the seal after redacting — is the one thing we will not do. If redacting an entry also repaired its seal, then anyone who could edit an entry could label their edit a redaction and walk away with an intact chain. Leaving it broken is what keeps the label honest.

Don’t take our word for it

This is a claim you can test in a trial workspace, in about four minutes.

Most integrity claims in this market can only be evaluated by reading a vendor’s documentation and believing it. This one has a button. Do the following in a free workspace and you will have exercised the control end to end without speaking to us.

Do a few things worth recording

Invite a user, change a role, approve something, delete a record. Each one writes an entry with an actor, a moment, a route and an address.

Press “Verify integrity”

It walks every entry in your workspace — not a sample — and reports how many were checked and anything it found. The verification is itself recorded, so you will see it appear in the trail you just verified.

Export the trail

CSV or JSON, carrying each entry’s position, its own seal and the seal it links to. Confirm for yourself that consecutive rows chain together, in a spreadsheet, with no access back into AWRA.

Look for the delete button

This is the step we would want a buyer to spend the longest on. There isn’t one — on the page, in the API, or behind an owner-level permission. Try to find it, then ask every other vendor on your shortlist the same question.

Evidence that travels

An export nobody can open is not evidence, and neither is one only we can check.

The point of exporting a trail is to hand it to somebody else — an auditor, a donor, a regulator, your own security team, a lawyer. So the export is built for that recipient rather than for a screenshot.

Streamed, so size is not a limit

A two-year trail under a typical retention policy runs to millions of entries. The export streams rather than assembling itself in memory first, because an export that gives up at a hundred thousand rows is the same as no export on the day somebody asks for the year.

The seals ride along

Each row carries its position, its own seal and the seal it links to. A recipient can confirm the entries chain to one another using nothing but the file — no access back into the system that produced it, and no need to trust the vendor who wrote it.

Filtered exactly as you see it

Whatever you have narrowed the page to — a module, an action, one person, a date range, a search — is what the file contains. An auditor asking for “everything user X did in March” gets that file, not the whole trail with instructions.

CSV for people, JSON for systems

CSV opens in Excel without mangling non-ASCII names, which is what a reviewer actually wants. JSON is the shape to hand a SIEM, a data warehouse or a script.

Exporting is itself an event

Reading the trail in bulk goes into the trail: who exported, in what format, with which filters, when. A trail that does not record who read it is missing the entry an investigation most often needs.

And a command line for the schedule

Verification also runs from the CLI and exits non-zero when the chain is broken, so it can be wired into whatever already watches your infrastructure.

For the security questionnaire

The rows this answers, and the wording we would want you to use.

These questions turn up in almost every vendor assessment, and the usual answer is a marketing sentence that collapses on the follow-up. Here is what we would write in the box, phrased so it survives being read carefully by somebody whose job is to find the gap.

They askCan a customer administrator delete or modify audit records?

No deletion path exists — not in the interface, not in the API, not behind an owner-level permission. Records expire only through the customer’s configured retention policy, and each expiry writes a receipt naming the range removed. Modification is not offered as a feature; if it were performed directly against the database, the chain would surface it as content_mismatch on the affected record.

They askAre audit records tamper-proof?

They are tamper-evident, which is the accurate word and a deliberately different claim. Records are HMAC-chained per organization, so edits, deletions and insertions are detectable. Anyone with direct database write access can still alter data — what they cannot do is make the alteration consistent, because the keying material is not in the database.

They askHow far back does integrity assurance extend?

From the point the chain was established for that organization. Existing history was sealed as it stood at that moment, which sets the baseline from which tampering becomes detectable. It is not retrospective proof about the period before, and we will not describe it as such.

They askCan the audit trail be exported for independent review?

Yes — CSV or JSON, streamed, honouring the active filters, and carrying the chain values so the recipient can verify linkage from the file alone. Each export is recorded in the trail with the actor, the format and the filters used.

They askIs integrity verified continuously or on demand?

On demand today, from the audit page or the command line, over every record rather than a sample. The command exits non-zero on failure so it can be scheduled; wiring it to a specific alerting channel is deployment-side work rather than something we do for you, and we would rather say so than imply a monitoring service we do not run.

They askWhat is recorded per event?

Actor identity and email, action, module, route, HTTP method, URL, IP address, user agent, session, the subject record, a description and structured metadata — plus the chain position and seals. Impersonation, exports and the verification runs themselves are all events.

Use these against us too. Every one of these questions has a version we would fail, and the fastest way to find it is to ask us the follow-up rather than the question. The compliance matrix marks which of our control claims have been verified against the code and which have not, which is the document to read before a review rather than after one.

What it is, and what it isn’t

Read this part before you quote any of it in a tender response.

Integrity language is unusually easy to overstate, because the cryptography sounds absolute and the guarantee is not. Here is the line drawn where we would want it drawn if we were the ones being audited.

What you actually get

  • Detection, at the exact entry. The verifier names the position and the kind of problem, so an investigation starts at a row rather than at a table.
  • No delete path for anyone. Removing the capability is a stronger control than logging its use, and it applies to owners as much as to staff.
  • Independent verifiability. The exported file carries what is needed to check linkage without us, so your evidence does not depend on our continued cooperation.
  • Legitimate change kept distinguishable. Retention receipts and redaction stamps are written at the moment they happen, so nobody has to reconstruct intent later.
  • Separation from the database. The keying material is not stored in the tables being protected, so read-write access to the data is not sufficient to forge a consistent chain.

What we are not claiming

  • Not immutable, and not tamper-proof. Somebody with database access can still destroy records. They cannot make the destruction look like nothing happened, and that is the honest extent of it.
  • Not retroactive. The chain proves nothing about the period before it was established for your organization.
  • Not a blockchain, and not externally notarised. There is no distributed ledger and no third party timestamping your entries. If your requirement is external notarisation, this is not that.
  • Not continuously monitored by us. Verification is on demand or on a schedule you wire up. We do not watch your chain for you and will not imply that we do.
  • Not a certification. This is a control, not an attestation. It should help you pass an assessment; it is not itself one, and AWRA holds no SOC 2 or ISO 27001 report today.
  • Not streaming to your SIEM yet. Getting entries into Splunk, Sentinel or Datadog means pulling an export today. A push endpoint is not built.

One more limitation, because it will come up in a serious review. A legal hold can preserve individual entries inside a span that retention otherwise removed. The receipt for that purge records the range it covered rather than a list of every position taken, so a hold leaving islands inside a purged span is reconciled as a range rather than entry by entry. Exact manifests would tighten it, and that is a known refinement rather than a claim we are quietly hoping nobody tests.

What changes

The trail stops being a log and starts being evidence.

None of this prevents somebody inside your organization doing something they should not. What it changes is whether the record of it survives contact with the person who would rather it didn’t.

An investigation has a starting row

The verifier names the position and the failure type, so you begin at one entry instead of auditing a table.

Nobody can tidy up after themselves

The delete is gone rather than gated, which is the version of that control that holds when the person doing it is the administrator.

Evidence outlives the relationship

An export that verifies on its own does not stop being evidence if you stop being a customer.

Erasure requests stop costing integrity

Honouring a data-protection request no longer looks identical to interference, so you can do both properly.

Assessment answers get shorter

Six of the most common questionnaire rows have a specific answer with a mechanism behind it instead of a paragraph of reassurance.

Retention becomes defensible

Old history still expires on your schedule — the difference is that the gap it leaves carries a receipt.

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