AWRA OpsHub Search

The Audit Trail That Leaves the Building

A hash chain proves an audit trail was tampered with — but only to someone who still holds a copy the attacker could not reach. Shipping every event out within a minute, to a log store your security team controls, is what turns a record into evidence. How the stream works, what it guarantees, and where it deliberately stops.

Security & Compliance Washingtone Aura 13 min read

At 02:14 on a Saturday somebody signs in with an administrator’s credentials, changes a supplier’s bank account, approves a payment run and exports the customer list. At 02:31 they reach the database itself, delete the last forty audit rows, and leave. On Monday the finance lead notices a payment nobody remembers approving, opens the audit log, and finds a perfectly ordinary Friday afternoon followed by nothing at all. The log is intact. Every check on it passes. It simply ends early.

That is the failure this post is about, and it is not the one most audit-trail discussions worry about. The usual fear is an edit: someone changes a row to say a different person approved the payment. Good audit design catches edits. The harder case is the trail that has been shortened — the most recent entries removed, so that what remains is internally consistent, honest about everything it still contains, and silent about the only hour that mattered.

No amount of cleverness inside the system fixes that, because the system is what was compromised. The fix is boring and physical: a copy of every event, made within a minute of it happening, held somewhere the attacker would also have to break into. This is what security teams mean when they ask whether you can “stream to our SIEM”, and it is worth understanding why they ask before deciding whether the answer you are given is any good.

Why a chain alone cannot see the end of itself

Every audit row in AWRA is signed over its own content and the signature of the row before it, so an edited row stops matching its signature and a deleted row leaves its successor pointing at nothing. We wrote about that mechanism, and about how a legitimate retention purge is explained inside the same chain, in The Excuse Is Also in the Chain. It is good at what it does. Here is what it cannot do, and no design of its kind can.

  • It cannot see a missing tail. Each row vouches for the one before it. Nothing vouches for the row after the last one, so removing the newest rows leaves a shorter chain that verifies cleanly.
  • It accepts a start above one. Retention removes the oldest entries on purpose, so a chain beginning at entry 4,812 is normal and is treated as an anchor rather than as damage.
  • It is checked by the system it protects. The verifier runs on the same servers and reads the same database. Whoever owns both can also decide what the verifier gets to read.
  • Its signing key lives with the application. The key is deliberately not in the database, so a database leak alone cannot re-sign rows. An attacker who holds the application server as well could, in principle, re-sign a rewritten history from top to bottom.

None of those is a flaw in the chain. They are what “self-contained” means. A tamper-evident log tells you that something changed relative to a copy you trust, and inside the building there is no copy the intruder could not also reach. The chain supplies the fingerprints; the external store supplies the second set of records to compare them against.

An audit trail stored only inside the system it audits is a statement the system makes about itself. Evidence is what somebody else kept.

What leaving the building actually buys

Go back to Saturday night with a stream switched on. At 02:14 the sign-in is written to the audit log; within a minute it is in the security team’s log store, alongside the bank-detail change at 02:16 and the approval at 02:19. When the intruder deletes the last forty rows at 02:31, they are deleting copies. The originals left the building fifteen minutes earlier.

On Monday the comparison is mechanical rather than forensic. The log store holds sequence numbers up to, say, 10,447. The application’s own log ends at 10,407. Each event in the store carries the signature of the event before it, so the store can show that its own copy is unbroken from 10,400 to 10,447 — and therefore that the forty missing rows existed, in that order, with those signatures, before anyone removed them. The question stops being “did something happen?” and becomes “what do these forty rows say?”, which the store can already answer.

A trail kept only in the application

  • Edits and gaps between rows are detected
  • Removal of the newest rows leaves a clean, shorter chain
  • Checked by the same servers an intruder controls
  • Retention is whatever the application’s settings say
  • Investigators need access to the system under investigation

The same trail, streamed out every minute

  • Edits and gaps are detected, and so is a shortened tail
  • A copy exists that the intruder would have to breach separately
  • Checked by a team whose access is separate from the application’s
  • Retention is set by your security team’s policy, not ours
  • Correlated with firewall, identity and endpoint logs in one place

