Security & operations

Audit Logging Without Exposing Sensitive Data

Choose meaningful audit events, exclude secrets, protect log integrity, and test what happens when logging fails.

Start with the question the audit trail must answer

An audit trail should help explain who performed a consequential action, what resource was involved, when it happened, and whether it succeeded. Copying every request body into a log can expose private information while still failing to explain the business event.

For an employee-record application, useful events might include a permission change, an approved request, or a bulk export. Decide which events matter with the people responsible for investigating incidents and handling the data.

Capture the event, not the whole payload

Use structured fields such as event type, timestamp, actor identifier, resource identifier, outcome, and correlation ID. Take identity information from the authenticated server context. Use consistent event names so investigators can follow an action across services.

For a permission change, record the affected account and the permitted role transition when appropriate. Do not automatically copy the entire account record. Identifiers may themselves be personal data, so include only what the investigation requires.

Keep secrets and unnecessary personal data out

Exclude passwords, access tokens, session cookies, private keys, and connection strings. Avoid logging complete personnel records, health details, or payment information. Use an allowlist of fields rather than relying on a growing list of strings to redact after collection.

OWASP's Logging Cheat Sheet discusses event selection, exclusions, and log protection. Its guidance also covers untrusted event data: limit field sizes and prevent line breaks or delimiters from forging additional entries.

Protect the trail and define retention

Restrict who can read logs and separate normal application writes from administrative deletion. Central collection with controlled retention can reduce the chance that an application compromise silently rewrites the evidence. Protect transport and storage according to the sensitivity of the events.

Define a retention period based on operational needs and applicable obligations, then enforce deletion. Indefinite retention increases exposure and storage costs. Audit access to the log system itself, especially exports and changes to retention settings.

Test failures as well as successful events

Check that events are emitted for successful actions, denied attempts, and failed changes, with outcomes that match the transaction result. A success event written before a failed database commit can mislead an investigation. For critical committed changes, consider transactional event storage and reliable delivery.

Exercise a full disk, an unavailable collector, and malformed input. Decide which operations must stop if audit evidence cannot be recorded, and alert on lost events. Avoid making an ordinary collector outage an accidental application-wide outage.

Finally, inspect real sample output in a safe environment. Search for credentials and private payloads, and confirm that one action can be followed using its correlation ID. Pair the trail with server-side API authorization; logs provide evidence, while access controls prevent unauthorized actions.

Jan Chester Peren

I build web apps, APIs, and internal systems with security in mind from the start.

All articles · Explore my work