Audit logging records who did what, when, and to which resource, so you can investigate incidents, prove compliance, and satisfy enterprise customers. I build this into SaaS products as a core feature, not an afterthought. The event vocabulary comes from OWASP, the storage and retention guidance from NIST, and the implementation patterns from the SaaS MVPs I build and rescue.
Key Takeaways
Effective audit logging captures security-relevant events with a consistent schema, supporting compliance, incident response, and trustworthy data integrity.
| Point | Details |
|---|---|
| Prioritize key events | Log authentication, authorization, and admin actions first, as these are most critical for compliance and security. |
| Use a standard schema | Maintain consistent core fields like event_id, timestamp, actor_id, target_id, and outcome for cross-service queryability. |
| Protect sensitive data | Redact secrets and minimize personal data in logs to prevent information leaks and meet privacy requirements. |
| Build in fixed scope | Integrate audit logging from the start of product development, including schema, export, and documentation. |
| Reference Hanad Kubat approach | Follow Hanad Kubat's method of building and delivering audit logs within a clear scope to ensure readiness and compliance. |
Table of Contents
- What makes an audit trail different from a regular log
- Which events to capture first
- A schema that holds up across services
- Architecture choices that keep the trail trustworthy
- Retention, privacy, and what to keep out of the log
- Best practices and the mistakes that make trails useless
- How I build this into fixed-scope engagements
- When minimal logging stops being enough
- Getting audit-ready logging built and handed over
- FAQ
- Sources
What makes an audit trail different from a regular log
An audit trail is a sequential, attributable record of security-relevant events: who acted, what they touched, and the outcome. It answers a specific question months later: did this person have the right to do that, and what happened as a result.
Regular system or observability logs answer a different question. They tell an engineer why a request was slow or why a service crashed at 3 a.m. The consumers differ too.
- Audit logs are read by security teams, auditors, and compliance officers, usually after the fact.
- System logs are read by engineers and SREs, usually in real time, to fix something that is breaking now.
- Audit entries need to stay human-readable years later; debug logs can be noisy and short-lived.
Enterprise customers increasingly ask for the first kind as a contract condition, not a nice-to-have, because their own auditors need a readable trail they can hand upward.
Which events to capture first
Not every action deserves a log entry, and logging everything creates noise that buries the events that matter. I prioritize in this order when building audit logging into a new SaaS product:
- Authentication events: login success and failure, MFA enrollment or removal, token issuance and revocation.
- Authorization changes: role or permission grants and revocations, and every access-denied event.
- Administrative and config actions: API key creation, plan or billing changes, user invitations, tenant settings.
- Data access on sensitive records: reads, exports, creates, updates, and deletes on anything regulated or customer-identifying.
- Security detections: injection attempts, rate-limit abuse, and session anomalies such as impossible travel or token reuse.
OWASP's logging guidance names authentication, authorization changes, sensitive data access, and administrative actions as the events that matter most, and recommends a standard event vocabulary so monitoring tools can alert on patterns instead of parsing free text. That consistency is what turns a pile of log lines into something an incident responder can query in minutes instead of hours.
These five categories cover most incident response needs and most SOC 2 or ISO 27001 evidence requests. A support ticket asking "who changed this customer's billing plan last Tuesday" is only answerable if admin actions were logged with an actor and a timestamp from day one. Skipping this category because it feels low-risk is one of the more common gaps I find when rescuing an existing product.
A schema that holds up across services
A consistent event schema is what makes audit logs queryable instead of just stored. Every event I log carries the same core fields, regardless of which service emitted it.
event_id: a unique identifier for the entry itself.timestamp: UTC, ISO 8601 format, never local time.event_type: a standardized name likeauthn_login_successorauthz_role_change.actor_idandactor_type: the user, service account, or API key that performed the action.target_idandtarget_type: the resource affected.actionandoutcome: what was attempted and whether it succeeded.request metadata: source IP and user agent, useful for anomaly detection.
Optional fields add context without bloating every row: request_id, session_id, correlation_id, tenant_id, and a short payload summary that never includes raw PII.
OWASP's logging vocabulary lists prefixes like authn_, authz_, malicious_, and sensitive_ specifically so teams across services land on the same names instead of inventing their own. It also warns explicitly against logging secrets and against including more personal data than the event needs.
Pro Tip: Mask tokens, passwords, and full card numbers at the point of logging, not later in a cleanup job. By the time someone remembers to redact, the secret has already been written to disk.

