Audit Logs for Small SaaS: Know Who Did What (Before Someone Asks) | Deployxa

When a customer asks who deleted their API key, "we don't know" is an expensive answer. Build a minimum viable audit log: what to record first, how to keep it honest, and how it pays you back.

← Back to Dispatch Articles
Engineering Log

Audit Logs for Small SaaS: Know Who Did What (Before Someone Asks)

When a customer asks who deleted their API key, "we don't know" is an expensive answer. Build a minimum viable audit log: what to record first, how to keep it honest, and how it pays you back.

Two questions land in small SaaS support inboxes more often than founders expect. The first comes from a customer's admin: "Can you confirm who deleted our API key? Our integration stopped working Friday and we need to know." The second comes from inside your own product: a teammate was tidying up the plan settings and changed a price by accident — and two days later, when a customer asks when the change happened and who made it, nobody can say. The database holds the current price and nothing else; the logs hold a stack trace; your teammates shrug. And then you hear yourself give the real answer: "We don't know." That answer is expensive. A customer who hears "we don't know" about their own account does not conclude that one key got deleted; they conclude that nobody is keeping track — and that conclusion spreads.

Key Facts

  • What an Audit Log Is (and Why It Is Not Your Application Logs): You already have logs — request logs, error logs, background-job logs — and that is exactly why the distinction confuses people.

  • The Minimum Viable Audit Event: An audit event is one line with six fields; everything fancier is optional.

  • The First Events Worth Capturing, In Order: You cannot record everything, and you should not try.

  • Audit Log Best Practices SaaS Teams Can Actually Keep: Most audit log projects die from ambition, not neglect: someone sketches an event-sourcing system with a streaming pipeline, realizes it will take a month, and ships nothing.

The uncomfortable reason this keeps happening is that your product grew. Teammates, contractors, customer admins, API clients — all of them can now take consequential actions inside your product, and nothing remembers any of it. Databases store the present tense: they overwrite, and the current state is the only state that survives. So the moment anyone asks about the past — who, when, from where — you have opinions and guesses where a record should be.

An audit log fixes this, and it is smaller to build than it sounds. This guide covers audit log best practices SaaS teams can actually keep without a security engineer: what an audit log is (and is not), the one-line event format that carries most of the value, the first events worth capturing in order, implementation patterns that stay small, retention and tamper-evidence basics, and the honest version of how it pays you back — plus a walkthrough of the afternoon it turns from a crisis into a five-minute lookup.

What an Audit Log Is (and Why It Is Not Your Application Logs)

You already have logs — request logs, error logs, background-job logs — and that is exactly why the distinction confuses people. The two kinds record different things for different readers.

Application logs are for the system: a request came in, a query ran slow, a worker crashed. They exist so you can debug, and most of what they contain is noise you discard after a few weeks.

An audit log is for accountability. It records consequential actions taken by people and API clients inside your product: who did what to which thing, when, from where. It exists so that months later you can answer a question about the past with evidence instead of a shrug.

Three properties make something an audit log rather than just more logging:

  • Written when the action happens, by the code that performs it. Not reconstructed afterward from request logs, not batched for later.
  • Append-only. Entries are never edited or deleted; a record an insider can quietly rewrite is not a record.
  • About actions on objects, not system chatter. One consequential action, one line. Page views and server heartbeats do not belong.

If you remember nothing else from this section: your application logs answer "what is the system doing?" Your audit log answers "who did that?"

The Minimum Viable Audit Event

An audit event is one line with six fields; everything fancier is optional. The examples below are fictional.

Field

Fictional example

What it captures

Actor

user_8412 (admin, Brightloop workspace)

Who performed it — a stable user ID, not a changeable display name

Action

api_key.revoked

What they did, as a filterable verb phrase

Object

api_key ...4k2m (integration: Billing sync)

Which thing it happened to — a type and ID, not the full contents

Timestamp

2026-09-14 16:42:11 UTC

When — server clock, UTC, to the second

Source

IP 203.0.113.24, session s_5517

Where it came from — an IP address or a session hint

Outcome

success

Whether it worked; failed and denied attempts are events too

Stored as one row, the same event might look like this (fictional, illustrative):

{ "actor": "user_8412", "action": "api_key.revoked", "object": "api_key:...4k2m (workspace: brightloop)", "time": "2026-09-14T16:42:11Z", "source_ip": "203.0.113.24", "outcome": "success"}

Notice what is already enough: no browser, city, or screenshot. Six fields answer essentially every question you will be asked — who, what, to which thing, when, from where, did it work. A field serving none of the six is decoration; cut it before it becomes a privacy problem.

The First Events Worth Capturing, In Order

You cannot record everything, and you should not try. Start with the events that answer the questions people actually ask, in roughly this order:

Event group

Why it matters

Example question it answers

Logins and failed logins

Establishes who was acting and when; failed attempts surface credential guessing early

