Skip to content

Observability Commands

Observability commands read the audit ledger. They require CARACAL_ADMIN_TOKEN and a zone ID. No mutation is possible through these commands.


Fetch recent audit events for a zone.

Terminal window
caracal audit tail
caracal audit tail --decision deny --limit 50
caracal audit tail --since 2026-05-01T00:00:00Z --until 2026-05-02T00:00:00Z
caracal audit tail --event-type token_exchange

Flags:

FlagTypeDefaultDescription
--since <timestamp>ISO 8601Return events after this time
--until <timestamp>ISO 8601Return events before this time
--request-id <id>stringFilter to a single request ID
--decision <d>allow|deny|partialFilter by policy decision
--event-type <type>stringFilter by event type
--limit <n>integer100Maximum rows to return
--zone <id>stringFrom env/configZone ID
--jsonbooleanfalseEmit JSON

Table columns: occurred_at, event_type, decision, evaluation_status, request_id, id

Example output:

occurred_at event_type decision evaluation_status request_id
----------- ---------- -------- ----------------- ----------
2026-05-11T20:00:01Z token_exchange allow complete req_abc123
2026-05-11T20:00:02Z token_exchange deny complete req_def456
2026-05-11T20:00:03Z agent_spawn allow complete req_ghi789

Common patterns:

Find all denied token exchanges in the last hour:

Terminal window
caracal audit tail \
--since $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ) \
--decision deny \
--event-type token_exchange

Pipe to jq for analysis:

Terminal window
caracal audit tail --json | jq '.[] | select(.decision == "deny") | .request_id'

Show the full policy evaluation diagnostics for a single request.

Terminal window
caracal explain req_def456
caracal explain req_def456 --json

Arguments:

ArgumentDescription
<request_id>Request ID from an audit event. Use caracal audit tail to find it.

Flags: --zone <id>, --json

Plain-text output:

event token_exchange decision=deny status=complete
occurred_at 2026-05-11T20:00:02Z
request_id req_def456
policy_set pset_pqr678 version=psetv_jkl012 sha=sha256:abc123...
determining_policies:
[
{
"policy_id": "pol_mno345",
"policy_version_id": "polv_abc",
"decision": "deny"
}
]
diagnostics:
[
{
"rule": "scope_guard",
"message": "required scope 'transfer:write' not present",
"data": {"requested_scopes": ["transfer:read"]}
}
]
metadata:
{"subject": "user_vwx234", "application_id": "app_def456", "resource": "resource://payments-api"}

JSON output:

With --json, the command emits the raw array of AuditDetail objects:

[
{
"id": "audit_xyz",
"event_type": "token_exchange",
"decision": "deny",
"evaluation_status": "complete",
"occurred_at": "2026-05-11T20:00:02Z",
"request_id": "req_def456",
"policy_set_id": "pset_pqr678",
"policy_set_version_id": "psetv_jkl012",
"manifest_sha": "sha256:abc123...",
"determining_policies_json": [...],
"diagnostics_json": [...],
"metadata_json": {...}
}
]

Workflow:

  1. Notice a failed exchange in application logs or a failing test.
  2. Capture the request_id from the error response or from the application’s trace headers.
  3. Run caracal explain <request_id> to see exactly which policy denied the request and why.
  4. Inspect diagnostics_json for the specific rule and message.
  5. Update the Rego policy or fix the grant and re-test.

For live streaming of audit events as they arrive, use the TUI, which polls the audit endpoint every 2 seconds and applies color coding to decisions.