Architecture

Audit Trails: Designing Systems That Can Prove What Happened

Updated December 17, 2019By the CalliArc team

Key takeaway

An audit trail records who did what, to which record, when, and what the values were before and after — stored append-only, separately from the data it describes. Application logs don't qualify: they're unstructured, rotated, and usually writable by the same process that made the change.

Auditability is normally introduced by a compliance requirement and then turns out to be one of the most useful features in the system — because "who changed this?" is asked far more often by support than by auditors.

What each entry must contain

  • Actor — the authenticated user, or the system process, with enough identity to be meaningful a year later.
  • Action and target — what was done, to which entity and id.
  • Before and after values for the fields that changed. Without the old value, the trail tells you something happened but not what.
  • Timestamp in UTC, plus the source: IP address, session, or API client.
  • Context: the reason, ticket, or approval where your process requires one.

Storage rules

  • Append-only. No update or delete path should exist in the application, and the database user writing it should not have permission to modify it.
  • Separate from the operational tables it describes, so a rollback or a purge of business data doesn't remove the record of it.
  • Retention defined by regulation or policy, not by disk convenience — and enforced, because keeping it forever has its own risk.
  • Consider a tamper-evident approach such as periodic hashing where the stakes justify it.

Record reads too, where it matters

For regulated personal data, who looked at a record is as important as who changed it. Access logging is the only way to answer the question an investigation actually asks — did this employee view patients or customers they had no business reason to see. Volume is the challenge; log the read of sensitive entities rather than every page view.

Make it usable

  • Expose it in the admin interface, filtered by record and by actor. A trail only a developer can query won't be used by the people who need it.
  • Present changes in business language — "status changed from pending to approved" — not as a raw column diff.
  • Include system and integration actions, clearly attributed, so an automated change isn't mistaken for a person.
  • Test it in your incident drills: the first thing you'll want during a real investigation is a reliable timeline.
Share LinkedIn X

Ready to build it right?

Get a transparent, milestone-based estimate for your project in a free consultation.

Book a free strategy call