Audit Logs and Compliance
By the Syncfusion DevTutorials team · Last updated
Make every action traceable: an append-only, hash-chained audit trail that shows tampering, answers 'who changed this and when', and keeps each tenant's events exactly as long as its contract says.
Who Changed This, and When?
Ticket 42 at Acme Retail was closed without a reply, and its priority was lowered the week before. The customer escalates, and Acme's manager asks Northwind support a simple question: who did this, and when?
If the answer is "we don't know" or "the row was updated at 14:02", Northwind fails its customer and, for many enterprise contracts, an audit. Enterprise customers expect an audit trail: a record of every important action, which nobody can quietly edit, kept for as long as their compliance rules require.
The main idea: write an append-only event for every important action (who, what, when, before and after), chain the events with hashes so any edit shows, store them away from the data they describe, and keep each tenant's events for its own retention period.
TL;DR
- An audit event records who (user and tenant), what (action and target), when, from where (IP, client), and before → after values.
- Audit logs are append-only: never update or delete an event, except by the retention job.
- A hash chain stores each event's hash with the next event. Editing or deleting one event breaks every link after it.
- Answer audit questions with indexed queries by target, actor and time.
- Retention is per tenant: one contract says 1 year, another 7. Delete on schedule, never before.
A Real-World Example
An agent at a support company deletes a customer complaint and edits the database row that logged the deletion, so the history shows a colleague did it. The company's "audit log" was a normal table that application admins could update. Nothing in the system could prove what really happened. Its customer moved to a vendor with a tamper-evident audit trail.
What You Will Learn
- What to put in an audit event.
- Why audit logs are append-only and stored separately.
- How a hash chain makes tampering visible.
- How to answer audit questions.
- How to apply retention per tenant.
What to Record
Never put secrets or full personal data in audit events: no passwords, tokens or card numbers, and as little personal data as the question needs. Audit logs are kept for years, and they are copied to many places.
Append-Only and Separate
Write audit events to a store the application cannot update or delete: a table the app's database role can only INSERT into, a separate audit service, or a write-once object store. Keep it separate from application data, so an attacker who changes a ticket cannot also change its history.
Make Tampering Visible: a Hash Chain
Append-only rules can be bypassed by someone with database admin rights. A hash chain makes any change visible: each event stores the hash of the previous event, and its own hash covers that link.
Change entry 5 and its hash no longer matches. Every later entry points at the old hash, so the break is visible from that point on.
The lab uses real SHA-256. The idea is the same.
Someone with full access could rebuild the whole chain after editing it. Stop that by regularly writing the latest hash somewhere they cannot rewrite: a write-once (WORM) storage bucket, a separate account, or a signed daily digest sent to the customer.
Answer "Who Changed This?"
Audit questions are almost always "everything that happened to this target" or "everything this person did", inside one tenant and a time range. Index for exactly those: (tenant, target, time) and (tenant, actor, time).
Notice the filter on tenant: t50 also has a ticket 42, and its history must never appear in t41's answer.
Retention per Tenant
Each tenant's contract or regulator sets how long its events must be kept, and often how soon they must be deleted. One global setting cannot satisfy them all.
Try It: An Audit Trail You Can Trust
- Leave the chain off and simulate the insider. Can you tell that entry 5 changed?
- Turn the hash chain on. Where does verification fail?
- Answer the five audit questions with the filter.
- Pick a purge rule that keeps every tenant's events exactly as long as its contract says.
Pass rule: tampering detected, 5 of 5 questions right, and no event purged early or kept too long.
Many enterprise customers also want their audit events exported into their own security tools (a SIEM), as a stream or a daily file. Plan an export per tenant from the start; it is the same event, sent somewhere else.
Check Yourself
Common mistakes
| Mistake | Wrong | Correct | Why it happens |
|---|---|---|---|
| Audit table next to the data | Same database, same admin role | Separate, insert-only store | It is the quickest place to write |
| No before/after | "ticket 42 updated" | priority: high → low | Values seem redundant when you write the log |
| Secrets in events | Tokens and full request bodies logged | Only what the question needs | Logging the whole request is easy |
| Global retention | Everything deleted after 90 days | Each tenant's contract | One setting is simpler |
| Unanchored chain | Hashes stored only in the same table | Latest hash copied to write-once storage | A full-access attacker can rebuild the chain |
Practice
What to Remember
- Record who, what, when, from where, and before → after.
- Keep audit events append-only and separate from the data they describe.
- Hash-chain them, and anchor the latest hash where nobody can rewrite it.
- Apply retention per tenant.
Further Reading
- OWASP: Logging Cheat Sheet: what to record, and what never to record.
- NIST SP 800-92: Guide to Computer Security Log Management: protecting and retaining logs.
- Crosby and Wallach: Efficient data structures for tamper-evident logging: hash chains and trees for audit logs.
Next: Workflow and Automation Engines. Customers want "when a ticket is urgent, page the on-call lead". You build the engine, and stop the rule that triggers itself forever.