Security logging is not simply collecting more application output. Its purpose is to leave reliable evidence of security-relevant activity so that suspicious behaviour can be detected, investigated, and explained.

Useful logs answer practical questions: what happened, when did it happen, which identity or client was involved, what resource was affected, and what was the result?

Log security decisions, not every detail

Start with events that represent changes in identity, authority, access, or security state.

Common examples include:

  • successful and failed authentication attempts;
  • password, email, or multi-factor authentication changes;
  • session creation, revocation, and suspicious reuse;
  • authorization failures;
  • administrative actions;
  • privilege or role changes;
  • secret and key lifecycle operations;
  • security configuration changes;
  • rate-limit or abuse-control triggers;
  • access to especially sensitive resources;
  • important validation or integrity failures.

A debug message such as request failed is rarely enough. A security event should describe the decision that matters.

Avoid logging every successful read merely because it is possible. High-volume, low-value events increase storage costs and can hide meaningful signals.

Give events a consistent structure

Structured logs are easier to search and correlate than free-form sentences.

A security event might contain fields such as:

timestamp = 2026-09-02T15:42:18Z
event_type = authorization_failure
actor_id = user_4821
resource_type = billing_account
resource_id = acct_173
source_ip = 203.0.113.24
request_id = req_8f12c
result = denied
reason = insufficient_role

Use stable event names and field meanings. If one service records login_failed, another records bad_login, and a third embeds the same event inside a sentence, detection rules become unnecessarily difficult to maintain.

Prefer identifiers that let investigators correlate activity without requiring sensitive values to appear directly in the log.

Record both actor and target

An event often needs two kinds of identity: who performed the action and what the action affected.

For an administrative role change, record the administrator as the actor and the modified account as the target. For an API authorization failure, record the authenticated principal and the requested resource.

This distinction makes questions such as “who changed this account?” and “which accounts did this administrator modify?” straightforward to answer.

Anonymous activity still needs context. A source address, client identifier, request ID, or other appropriate request metadata can help correlate repeated attempts.

Preserve request correlation

Security incidents rarely appear as one isolated log entry. Investigators often need to connect activity across an edge proxy, application, identity service, job queue, and database-facing service.

Generate or accept a request or trace identifier at a trusted boundary and propagate it through relevant components.

Do not treat a client-supplied correlation value as inherently trustworthy. If clients can choose the value, validate its format and distinguish it from an internally generated identifier where that distinction matters.

Correlation makes a sequence of individually ordinary events much easier to reconstruct.

Never turn logs into a secret store

Logs frequently have broad operational access and long retention periods. Treat them as a separate data store with their own exposure risk.

Do not record values such as:

  • passwords;
  • session tokens;
  • password-reset tokens;
  • API keys;
  • private keys;
  • authorization headers containing credentials;
  • complete payment-card data;
  • unnecessary personal or confidential request bodies.

Redaction should happen before sensitive data reaches the logging pipeline. Removing secrets later is less reliable because copies may already exist in buffers, collectors, archives, or backups.

Be careful with generic request logging. Headers, query strings, form fields, and exception objects can contain credentials even when the application did not explicitly add them to a security event.

Distinguish failures from attacks

A single authentication failure is normal. Hundreds of failures against many accounts from one source may deserve attention. Repeated authorization failures followed by a successful privileged action may be more important than either event alone.

Detection therefore depends on context and aggregation, not only individual log severity.

Useful detection questions include:

Are failures increasing rapidly for one account?
Is one client attempting many accounts?
Did a privilege change occur outside the normal workflow?
Was a sensitive action performed soon after account recovery?
Did an administrator act from a new or unusual context?

Thresholds should reflect the application and its normal traffic. A fixed number that works for a small internal service may be meaningless for a large public endpoint.

Log outcomes explicitly

Do not force an investigator to infer whether an operation succeeded from the absence of an exception.

Record an explicit result such as success, denied, failed, or cancelled, together with a reason code when useful.

Keep reason codes safe for operational use. An internal log may distinguish account_disabled from invalid_credential, while the public authentication response intentionally avoids revealing that distinction.

This lets internal detection retain useful context without creating an account-enumeration signal for an attacker.

Protect log integrity and availability

Security logs are valuable to attackers because deleting or altering them can hide activity.

Limit who and what can write, modify, and delete security records. Application identities generally need permission to append events, not to rewrite historical records.

Where risk justifies it, send important events to a separate logging system so compromise of one application host does not automatically provide control over its historical evidence.

Retention should be long enough for realistic detection and investigation needs, while still respecting privacy, legal, and storage requirements.

Reliable time is also important. Synchronize system clocks and use timestamps with an explicit time zone, commonly UTC, so events from different systems can be ordered correctly.

Design for monitoring from the beginning

A log becomes operationally useful when someone can act on it.

For each high-value event, decide:

  1. what normal behaviour looks like;
  2. what suspicious pattern should be detected;
  3. which fields are required to evaluate that pattern;
  4. who receives the alert;
  5. what evidence they need to investigate it.

This approach is better than emitting arbitrary fields first and hoping useful alerts can be built later.

For example, detecting repeated access denials across many resources may require an actor identifier, resource identifier, timestamp, result, and request context. If those fields are inconsistent or missing, the detection will be weak regardless of the monitoring product.

Test the logging path

Security logging should be tested like other security controls.

Create test cases that trigger important events and verify that:

  • the expected event is emitted;
  • required fields are present;
  • secrets are absent;
  • timestamps and identifiers are valid;
  • correlation works across relevant services;
  • alerts fire for representative suspicious patterns;
  • logging failures do not silently bypass critical evidence collection.

Also decide how the application behaves when the logging destination is unavailable. Blocking every request may create an availability failure, while silently discarding all events removes evidence. Buffering, backpressure, local fallback, or fail-closed behaviour for a small set of critical operations are trade-offs that should be chosen deliberately.

Keep the event model maintainable

Security events evolve as systems change. Document event names and important fields, and treat incompatible schema changes carefully.

A practical event model usually works best when it is small enough for developers to understand but structured enough for monitoring rules to depend on.

The goal is not maximum log volume. The goal is trustworthy, searchable evidence that makes important security behaviour visible without exposing the secrets the system is supposed to protect.