Tail and Query the Audit Stream
Every OPA evaluation — allow and deny — is recorded in the audit log. The caracal audit tail command streams live events from the database. The caracal explain command shows the full diagnostics for a single request ID: which policies determined the decision, what diagnostics were returned, and what the full input object looked like.
Prerequisites
Section titled “Prerequisites”CARACAL_ADMIN_TOKENset.- Events in the audit log (any token exchange generates at least one event).
Stream live events
Section titled “Stream live events”caracal audit tailDefault output is a human-readable table. Events appear in near real time as token exchanges complete.
Output as JSON
Section titled “Output as JSON”caracal audit tail --jsonEach line is a JSON object. Pipe to jq for field extraction:
caracal audit tail --json | jq '{id, decision, event_type, occurred_at}'Filter by decision
Section titled “Filter by decision”# Only denied exchangescaracal audit tail --decision deny
# Only allowed exchangescaracal audit tail --decision allowFilter by event type
Section titled “Filter by event type”# Only token exchange eventscaracal audit tail --event-type token_exchange
# Step-up related eventscaracal audit tail --event-type challenge_invalidcaracal audit tail --event-type challenge_cooldownFilter by zone
Section titled “Filter by zone”caracal audit tail --zone zone-abc123Filter by time range
Section titled “Filter by time range”# Events since a specific timestamp (ISO 8601)caracal audit tail --since 2026-05-11T08:00:00Z
# Events within a windowcaracal audit tail \ --since 2026-05-11T08:00:00Z \ --until 2026-05-11T09:00:00ZLimit output
Section titled “Limit output”# Last 50 events (default: 100)caracal audit tail --limit 50Filter by request ID
Section titled “Filter by request ID”Every token exchange carries a request_id in the response and in the mandate’s claim set. Correlate a specific exchange:
caracal audit tail --request-id req-abc123Inspect full diagnostics for a request
Section titled “Inspect full diagnostics for a request”explain shows the complete audit record for one request: the principal, resource, decision, determining policies, policy-returned diagnostics, and metadata:
caracal explain req-abc123Example output:
Request: req-abc123Zone: my-zoneDecision: denyEvent: token_exchange
Determining policies: - payments-policy (psv-def456)
Diagnostics: - step_up_required: mfa
Metadata: principal_id: app-xyz789 resource_id: res-ghi012 session_id: sess-jkl345 agent_session_id: sess-mno678As JSON:
caracal explain req-abc123 --jsonAudit event fields
Section titled “Audit event fields”| Field | Description |
|---|---|
id | Audit event UUID |
zone_id | Zone the exchange occurred in |
event_type | token_exchange, jti_collision, challenge_invalid, challenge_cooldown, etc. |
request_id | Correlation ID from the exchange request |
decision | allow or deny |
policy_set_id | Active policy set |
policy_set_version_id | Exact version that was evaluated |
manifest_sha | SHA-256 of the policy set version manifest |
determining_policies | Array of {"policy": "name"} objects |
diagnostics | Array of diagnostic objects from the policy (e.g., {"step_up_required": "mfa"}) |
metadata | Principal, resource, session, and agent session IDs |
occurred_at | Microsecond-precision timestamp |
Common query patterns
Section titled “Common query patterns”Find all denies for a specific application
Section titled “Find all denies for a specific application”caracal audit tail --decision deny --json \ | jq 'select(.metadata.principal_id == "app-abc123")'Find exchanges that triggered step-up
Section titled “Find exchanges that triggered step-up”caracal audit tail --decision deny --json \ | jq 'select(.diagnostics[]?.step_up_required != null)'Check which policy version is making decisions
Section titled “Check which policy version is making decisions”caracal audit tail --limit 10 --json \ | jq '{policy_set_version_id, decision, determining_policies}'Find JTI collision events (replay attempts)
Section titled “Find JTI collision events (replay attempts)”caracal audit tail --event-type jti_collision --jsonAudit chain integrity
Section titled “Audit chain integrity”The audit log is HMAC-chained. Each event includes a chain_hmac that links it to the previous event. Tamper detection runs at Audit service startup and hourly thereafter. Any detected break is recorded in audit_ingest_alerts.
The CLI does not expose chain validation directly. To verify the chain, query audit_ingest_alerts via the Audit service’s API or the database directly.
What to read next
Section titled “What to read next”- Author a Rego Policy —
determining_policiesanddiagnosticscome from the policy’sresultobject - Step-Up Re-Authentication —
challenge_invalidandchallenge_cooldownevents explained