Immutable Audit Trail
Term 13 of 68 in the ERPStack technical glossary
What is Immutable Audit Trail?
An Immutable Audit Trail is a security logging pattern that records all system events, database updates, and user accesses in an append-only, tamper-proof table that cannot be altered or deleted by any user or administrator.
Immutable Audit Trail at a glance
- Rule
- Append only — 0 updates and 0 deletes; a correction is a new row referencing the old one
- Minimum fields
- 5: actor, action, entity, before/after state, and a UTC timestamp in ISO 8601
- Transaction
- Written in the same PostgreSQL 18 transaction as the change, so the 2 cannot diverge
- Retention
- Sealed to WORM storage where a regulation requires the record to outlive the database
- Built with
- Append-only PostgreSQL 18 tables written through Drizzle ORM 0.45 in the same transaction as the change, sealed to AWS WORM storage by Terraform-defined policy, read paths gated by RBAC and SSO
- Numbers that matter
- 5 required fields; 0 updates and 0 deletes; 1 transaction covering both the change and its record; retention matched to the governing rule
- Compare with
- Application logs in Sentry, which are rotated, editable and not evidence
- Commonly paired with
- RBAC, SSO, Row-Level Security, WORM storage on AWS, Next.js 16 server actions, and SOC 2, ISO 27001 or GDPR reviews
- Where it is required
- healthcare, finance, government and aerospace records, where SOC 2, ISO 27001, HIPAA and FDA 21 CFR Part 11 Compliance reviewers all read the same PostgreSQL 18 table.
How Immutable Audit Trail works in production
The ERPStack approach to Immutable Audit Trail
We integrate automated, cryptographic audit trails in our PostgreSQL databases. Every write is verified via trigger pings, providing permanent logs for security auditors.
Frequently asked questions about Immutable Audit Trail
What makes an Audit Trail immutable rather than just a log?
The absence of an update path. An Immutable Audit Trail is append-only by construction: corrections are new entries referencing the original, so the history cannot be quietly rewritten. Application logs are usually rotated, editable and stored beside the system that produced them, which makes them operational telemetry rather than evidence. The distinction matters exactly when someone disputes what happened.
What should each entry record?
Enough to reconstruct the change without the reader guessing. An Audit Trail entry needs the actor, the action, the entity affected, the before and after state, and a UTC timestamp — 5 fields that answer who, what, which, how and when. Storing only 'record updated' produces a log that satisfies a checklist and helps nobody during an actual investigation.
Why write the audit record in the same transaction?
Because otherwise the 2 can disagree. If the business change commits and the Audit Trail write fails, you have an unexplained state; if the audit write commits and the change rolls back, you have a record of something that never happened. Writing both inside 1 PostgreSQL 18 transaction makes them atomic, which is the only arrangement that stays correct under crashes.
How long should audit history be kept?
As long as the governing obligation, with the storage tier matched to it. An Audit Trail in the operational database is fast to query but shares that database's lifecycle, so records that must survive independently are sealed into WORM storage on a schedule. Keeping everything forever in the transactional store is a performance and privacy problem, not a compliance strategy.