"Who was in the account on Friday night?"

Password and token changes

Credential changes are how accounts change hands — welcome and unwelcome

"Who reset the credentials right before this happened?"

Invites, role changes, removals

Permissions decide who can do damage, so changes to them explain everything afterward

"Who gave the contractor admin access?"

Deletes, exports, API key creation and revocation

The destructive and data-leaving paths: content disappearing, content copied out, new doors created

"Who deleted our API key?"

Plan and billing changes

Money disputes need timestamps more than apologies

"When did this account's plan change — and by whom?"

Settings changes

The quiet cause of mysterious behavior changes

"What changed right before integrations broke?"

The order is deliberate. Auth events come first because every other record depends on knowing who was acting; without logins, the rest of the log has unattributed lines. Permission changes come next because they explain how an actor got the ability to do the thing you are being asked about — half of "who deleted it" is "who could have." Destructive actions and exports are the ones customers ask about by name. Billing and settings round it out; less dramatic, but they turn "the app is behaving weirdly" conversations into short ones.

Two notes before you build: record the outcome for auth events too — a failed login is a security signal, and a failed delete is a story. And do not give all events the same retention clock: failed-login noise can live shorter than permission and billing changes, which you will want years from now.

Audit Log Best Practices SaaS Teams Can Actually Keep

Most audit log projects die from ambition, not neglect: someone sketches an event-sourcing system with a streaming pipeline, realizes it will take a month, and ships nothing. The patterns below are the boring version that ships.

Keep it one append-only table

A single audit events table — or one dedicated append-only channel in the structured logging you already run — is enough for years of a small SaaS's life. In a database, the columns are the six fields plus an ID and a workspace reference; index by tenant and time so the admin view is one fast query. A log channel keeps audit lines out of your database, which is tidier, but filtering and joining gets harder, and the lines inherit your log system's retention and rotation. For most small teams the table wins: it backs up with your database, exports with one query, and needs nothing new in your stack. Resist the upgrade temptations — no event bus, no stream processor, no event sourcing. Even the admin interface can wait: a saved SQL query you can run in a minute is fine for year one.

Write the event in the same transaction as the action

Commit the audit event together with the change it describes, in the same database transaction: if the action succeeded, the record exists; if the record exists, the action happened. When the action spans systems — you call a payment provider, then update your own database — write the event immediately after the action completes and include the outcome. A denied attempt is a legitimate audit event, often the most interesting line in the table. The one pattern to avoid is queuing audit writes for later "to keep the request path fast": if the process crashes between the action and the log write, the gap is exactly the window you will someday be asked about.

Never log the secret itself

Design against the obvious irony: the log built to prove trustworthiness becomes the liability. Never store full API keys, tokens, or passwords in audit events — and never a failed-login password, because people regularly type their password into the username box. Store the credential's ID and last four characters instead. Same discipline for customer data: for a delete event, log the record type and ID, not the contents. Redact at write time, because "we will clean the log up later" never happens.

Reconstruct, don't surveil

There is a privacy line, and it is easy to state: include enough context to reconstruct what happened to an object, not enough to monitor a person. Consequential actions, not presence — page views, keystroke captures, and "who read which row" telemetry are a different product your customers did not agree to. Two practical notes: IP addresses are treated as personal data under many privacy regimes, so apply your retention rules to them instead of hoarding them; and privacy obligations vary by jurisdiction and by what you collect — this is engineering guidance, not legal advice, so check what applies to you before deciding what to log and how long to keep it.

Retention and Tamper-Evidence: Keeping the Record Honest

An audit log you cannot trust is a diary with a delete button. Three basics keep it honest.

Keep audit events longer than application logs. Application logs are debugging data — a few weeks of retention is healthy. Audit events are the record people will rely on next year, so think in years, and write the period down as an actual policy, even if it is one line in your README. Expectations vary by industry and jurisdiction, so pick the number deliberately. High-volume, low-value events like failed logins can run on a shorter clock than permission and billing changes.

Restrict who can edit or delete them. The value of the log collapses if an admin can quietly edit it — or if one compromised admin account can. In practice: the application only ever inserts and reads; no edit or delete UI exists anywhere; and at the database level, revoke UPDATE and DELETE on the audit table from the application's database user so even an app bug or injection cannot rewrite history.

Export periodically. A nightly or weekly export of new audit events to storage outside your primary database gives you a copy that survives both disaster and insider mistakes, and something concrete to hand a customer or reviewer who asks pointed questions. For a cheap tamper-evidence upgrade later, daily hash chains — each export's hash includes the previous day's — make silent tampering detectable; that can wait.

How Audit Logs Pay You Back

Three returns, in increasing order of strategic value.

Support disputes end in minutes instead of days. "Who changed X?" goes from an afternoon of database archaeology to a filtered query. And disputes you can answer with evidence are usually the ones that end: a customer shown exactly what happened, with timestamps, tends to stop escalating.