The last line is the quiet benefit. A SIEM is where the sign-in from an unfamiliar country, the identity provider’s risk alert and the bank-detail change can sit on one timeline. An audit log that only lives inside the operations system can never be joined to the rest of the evidence without someone exporting it by hand — usually after the incident, which is exactly when the export is least trustworthy.

How the stream works

Streaming lives under Settings → Audit Log Streaming. You choose a format, paste an HTTPS endpoint and a token, and switch it on. Once a minute a scheduled job looks at every workspace with streaming on and sends whatever is new.

1 min
between sends
500
events per batch, up to four batches a run
3
formats: signed JSON, Splunk HEC, Datadog
60 min
longest wait between retries
  1. Read from a cursor

    Each stream remembers the last audit entry it delivered. A run reads the next entries after that point, oldest first, five hundred at a time — so a backlog after an outage drains in order rather than in whatever order the database prefers.

  2. Send the batch

    The batch goes out in the destination’s own shape: newline-delimited events with the Splunk token header, an array of log entries with the Datadog API key, or a JSON body carrying a Bearer token and an HMAC-SHA256 signature of the body in X-Awra-Signature so your receiver can confirm it came from us unaltered.

  3. Move the cursor only on acceptance

    The cursor advances only when the destination answers with a success status. A timeout, a refused connection or an error status leaves it exactly where it was, so the same entries are offered again on the next attempt and nothing is skipped.

  4. Back off, then try again

    A failed send waits one minute, then two, four, eight, sixteen, thirty-two, and then an hour between attempts until the destination recovers. The first success clears the error and resets the wait.

One honest consequence of “move only on acceptance”: delivery is at least once, not exactly once. If your endpoint accepts a batch and the answer is lost on the way back, we cannot tell that from a failure, so the batch is sent again. Every event carries its audit id and its chain sequence number, which makes de-duplication on the receiving side a one-line search. We chose a possible duplicate over a possible gap, because a duplicate is visible and a gap is the thing this whole feature exists to rule out.

The destination is checked twice

The endpoint must be HTTPS on a public address. That is checked when you save it, and again at every send — the name is resolved, every address it returns is checked, and the connection is pinned to the checked address with redirects refused. Without the second check, an endpoint that resolved to a public server on Monday could be pointed at an internal address on Tuesday, and the audit log would be sent somewhere inside the network it describes.

What an event carries

Every event is one audit entry, in full, plus its place in the chain. The receiving side gets enough to answer who, what, when, from where and to which record without coming back to us.

Field What it is for
Entry number and time The entry’s identity and when it happened, for ordering and de-duplication
Actor — who, what kind, name and email Who acted, whether a user, an API key or the system itself
Action, module, route and method What was done and through which screen or endpoint
IP address Where the request came from, to join with network and identity logs
Subject — record type and number, description, detail Which record was touched, in words and in the detail the module recorded
Chain position, previous signature, own signature The entry’s position in your workspace’s chain and the signatures that link it to its neighbours

Notice what the receiving side can and cannot do with the last row. With the sequence numbers and the two signatures it can prove its own copy is continuous — every event links to the one before it, and no number is skipped. What it cannot do is recompute a signature from the content, because the signing key stays with the application. That is deliberate: a key shared with every customer’s log platform would be a key anyone could sign with. The stream’s job is to put an untouchable copy of the signatures somewhere else; the comparison is between that copy and what the application says today.

The event is not minimised. The actor’s name, email address and IP address leave with it, because an investigation that has to come back to us to find out who “user 41” was is an investigation that depends on the system under suspicion. The consequence is worth saying plainly: once an event is in your log store, your log store’s retention governs it. When AWRA’s own retention policy later anonymises an old entry, the copy you already hold is untouched. That is the point of holding it, and it means the SIEM’s retention needs to match your privacy policy as well as your security one.

Who controls the stream, and how you know it is working

