# Runtime Proxy Audit JSONL

`agent-bom proxy --log audit.jsonl` writes one JSON object per line. The file
is intended for local review, SIEM forwarding, runtime correlation, and release
evidence. Durable records are sanitized before they are appended to the log.

## Start a local audit log

```bash
agent-bom proxy \
  --log audit.jsonl \
  --policy policy.json \
  --block-undeclared \
  --detect-credentials \
  -- npx @modelcontextprotocol/server-filesystem /workspace
```

## Example records

These records are shown on separate lines because JSONL is line-delimited.
Hashes are example values.

```jsonl
{"ts":"2026-05-08T18:56:05.635108+00:00","type":"tools/call","tool":"read_file","agent_id":"anonymous","tenant_id":"default","policy":"blocked","event_relationships":{"normalization_version":"1","source":"proxy_tool_call","targets":[{"type":"tool","id":"read_file","role":"invoked_tool","source_field":"tool"}],"resources":[{"type":"path","id":"<path:passwd>","role":"referenced_input","source_field":"path"}]},"prev_hash":"","record_hash_algorithm":"aes-cmac-128","record_hash":"be865de2cfeef8d0f1056cbc8b40ad36"}
{"ts":"2026-05-08T18:57:14.240901+00:00","type":"tools/call","tool":"write_file","agent_id":"anonymous","tenant_id":"default","policy":"allowed","event_relationships":{"normalization_version":"1","source":"proxy_tool_call","targets":[{"type":"tool","id":"write_file","role":"invoked_tool","source_field":"tool"}],"resources":[{"type":"path","id":"<path:report.md>","role":"referenced_input","source_field":"path"}]},"prev_hash":"be865de2cfeef8d0f1056cbc8b40ad36","record_hash_algorithm":"aes-cmac-128","record_hash":"bd6029a0fd242e9a7a49d0dc03e0f3c9"}
{"ts":"2026-05-08T18:58:00.000000+00:00","type":"proxy_summary","uptime_seconds":300.0,"total_tool_calls":2,"total_blocked":1,"calls_by_tool":{"read_file":1,"write_file":1},"blocked_by_reason":{"policy":1},"latency":{"min_ms":12.4,"max_ms":33.9,"avg_ms":23.15,"p50_ms":33.9,"p95_ms":33.9,"count":2},"messages_client_to_server":5,"messages_server_to_client":4,"replay_rejections":0,"relay_errors":0,"audit_buffer_bytes":0,"audit_spillover_bytes":0,"audit_dlq_bytes":0,"policy_fetch_failures":0,"audit_push_failures":0,"audit_push_backoff_seconds":0,"audit_circuit_open":0}
```

## Field guide

| Field | Meaning |
|---|---|
| `ts` | UTC timestamp generated by the proxy. |
| `type` | Record type, commonly `tools/call` or `proxy_summary`. |
| `tool` | MCP tool invoked by a `tools/call` request. |
| `agent_id` | Resolved agent identity, or `anonymous` when no identity is available. |
| `tenant_id` | Tenant scope used for runtime correlation and control-plane audit ingest. |
| `policy` | Effective local proxy policy result, such as `allowed` or `blocked`. |
| `event_relationships` | Normalized tool and resource references for graph/runtime correlation. |
| `prev_hash` | Previous durable record hash for the local audit chain. |
| `record_hash_algorithm` | Hash algorithm label used for the durable chain. |
| `record_hash` | Current durable record hash. |
| `blocked_by_reason` | Summary-only aggregate of normalized block reasons. |
| `audit_buffer_bytes`, `audit_spillover_bytes`, `audit_dlq_bytes` | Backlog health for control-plane audit push delivery. |

## Redaction boundary

Durable proxy audit records are Tier-A evidence. The writer removes raw prompts,
full tool arguments, full paths, URLs with credentials, response bodies, and
free-text policy reasons before appending the JSONL line. The durable record
keeps safe structural fields such as tool name, policy decision, normalized
relationships, tenant, and audit-chain hashes.

When replay capture is explicitly enabled, richer Tier-B payloads are stored in
the separate replay store with a retention boundary. Do not treat
`audit.jsonl` as a raw transcript of tool input or output.

## Operator checks

```bash
# Confirm every line is valid JSON.
jq -c . audit.jsonl >/dev/null

# Inspect tool call decisions without printing redacted payloads.
jq -r 'select(.type == "tools/call") | [.ts, .tenant_id, .tool, .policy] | @tsv' audit.jsonl

# Summarize the proxy shutdown record.
jq 'select(.type == "proxy_summary") | {total_tool_calls,total_blocked,blocked_by_reason,audit_dlq_bytes}' audit.jsonl
```

Use the same `audit.jsonl` path with `agent-bom runtime correlate` or the MCP
runtime correlation tool when connecting live tool behavior back to scan
findings.
