Arezgitfield notes / engineering
SecurityUPDATED AUG 18, 2026

Design Application Logs Without Leaking Sensitive Data

A secure logging workflow for selecting events, minimizing data, preventing injection, protecting transport and storage, controlling access, and testing failures.

AREZGIT / FIELD NOTESECURITY
Logs are often granted broader access and longer retention than the production data they accidentally copy. A request logger can capture authorization headers, reset tokens, database URLs, p
READ / VERIFY / APPLYTECHNICALLY REVIEWED

Logs are often granted broader access and longer retention than the production data they accidentally copy. A request logger can capture authorization headers, reset tokens, database URLs, personal records, or attacker-controlled line breaks while still appearing useful during development.

Secure logging begins before redaction. Decide which events operators need, define an allowlisted schema, minimize values at the source, and protect the complete pipeline from application memory to deletion.

Log security-relevant events, not entire objects

Start with decisions and state transitions that support detection, diagnosis, and accountability:

  • authentication success and failure categories;
  • authorization denial with protected resource type, not resource content;
  • account recovery initiation and completion;
  • administrative configuration changes;
  • input rejection categories;
  • dependency and job outcome classes;
  • security control activation or bypass;
  • release, migration, and data-reconciliation events.

For each event, name the consumer and action it enables. If nobody can state why a field is needed, omit it. Logging every request body “for debugging” turns the log store into an uncontrolled replica of application data.

The OWASP Logging Cheat Sheet distinguishes application logging from infrastructure logging and recommends consistent event information while excluding data that should not be recorded directly.

Define an allowlisted event schema

Use structured fields with documented types and size limits. A useful event can contain timestamp, event name, outcome, service and release identity, bounded reason code, correlation identifier, and a pseudonymous actor or tenant reference when justified.

Do not record directly:

  • passwords, session identifiers, access or refresh tokens;
  • authorization headers, cookies, private keys, or connection strings;
  • payment card or bank data;
  • sensitive personal or health information without an approved necessity;
  • raw database rows or request and response bodies;
  • secrets embedded in URLs or command arguments;
  • source code or files merely because an exception referenced them.

Hashing an identifier is not automatically anonymization. Stable unsalted hashes can be linked across events or guessed from a small input space. Use a purpose-specific pseudonymous identifier with key management and deletion behavior when correlation is necessary.

Sanitize at the emission boundary

Redaction at the dashboard is too late because sensitive values have already crossed transport, storage, indexing, and backup boundaries. Apply an allowlist or typed event constructor inside the application before handing data to the logging library.

Treat exception messages as untrusted. Libraries and dependencies may include URLs, SQL fragments, local paths, or input values. Map known failures to stable reason codes and store a sanitized message. Bound unknown messages and route detailed diagnostics to a more restricted channel only when policy permits.

Prevent log injection by encoding line breaks and control characters or by using a serializer that produces valid structured records. An attacker-controlled username containing a newline must not create a fake event. Validate field names as well as values when dynamic attributes are allowed.

Redaction patterns can miss new secret formats and can over-redact useful text. Test them as a secondary safeguard, not the primary design.

Preserve trustworthy context

Use a correlation identifier that is random, non-secret, and independent of user input. Propagate it across services with bounded validation. Do not use an access token or sequential database key as a trace identifier.

Record authoritative server-side identity after authentication rather than trusting an account ID supplied in the request body. Distinguish the actor, subject, and service when an administrator or worker acts on another resource.

Synchronize clocks and record timezone explicitly, but expect some clock skew across systems. For sequences where order is critical, include transaction or event-stream positions in addition to timestamps.

Logs support investigation; they are not automatically an immutable audit trail. If audit integrity matters, define append controls, access separation, retention, export, and tamper detection under a specific threat model.

Protect transport, storage, and access

Encrypt log transport and authenticate collectors. Buffer safely during transient outages without blocking the application indefinitely or writing sensitive emergency files to an uncontrolled directory.

At rest, apply access control by role, environment, and data classification. Production logs should not be visible to every developer by default. Record access to sensitive log datasets and review export permissions.

Set retention from operational and legal needs, then delete data across primary storage, indexes, archives, and backups according to policy. Longer retention increases investigation history and exposure at the same time. Do not claim deletion guarantees that the backup architecture cannot meet.

Separate development verbosity from production. Debug mode should not silently change the data classification of emitted events.

Fail without losing the application boundary

A logging outage should not normally take down the user request path. Use bounded queues, timeouts, backpressure, and a documented drop strategy. Security-critical audit events may require a stricter failure policy, but the consequence must be designed explicitly rather than emerging from a full disk.

Monitor dropped events, serialization failures, collector rejection, queue saturation, clock drift, and redaction activation. Avoid recursive logging when the logger itself fails.

Local emergency buffers need restrictive permissions, size limits, rotation, encryption where required, and cleanup. Never fall back to printing complete objects to standard output.

Test for disclosure and operational value

Create synthetic canary values that resemble protected categories without being real credentials or personal data. Exercise authentication failure, validation errors, dependency exceptions, oversized input, multiline attacker input, retries, and logger outage. Search every resulting sink and artifact for the canaries.

Also test the positive requirement: can an authorized operator reconstruct the event category, affected service, release, and recovery path without the omitted sensitive value? Security that removes all diagnostic value will be bypassed during an incident.

A logging design is successful when events support defined operational decisions, sensitive data is excluded before emission, the pipeline has bounded failure behavior, and access and retention match the data that remains.

READER SIGNAL

Was this guide useful?

Your rating helps us prioritize clearer, more practical technical content.

AREZGIT / DESKTOP WORKSPACEFROM FIELD NOTE TO RELEASE

Review diffs, run checks, and prepare the release in Arezgit.

Keep Git review, security scanning, API checks, database inspection, and release preparation together in one local desktop application.

Explore Arezgit