Anyone with permission to view settings can see the page; only someone who can edit settings can change the destination, switch it off or send a test. The token is stored encrypted, never shown again after it is saved, and left blank on later edits to keep the current one. The API status view reports the host, format, last success, last error and backlog, and omits the token entirely.

Every save is itself an audit entry naming the destination host and the format, though never the token. Pointing the stream at a different host therefore shows up — in the application’s log, and in the stream, which delivers that entry to the new destination. Since an attacker’s first move against a stream is to redirect it or switch it off, your log store should also alert on silence: a workspace that normally produces events every few minutes and has produced none for an hour is a finding, whatever the reason.

The settings page shows three numbers — whether streaming is on, when the last batch was delivered, and how many entries are waiting — and, after a failure, the destination’s own answer and the time of the next retry. Send a test event pushes one synthetic entry through exactly the same path, so a wrong token or a firewall rule fails on the settings page rather than quietly at 02:14 on a Saturday.

You are connecting a destination for the first time and already keep older audit exports elsewhere

Start from now

Leave the box ticked. The stream begins at today’s newest entry and your log store is not flooded with years of history it already has.

This log store will be the evidence of record and nothing else holds the history

Send the whole log first

Untick it. The existing log is replayed oldest first, in batches, before new events; the waiting count on the settings page shows the backlog falling.

Your endpoint has been unreachable for hours

Fix the endpoint, not the cursor

Nothing was skipped. Entries wait behind the cursor and the next successful send picks up where the last one stopped.

What streaming does not promise

A stream shrinks the window in which a trail can be quietly shortened; it does not close it to zero. An entry written at 02:14 and deleted from the database at 02:14:30, before the next send, never left the building. While your endpoint is down, everything in the backlog is in the same position. The protection is proportional to how promptly events leave and how reliably your destination accepts them, which is why the waiting count and the last-error line are on the settings page rather than in a log file.

Nor does streaming replace the permanence inside the application. Audit entries cannot be deleted from any screen — the argument for that is in An Audit Trail Nobody Can Delete — and the chain still catches edits and gaps between rows. The three work as layers: nobody can remove an entry through the product, nobody can alter one through the database without the chain noticing, and nobody can shorten the trail without the external copy disagreeing.

Five questions for any vendor that says it streams to your SIEM

If my endpoint is down for six hours, what happens to the events from those six hours?

What you will hear

They are retried.

How to read it

Ask whether delivery reads from a cursor that moves only on acceptance, or from an in-memory queue that is dropped on restart. Only the first means nothing is lost.

Can my log store tell, from its own copy, that no event is missing?

What you will hear

Every event has an id.

How to read it

An id is not a sequence. You want a per-workspace position with no gaps and a link to the previous event, or you cannot tell a quiet hour from a deleted one.

Can I get the same event twice?

What you will hear

No, never.

How to read it

Over a network, “never” means a lost acknowledgement drops a batch. “Occasionally, and here is the key to de-duplicate on” is the honest answer.

Who in my organization can switch the stream off, and is that recorded?

What you will hear

Admins can.

How to read it

Then ask where the record goes. Plan to alert on silence in your log store, because the off switch is the first thing an intruder looks for.

Where is my HEC token stored, and can anyone read it back?

What you will hear

It is secure.

How to read it

Ask whether it is encrypted at rest and write-only on screen. A token that can be displayed is a token an intruder can lift and reuse to send forged events to your SIEM.

Our take

Tamper evidence is a comparison, and you cannot compare a record with itself. Signing each audit entry over the one before it makes edits and gaps visible; only a copy held somewhere else makes a shortened trail visible, and a shortened trail is what a capable intruder leaves. So send every event out within a minute, move the cursor only when the other side has accepted, prefer a duplicate to a gap, and let the security team own the copy and its retention. If you are judging a vendor’s streaming, unplug its endpoint for an hour and see whether the hour arrives.

The straight answer

