Skip to main content

Anatomy of an audit trail

For eight years, part of my job was making sure laboratory computer systems could answer one question under oath: who did what, when, and why? In an FDA-regulated environment that answer is not a log file someone remembers to grep. It is an engineered subsystem with its own requirements, its own failure modes, and its own auditors.

This piece explains how that subsystem actually works. If you build software that regulated customers buy, this is the checklist their auditors walk in with.

What an audit trail is, precisely

An audit trail is a secure, computer-generated, time-stamped record of the creation, modification, and deletion of regulated data, kept so that the original value is never lost. That definition compresses four hard requirements:

  1. Computer-generated. Humans do not write audit entries; systems emit them as a side effect of the action. An entry a person can compose is an entry a person can compose falsely.
  2. Time-stamped. Every entry carries when, from a clock nobody can quietly adjust.
  3. Creation, modification, deletion. Not just "the record changed" but what it was before and what it became.
  4. Original value preserved. Overwriting history is the one unforgivable act. Corrections append; they never replace.

The same expectations apply to sign-offs, permission changes, and configuration changes, because those decide what the data means and who could touch it.

The architecture

Four responsibilities, deliberately separated:

Capture happens inside the transaction boundary of the action itself: a database trigger, an application service, or a platform facility. If the action commits, the audit entry commits with it. Capture bolted on afterward (a nightly diff job, a log scraper) fails the "computer-generated" test the moment the two disagree.

Storage is append-only. No update or delete privilege exists on the audit store for anyone, including administrators. Tamper evidence can be layered on with hash chaining, where each entry carries a hash of the previous one, so removal or edit breaks the chain visibly.

Review is a scheduled human activity, not a dashboard nobody opens. In the labs I supported, audit trail review was itself a procedure with a signature, and "we reviewed the trail" produced its own record.

Here is the write path for a single change, with the fields that matter:

The entry that lands in the store: who (a named individual account), when (trusted time), where (record and field), what (old and new values), and why (a reason, captured at the moment of change).

The design decisions that actually matter

Each of these looks optional until an auditor, or an incident, proves otherwise.

Named identity, no exceptions

Shared accounts destroy attributability: an entry that says labuser3 answers "who" with "one of eleven people." Every human gets a unique account; every service gets a service account that is visibly not a human; and re-authentication guards the moments that matter, such as electronic signatures. Half of the user-access administration work I documented existed to keep this one property true.

Time nobody can argue with

All servers sync to a common time source, timestamps normalize to a single zone (or carry their offset), and ordinary users have no path to the system clock. Without this, two entries can honestly disagree about the order of events, and "contemporaneous" becomes a negotiation.

The reason travels with the change

"Why" captured at the point of change costs the user five seconds. "Why" reconstructed eighteen months later costs an investigation. Systems that force a reason code, free text, or a change-request reference into the audit entry make every later question cheaper to answer.

Rejected actions are evidence too

Failed logins, permission denials, and validation rejections tell you what somebody attempted. A trail that records only successes documents the polite version of history.

Retention means readable, not just kept

Regulated records live for years, often past the software that created them. The trail must stay reviewable that whole time: exportable to a durable, human-readable format, with enough context (field labels, user names, units) to make sense without the original application running.

The ALCOA+ test

Auditors compress all of this into a mnemonic. It doubles as a design checklist:

PrincipleThe system must ensure
AttributableEvery entry names one authenticated individual or service
LegibleEntries are readable by a human, now and at year ten
ContemporaneousEntries are written at the moment of action, by the system
OriginalThe first recording survives; corrections append rather than replace
AccurateEntries reflect what actually happened, validated at capture
+ CompleteAll changes, including deletions and rejections, are covered
+ ConsistentTimestamps and sequence agree across the system
+ EnduringThe record survives media, software, and vendor lifecycles
+ AvailableRetrieval works during an inspection, not just in theory

How this maps to modern systems

If you build SaaS and a pharmaceutical, medical, or financial customer appears, the translation is direct: structured event logs with before-and-after values, written in-transaction; object-lock or WORM storage tiers for immutability; hash chains or signed digests for tamper evidence; SSO with named identities and service principals; NTP discipline; and an export path a non-engineer can read. None of it is exotic. All of it is deliberate.

The pattern generalizes past compliance, too. Git history, financial ledgers, and incident timelines all rest on the same bet: systems that never erase their past are the only ones that can prove anything about it.