Skip to main content

Audit Logging

OSAPI records a structured audit trail of every API request. Audit entries capture who made the request, what they did, and how long it took. This provides accountability and supports compliance requirements.

How It Works

The API server records audit entries automatically via middleware. Every authenticated request generates an audit entry that is stored in a dedicated NATS JetStream stream. No application code needs to explicitly log audit events -- the middleware handles it transparently.

Each audit entry contains:

FieldDescription
idUnique entry identifier (UUID)
timestampWhen the request was made
userIdentity from the JWT sub claim
rolesRoles from the JWT token
methodHTTP method (GET, POST, etc.)
pathRequest path (e.g., /node/hostname)
operation_idOpenAPI operation ID (if available)
source_ipClient IP address
response_codeHTTP response status code
duration_msRequest processing time in milliseconds
trace_idOpenTelemetry trace ID (when tracing is enabled)

Viewing Audit Logs

Query audit entries through the API or CLI. You can list recent entries (paginated), get a specific entry by ID, or export all entries. See CLI Reference for usage and examples, or the API Reference for the REST endpoints.

Export

The export feature retrieves all audit entries and writes them to a local file in JSONL format (one JSON object per line). This is designed for long-term retention -- since audit entries in the NATS stream have a configurable max_age (default 30 days), exporting preserves them before they expire.

The export endpoint returns all entries in a single response. The CLI writes each entry as a JSON line to the output file. JSONL files are easy to process with standard tools:

# Count entries
wc -l audit.jsonl

# Filter by user
grep '"user":"ops@example.com"' audit.jsonl

# Pretty-print with jq
cat audit.jsonl | jq .

Retention

Audit entries are stored in a NATS JetStream stream with configurable retention settings. When entries exceed the max_age or the stream reaches its size limit, older entries are automatically removed. Export entries before they expire if you need long-term retention.

Configuration

nats:
audit:
stream: 'AUDIT' # JetStream stream name
subject: 'audit' # Base subject prefix
max_age: '720h' # 30-day retention (default)
max_bytes: 52428800 # 50 MiB max stream size
storage: 'file' # "file" or "memory"
replicas: 1 # Number of stream replicas

Each audit entry includes a trace_id field when distributed tracing is enabled, allowing correlation with OpenTelemetry traces.

See Configuration for the full reference.

Permissions

All audit endpoints require the audit:read permission. Only the admin role includes this permission by default.