What AWRA OpsHub does today

  • Streaming from Settings → Audit Log Streaming to Splunk’s HTTP Event Collector, Datadog Logs, or any HTTPS endpoint as JSON signed with HMAC-SHA256.
  • A cursor that moves only on a successful answer, so an outage delays events and never skips them; delivery is at least once, with id and chain sequence on every event to de-duplicate on.
  • Retries with growing waits of one to sixty minutes, the destination’s last answer and the next retry time shown on the settings page.
  • Every event carrying its chain position and both signatures, so the receiving side can prove its own copy is continuous.
  • Destinations held to public HTTPS, checked at save and again at every send with the address pinned and redirects refused.
  • Tokens encrypted at rest and write-only, never displayed after saving and omitted from the API status.
  • Edit-settings permission to change, switch off or test, with every change recorded as an audit entry naming the host and format.
  • A test send and a backlog count, so a misconfigured destination fails on the settings page rather than during an incident.

More we can add to your workspace

  • Field selection for the stream, including pseudonymised actor emails and IP addresses for log stores that should hold less personal data.
  • A heartbeat event and a delivered final event when streaming is switched off, so a log store can tell a quiet workspace from a silenced stream without its own silence rule.
  • Alerts to your administrators when deliveries keep failing, by email and in the bell, beyond the warning on the settings page.
  • Several destinations per workspace, such as a SIEM and a long-term archive receiving the same events.
  • Replaying history from a chosen date to a new destination, for when you move log platforms after the stream is already running.
  • Per-entry public-key signatures, so your log store can check each event’s content on its own as well as the continuity of the chain.
  • Native syslog, Microsoft Sentinel and Elastic formats, and setting up the stream through the API and the mobile app as well as the web.

Where we point you to a specialist

  • We do not hand out the key that signs your audit chain. A key shared with a log platform is a key that platform, or anyone who breaches it, could sign forged history with.
  • We do not stream to private network addresses or plain HTTP, even on request. An audit log sent to an address inside a network is a way of mapping that network.

The heartbeat and the failure alerts are one build seen from two sides: the log store learning the stream has stopped, and your administrators learning it has.

More we can add to your workspace

Anything above that you need, we can build for you

Everything listed above as something we can add describes what ships in the standard product today — it is a starting point, 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 whatever you just read about. One qualification so this is worth what it claims: a small number of things on this blog we deliberately leave to a specialist rather than build — 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. 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 additions, which are the ones readers ask for 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

See how the audit trail is kept honest

Permanent entries, a signed chain your auditors can verify, exports for reviewers and a live stream to your security team’s log store.

Explore audit trail integrity

Frequently asked questions

Which SIEM and log platforms can receive the audit stream?

There are three formats: Splunk HTTP Event Collector, Datadog Logs intake, and JSON over HTTPS signed with HMAC-SHA256 for anything else that accepts an HTTPS post with a Bearer token.

How quickly does an audit event reach my SIEM?

A scheduled job runs every minute and sends everything new since the last delivered event, up to four batches of five hundred per workspace per run. In normal operation an event leaves within about a minute of being written.

What happens if my SIEM endpoint is down?

Nothing is skipped. The stream only moves past an event once the destination accepts it, so events wait while the endpoint is down. Retries wait one, two, four, eight, sixteen and thirty-two minutes, then an hour, and the settings page shows the last error, the next retry and how many events are waiting.

Can the same audit event arrive twice?

Occasionally. If your endpoint accepts a batch but the answer is lost, the batch is sent again. Each event carries its audit id and its chain sequence number, so the receiving side can discard a repeat. A possible duplicate was chosen over a possible gap.

Is personal data included in streamed audit events?

Yes. Each event carries the actor’s name, email address and IP address so an investigation does not depend on the system being investigated. Once an event is in your log store, that store’s retention applies, so set it to match your privacy policy.

Who can change or switch off audit log streaming?

Only people whose role can edit settings. Anyone who can view settings can see the status. Every change is recorded as an audit entry naming the destination host and format, and the token is stored encrypted and never displayed again.

Share this article

LinkedIn X WhatsApp

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