Skip to main content
When your firewall policy judges a tool call, it writes a row. The events feed is that running log: one record per evaluation, carrying the verdict, the surface it fired on, the tool, the reason, and the run/session it belonged to. It’s how you answer the only question that matters after you ship a policy — did the firewall actually do what I think it did, on the calls I think it did it on? This is your ai firewall logs surface. Every allow, every deny, every held approval, every shadow-mode “would-have” lands here, filterable and correlated back to the agent run that produced it.
The events feed is Developer+ to read. Each row reserves a capped args_summary field for a tool-call argument snapshot, so the surface sits above the Member-readable ones (settings, policies, discovered tools, the anomaly feed). Configure all of this from the console — these are session-authenticated routes, not relay calls.

1. What lands in the events feed

Every evaluation the engine runs is recorded — not just the blocks. An allow and an audit leave a row exactly like a deny does, so the feed is a complete trail, not an exception log. The verdict on a row is the one the agent actually saw:
VerdictMeans
allow / auditLet through; audit flags it as something you wanted to watch.
denyBlocked — firewall_blocked (HTTP 400) inbound, tool error on mcp.
sanitizeForwarded with matched substrings redacted from the call’s arguments.
pending_approvalHeld for a human; the row marks the call was gated.
observeNo policy matched — an observe-mode coverage gap.
You’ll never see a literal cap_cost in the feed. A cap-cost rule resolves to a concrete allow or deny at evaluation time, and that’s what gets logged — the verdict the run actually experienced.
In shadow mode the enforcing verdicts are downgraded to audit and the reason is prefixed [shadow] would …, so the feed shows you exactly what a policy would have blocked before you flip it live.

2. What each event records

A single event is a denormalized snapshot — enough to reconstruct the decision without joining back to anything:
verdict, surface (inbound / response / mcp / egress), tool_name, and a human reason (“destructive shell command”, “egress to 169.254.169.254 denied”). When the matching rule had a label, policy_name and rule_label name the exact rule that fired — so the row points straight back to the line you wrote.
request_id joins the event to the request log; conversation_id groups a multi-turn session; agent_run_id (with step_id / parent_step_id) ties it to one full agent run and the LLM call that requested the tool. These are what make the feed a trace, not a flat list — see §4.
token_name, model_name, and the caller ip — the key, model, and origin behind the call. skill_name names the owning skill when the call was attributable to one, and quarantine flags a skill-quarantine hold.
args_summary is the capped tool-call argument snapshot field (the reason this surface is Developer+). On an egress event, egress_host records the outbound destination that was judged.
args_summary is capped — the raw argument bytes are never written verbatim to the feed, and the retry-loop grouping hash that backs anomaly detection is server-only: it never ships in the API.

3. One concrete example

Your agent emitted a shell.exec call with rm -rf /data, a deny rule caught it, and you want to see that one decision. Filter the feed by verdict and tool:
# Developer+ console session — GET /api/workspace/firewall/events
curl https://api.orcarouter.ai/api/workspace/firewall/events?verdict=deny&tool=shell.exec \
  -H "Authorization: Bearer $ORCA_CONSOLE_TOKEN"
{
  "events": [
    {
      "verdict": "deny",
      "surface": "response",
      "tool_name": "shell.exec",
      "reason": "destructive shell command",
      "policy_name": "agent-baseline",
      "rule_label": "block destructive shell",
      "model_name": "gpt-4o",
      "token_name": "prod-agent",
      "agent_run_id": "run_abc",
      "request_id": "req_…"
    }
  ],
  "total": 1
}
The console renders the same rows as a filterable table — you rarely hit the route by hand. Configure filters, drill into a run, and export from the events view; the curl above is just to show the shape.
$ORCA_CONSOLE_TOKEN is your session / access token, not an sk-orca-… relay key. The /api/workspace/firewall/* routes are console-authenticated and role-gated; only /v1/* traffic uses a relay key.

4. Correlate by run and session

The reason every event carries agent_run_id and conversation_id is so you can stop looking at calls in isolation and start asking what did this agent do over its whole run:
FilterQuestion it answers
run_id=<run>Every verdict in one agent run — the full action trail.
session_id=<conv>Every verdict across a multi-turn conversation.
verdict=deny,pending_approvalThe “what got stopped or held” view in one query.
surface=egressOnly outbound-destination decisions — the exfiltration lens.
The events list also accepts since / until (unix seconds) and limit / skip for paging. For the rolled-up view — one row per run or session with a per-verdict breakdown, distinct tools and models, and first/last-seen — the console reads GET /api/workspace/firewall/events/aggregate?group_by=run (or group_by=session), and the agent-trace tree reads /trace/by-run. Both are Developer+, same as the raw feed.
From the request-log drawer you can pivot the other direction: GET /api/workspace/firewall/events/by-request/:request_id returns every firewall event captured under a single request — handy when one request tripped several rules across surfaces.

5. Retention and erasure

Firewall events carry their own retention horizon — a 30-day default, server-clamped to a 365-day hard maximum. Each event is written with an expiry and aged out automatically by a TTL index; nothing in the feed lives past your retention setting. A right-to-erasure request cascades here too: deleting a user starts a 30-day grace period, after which their PII is scrubbed and their firewall events are purged alongside the request logs and guardrail matches of the same scope.

Where to go next

Verdicts

What each verdict in the feed actually did to the call.

Shadow mode

Read the feed in “would-have” mode before you enforce.

Stages & surfaces

The four surfaces the surface field names.

Firewall reference

The full policy, rule, and API reference.
For the threats these logs help you catch in the act, see data exfiltration and dangerous tool calls. For how the firewall pairs with prompt/response text screening, see firewall + guardrails.