Schema

Audit log entries are JSON objects, one per line. This page documents the complete schema.

Top-Level Fields

FieldTypeDescription
validation_startedstringRFC3339Nano timestamp when validation began
created_atstringRFC3339Nano timestamp when entry was written
toolobjectTool call information
upstream_requestobjectIncoming request metadata
aiobjectAI provider info (when AI validation enabled)
request_validationobjectRequest validation results
response_validationobjectResponse validation results
recommended_actionstringWhat validation recommended
actionstringWhat actually happened: allow or deny
action_reasonstringWhy action was taken
duration_msintTotal time from start to entry written
total_blocked_msintTime caller was blocked

Tool Object

{
  "tool": {
    "name": "delete_file",
    "client": "github",
    "prefixed_name": "github__delete_file",
    "params": { "path": "/tmp/test.txt" },
    "called_at": "2025-02-04T15:30:00.500Z",
    "duration_ms": 234
  }
}
FieldTypeDescription
namestringOriginal tool name
clientstringDownstream MCP server name
prefixed_namestringFull prefixed name (client__name)
paramsobjectTool call parameters (may be omitted)
called_atstringWhen downstream tool was invoked (omitted if denied)
duration_msintDownstream call duration (omitted if denied)

Upstream Request Object

{
  "upstream_request": {
    "id": "req-abc123",
    "session_id": "sess-xyz789",
    "client_ip": "192.168.1.100",
    "user_agent": "claude-code/1.0"
  }
}
FieldTypeDescription
idstringRequest ID
session_idstringSession identifier
client_ipstringClient IP address
user_agentstringUser-Agent header

AI Provider Object

Present when AI validation is enabled:

{
  "ai": {
    "provider": "openai",
    "model": "gpt-4o-mini",
    "endpoint_host": "api.openai.com",
    "endpoint_path": "/v1/chat/completions"
  }
}

Validation Objects

Both request_validation and response_validation share the same structure. Each contains a cel and/or ai object with per-engine results:

{
  "request_validation": {
    "cel": {},
    "ai": {}
  }
}

CEL Results

{
  "cel": {
    "action": "deny",
    "blocked_ms": 2,
    "evaluation_ms": 2,
    "deciding_rule": "deny-delete-file",
    "reason": "File deletion is not allowed",
    "results": [
      {
        "rule": "deny-delete-file",
        "action": "deny",
        "result": "deny",
        "evaluation_ms": 1
      },
      {
        "rule": "allow-read-only",
        "action": "deny",
        "mode": "audit_only",
        "result": "allow",
        "evaluation_ms": 1
      }
    ]
  }
}
FieldTypeDescription
actionstringFinal CEL decision: allow, deny, or redact
blocked_msintTime this phase blocked the request
evaluation_msintTotal evaluation time
deciding_rulestringRule that caused the decision
reasonstringMessage from deciding rule
resultsarrayPer-rule results

Per-Rule Result

FieldTypeDescription
rulestringRule name
actionstringRule’s configured action
modestringPresent if audit_only
resultstringEffective decision
evaluation_msintTime for this rule
errorstringPresent if evaluation failed

AI Results

{
  "ai": {
    "action": "deny",
    "blocked_ms": 1500,
    "evaluation_ms": 2300,
    "deciding_rule": "check-mass-deletion",
    "reason": "Wildcard deletion blocked",
    "request_id": "chatcmpl-abc123",
    "results": [
      {
        "rule": "check-mass-deletion",
        "action": "deny",
        "result": "deny",
        "evaluation_ms": 1500
      },
      {
        "rule": "check-system-dirs",
        "action": "deny",
        "result": "allow",
        "evaluation_ms": 800
      }
    ]
  }
}
FieldTypeDescription
actionstringFinal AI decision
blocked_msintTime request was blocked
evaluation_msintTotal evaluation time
deciding_rulestringRule that caused decision
reasonstringAI’s explanation
request_idstringProvider request ID (for debugging)
resultsarrayPer-rule results

Action Reasons

The action_reason field explains why the final action was taken:

ValueMeaning
request_policyRequest validation denied
response_policyResponse validation denied
audit_modeWould deny, but running in audit_only mode
fail_openValidation timed out, allowing request
(empty)Normal allow, no special circumstances

Complete Example

{
  "validation_started": "2025-02-04T15:30:00.000000000Z",
  "created_at": "2025-02-04T15:30:02.345678000Z",
  "tool": {
    "name": "delete_file",
    "client": "github",
    "prefixed_name": "github__delete_file",
    "params": {
      "path": "/tmp/*.txt"
    }
  },
  "upstream_request": {
    "id": "req-abc123",
    "session_id": "sess-xyz789",
    "client_ip": "192.168.1.100",
    "user_agent": "claude-code/1.0"
  },
  "ai": {
    "provider": "openai",
    "model": "gpt-4o-mini",
    "endpoint_host": "api.openai.com"
  },
  "request_validation": {
    "cel": {
      "action": "deny",
      "blocked_ms": 1,
      "evaluation_ms": 1,
      "deciding_rule": "deny-delete-file",
      "reason": "File deletion is not allowed",
      "results": [
        {
          "rule": "deny-delete-file",
          "action": "deny",
          "result": "deny",
          "evaluation_ms": 1
        }
      ]
    },
    "ai": {
      "action": "deny",
      "blocked_ms": 0,
      "evaluation_ms": 1200,
      "deciding_rule": "check-mass-deletion",
      "reason": "Wildcard deletion blocked",
      "results": [
        {
          "rule": "check-mass-deletion",
          "action": "deny",
          "result": "deny",
          "evaluation_ms": 1200
        }
      ]
    }
  },
  "recommended_action": "deny",
  "action": "deny",
  "action_reason": "request_policy",
  "duration_ms": 2345,
  "total_blocked_ms": 1
}

Parsing Tips

Since entries are newline-delimited JSON, you can use standard tools:

# Count denies
cat audit.log | jq -r 'select(.action == "deny")' | wc -l

# Find slow validations
cat audit.log | jq -r 'select(.duration_ms > 5000)'

# Extract tool names
cat audit.log | jq -r '.tool.prefixed_name' | sort | uniq -c