Audit trails for actions and decisions

An audit trail records who attempted an action, the resource involved, the authority used and the result. Restrict access to the records and verify that retention and integrity controls work as intended.

2 min read

Denied invoice approval

Example audit record · audit_7041

Actor
user_82
Requested action
invoice.approve
Resource
inv_1042
Policy evaluated
policy_12
Outcome
Denied: approval limit

Required event fields

Include event and collection timestamps, the original actor when a service acts on their behalf, and checks for collection integrity.

Define the questions the trail must answer

Operational logs help diagnose software behavior; audit records explain attributable actions and decisions. They may share correlation identifiers but have different access, retention, and integrity requirements. Decide which actions require audit evidence, including denied access, policy changes, exports, credential changes, and privileged support operations.

For an invoice approval, record the actor, tenant, resource identifier, requested action, policy outcome, relevant version, timestamp, and resulting status. Capture the original actor as well as a service acting on their behalf where delegation is involved. Avoid replacing all background activity with one indistinguishable system identity.

Record structured events with safe context

Use a stable event schema and distinguish event time from collection time when buffering can delay ingestion. Include an operation or trace reference so an investigator can connect an audit event to related execution evidence. The reference should not require exposing a complete request payload in the audit store.

Do not log passwords, access tokens, session secrets, or unrestricted personal data. Resource identifiers, source addresses, and query parameters may still be sensitive, so classify them deliberately. Sanitize untrusted values and use structured encoding to prevent a crafted field from corrupting log interpretation or impersonating another event.

json
{
  "eventId": "audit_7041",
  "tenantId": "tenant_acme",
  "actorId": "user_82",
  "action": "invoice.approve",
  "resourceId": "inv_1042",
  "outcome": "denied",
  "reasonCode": "approval_limit",
  "policyVersion": "policy_12"
}

Example audit fields for actor, action, resource and outcome. Include event and collection timestamps in the full record, with access and integrity controls for storage.

Protect the trail from the systems it records

Restrict who can write, read, modify, and delete audit records. Separate application credentials from administrative retention controls where practical. Central collection and immutable storage options can improve resistance to alteration, but no storage setting alone proves an entire evidence chain is trustworthy.

If using signed batches, hash chains, or external checkpoints, document key management, verification, gap detection, and the threat model. A chain stored with fully compromised application keys has limits. Test clock synchronization, collector outages, and storage failures so missing audit evidence is detectable and does not remain a silent side effect.

Operate retrieval, retention, and review

Select retention periods with the relevant business, security, and legal owners instead of adopting an arbitrary number. Plan how records are located, exported under authorization, and eventually deleted or preserved under an applicable hold. Search access should itself be controlled when the trail reveals sensitive activity.

Run an investigation exercise using a known operation. Confirm that actors can be attributed, related events can be correlated, and denied actions are visible. Measure collection gaps and delivery delay. An audit system is useful only when an authorized reviewer can retrieve credible evidence within the operational time available.