Incident forensics stops being guesswork. When a credential leaks or an account behaves strangely, your audit trail tells you what the actor touched — which keys were created, which records were exported, which settings changed. That defines the response — what to rotate, what to restore, who to notify; without it, the safe move is assuming the worst about everything.

Enterprise buyers ask about audit trails in security reviews. If you sell to companies with security teams, "do you keep audit logs of administrative and customer-data actions?" is a standard questionnaire line, and "we don't" is an answer that lives in the reviewer's notes. The weight cuts both ways: having a competent audit trail is table stakes for B2B deals — its absence can quietly cost you one, and its presence rarely wins one by itself. It is one checkbox among many, not a moat. And the other direction, equally honest: an audit log is not a compliance certification. It does not make you SOC 2 or GDPR-anything or "secure" — it makes you answerable, the part customers can actually verify.

A Walkthrough: The Missing Report (Illustrative)

A fictional example to make it concrete; any resemblance to your Tuesday is the point.

A three-person project-management SaaS works with one contractor. Monday, 9:15 a.m.: a customer writes that the quarterly report they generated Friday is gone from their workspace. It is indeed missing — and the follow-up makes it worse: "Was our data removed?"

Without an audit trail, the next three hours are improv: check whether the report even falls inside a backup window, ask everyone — including the contractor, politely, twice — and eventually restore something and hope it is the right version, with no way to tell the customer what happened.

With an audit trail, the same morning looks different. Filter the workspace's events for Friday: 16:42 — a teammate exported the report, outcome success; 16:47 — the same teammate deleted the report. Five minutes in, the team knows the story: while cleaning up "test" items, the teammate mistook the customer's report for a duplicate and deleted it after downloading a copy. They restore the report from Friday's backup, tell the customer exactly what happened, and ship a small fix: a confirmation dialog for deleting reports in shared workspaces. Total cost: under an hour, most of it spent on the fix. The log did not just answer "who did what"; it converted a blame exercise into a correction.

Where Your Platform Ends and Your Code Begins

Be clear about the division of labor, because buyers and reviewers will be.

The audit trail described in this article lives in your application and records your users' in-app actions — logins, role changes, deletes, exports. That is application code, and no deployment platform can write it for you. If you deploy on Deployxa, the platform does not record your users' in-app actions — that layer is yours.

The platform side gives you its own record of the infrastructure around your code. Per-deployment logs are available from the Deployxa dashboard, so the deploy layer's questions — when each release shipped and how it behaved — have their own answer: yours covers what people did in the product; the deployment record covers what changed around the code. Credentials are the other platform-side piece: Deployxa manages environment variables per deployment, keeping credentials scoped to where they are used — so when your audit trail shows a key was created or leaked, rotating the platform-side variables is a contained operation rather than a hunt. And because deploys are health-gated — a new release goes to a standby slot and takes traffic only after passing health checks — the set of changes that reach production stays deliberate and small. The docs cover how logs and environment variables work, and Deployxa's own platform security practices are described on the security page for the questions buyers ask about your vendor layer.

The honest limits, once more: your audit trail is your code's job, and nothing in this article is a compliance certification — not for you, not for any platform. Audit logs make you answerable; they do not make you compliant. Obligations depend on your business, your customers, and your jurisdictions.

The Audit Log Launch Checklist

Everything above, compressed. A small SaaS audit log is done when:

  • [ ] One append-only audit table exists; the application can only insert into and read from it
  • [ ] Every event carries actor, action, object, UTC timestamp, source, and outcome
  • [ ] Successful and failed logins are recorded
  • [ ] Credential changes (passwords, tokens, API keys) are recorded — without the secrets themselves
  • [ ] Invites, role changes, and member removals are recorded
  • [ ] Deletes, exports, and API key creation or revocation are recorded
  • [ ] Plan and settings changes are recorded
  • [ ] A written retention period exists, and it is longer than your application log retention
  • [ ] Events export periodically to storage outside your primary database
  • [ ] You can filter a workspace's events by person and time in under a minute

Ten lines, and the first four carry most of the weight. Everything after them is iteration.

Your Next Step: Ship the First Three Events

Here is the highest-priority checklist item, made specific for this week: create the append-only table and wire three events — successful and failed logins, role changes, and deletes. That is a day of work in most small codebases, it covers the three questions you are statistically most likely to be asked, and every later event becomes copy-paste work instead of a design decision. If you are tightening the platform side at the same time — deploy logs, scoped credentials, health-gated releases — Deployxa handles that layer so the time it recovers can go into your own audit trail. Six months from now, when someone asks who did what, the answer will be a query instead of a shrug — and that is what an audit log is for.

Ready to deploy with Deployxa?

Deploy your apps globally with automatic SSL and AI diagnostics.

Start Free Now