Architecture choices that keep the trail trustworthy
Application-level events matter even when infrastructure logs already exist, because infrastructure logs rarely know who the user was or what business action they took. A load balancer log shows a request; it does not show that a billing admin downgraded a tenant's plan.
NIST SP 800-92 recommends centralized log collection with routine review and protected storage, and that pattern holds for SaaS audit trails too.
- Emit structured JSON events from the application, not formatted strings meant for a terminal.
- Ship events over a reliable transport to a central collector, then into a time-series or object store that supports fast range queries.
- Feed the same stream into a SIEM or analytics layer for alerting, without duplicating the logging code in every service.
- Write audit entries append-only, and add a hash or signature chain so a tampered or deleted row is detectable.
- Restrict write access to the logging pipeline itself; nobody with application access should be able to edit a past entry.
For enterprise customers, build an admin-facing view and an export API early. A security team evaluating your product during procurement will ask to see their own tenant's audit trail before they sign, not after.
Retention, privacy, and what to keep out of the log
Retention length depends on four things: regulatory requirements, contractual promises to customers, how far back forensic investigations realistically need to reach, and storage cost at scale. Most SaaS teams land somewhere between 90 days of hot, queryable storage and one to seven years of cold archive, depending on the industry.
Protecting what you store matters as much as how long you keep it.
- Redact secrets and full payloads; log a reference or hash, not the raw value.
- Pseudonymize or hash user identifiers where the raw ID is not needed for the audit purpose.
- Minimize fields: log what the event needs, not everything the request object happens to contain.
A real-world gap shows what happens when this discipline slips: a logging feature in Directus allowed templates to output sensitive user data to the console before a fix landed in version 11.9.0. That is the exact failure mode redaction rules exist to prevent.
For SOC 2, PCI, or GDPR contexts, document your retention policy in writing, including what gets archived, what gets deleted, and on what schedule, since auditors ask for the policy itself, not just the logs. Privacy-by-design guidance on minimizing collected personal data applies directly to what fields belong in an audit event.
Best practices and the mistakes that make trails useless
Start narrow and expand deliberately rather than instrumenting everything at once.
- Instrument authentication, authorization, and admin events first, since these cover most compliance and incident questions.
- Add sensitive data access logging once the core categories are stable.
- Layer in security detection signals like injection attempts and rate-limit abuse last, since these need tuning to avoid false positives.
- Review logging coverage in code review, the same way you'd review test coverage.
- Add logging assertions to CI so a new endpoint touching sensitive data can't ship silently without an audit event.
The pitfalls I see most often: secrets logged in plaintext during debugging and never removed, event names that drift between services so nothing is queryable across the product, and payloads so large they make the audit store unsearchable within months.
Pro Tip: Run a quick checklist before calling audit logging "done": events instrumented for the five priority categories, schema validated against a fixed set of field names, ingestion centralized into one store, an export endpoint built, and a retention period written down.
How I build this into fixed-scope engagements
When I build or rescue a SaaS product, audit logging is part of the core build, not a phase tacked on at the end. My minimal baseline for a two to four week build covers authentication, authorization, and admin events from day one, since those are what enterprise buyers and auditors ask for first.
What I hand over at the end of a build:
- A documented event schema with the field names and types used across the codebase.
- A working export endpoint, so a customer's security team can pull their own tenant's trail.
- Sample queries for the most common investigation questions.
- A short runbook covering how to add a new event type without breaking the schema.
Full tamper-evidence chains and multi-year retention usually come after the first enterprise sale, since the storage cost and operational overhead aren't justified before that signal appears. I document that trade-off explicitly so it's a deliberate decision, not a gap nobody noticed.
When minimal logging stops being enough
A rough rule of thumb: log the five priority categories from day one, and treat anything beyond that as a response to a specific signal rather than a precaution. The signals that mean it's time to invest further are concrete: an enterprise buyer's security questionnaire asks for exportable audit trails, a regulator or contract requires a specific retention period, or you've already had an incident where the logs didn't answer the question you needed answered.
Building ahead of those signals usually means paying storage and engineering cost for a requirement nobody has asked for yet.
— Hanad Kubat
Getting audit-ready logging built and handed over
I build audit logging as part of a fixed-price engagement, not as a separate line item you have to negotiate for later. The event schema, the implementation across your authentication and admin flows, the export endpoint, and the handover documentation are all part of the same scope, delivered in two to four weeks.
You see working progress before paying anything, and you own the code from the first commit, the same way you'd own any other part of the build. There's no agency layer between you and the person writing the code, and no retainer required to get a working audit trail into your product.
If you're building a first version or rescuing a prototype that's outgrown its current logging (or lack of it), the services page outlines how the engagement works and what's included. Builds start from a moderate fixed price, and a fixed-price Prototype Audit is available first if you want a clear scope before committing to the full build.
FAQ
How long should SaaS companies retain audit logs?
Retention depends on your regulatory obligations, contractual promises, and forensic needs, and most SaaS teams keep 90 days of hot storage with longer cold archival after that. There's no single universal number, so the right period should be documented in a written retention policy rather than left implicit.
What's the difference between audit logs and system logs?
Audit logs are attributable security records read by auditors and security teams, answering who did what and when. System or observability logs are read by engineers in real time to debug performance or stability issues, and they're not designed to stay readable or complete years later.
How do you keep PII out of audit logs?
Redact secrets and full payloads at the point of logging, pseudonymize or hash identifiers where the raw value isn't needed, and log only the fields the event actually requires. OWASP's logging vocabulary explicitly calls out excluding secrets and minimizing personal data as part of the event design itself.
What events should a SaaS product log first?
Start with authentication events, authorization changes, and administrative actions, since these cover most incident response and compliance questions. Sensitive data access and security detection signals come next, once the core categories are stable and consistently named.
What does it cost to add audit logging to an existing SaaS product?
Pricing depends on scope. Exact scope and price are confirmed upfront before any work begins.
Sources
For teams that want the underlying standards rather than a summary, these are worth reading directly.
- Logging - OWASP Cheat Sheet Series
- Guide to Computer Security Log Management (NIST SP 800-92)
- NVD - CVE-2025-53885
