1. The two route families
Console — configure
/api/workspace/firewall/*. Authenticated by your session / access
token (UserAuth), scoped to your active workspace. Author policies,
read events, register MCP servers, resolve approvals. Every action is
role-gated.Gateway — enforce
/api/v1/firewall/*. Authenticated by a firewall-gateway-scoped key
(a key with is_firewall_gateway set). The machine-to-machine surface
your agent or MCP client calls at runtime. A regular relay key gets
403 here.Console routes never take an
sk-orca-… relay key, and gateway routes
never take a session token. Mixing them up is the most common 401/403
when wiring the firewall up the first time. The only sk-orca-… key that
belongs on a /v1/firewall/* call is one minted with is_firewall_gateway
turned on — see Scope, keys & policies.2. Roles at a glance
Console routes resolve your workspace role and gate accordingly. Reads that carry no tool-call provenance are open to any member; writes and anything exposing tool-call arguments require Developer+.| Role | Can do |
|---|---|
| Viewer / member | Read settings, policies, presets, discovered tools, simulate, anomalies. |
| Developer+ | All of the above, plus every write, the events/runs/trace surface, and the test dry-run. |
| Admin+ | Additionally, set the is_firewall_gateway flag on a key and read a gateway key’s plaintext. |
3. Configure a policy from the console
The console routes are how you author and inspect policy. You configure everything in the dashboard UI — these are the same endpoints it calls.Policies & settings
| Method & path | Role | Purpose |
|---|---|---|
GET /api/workspace/firewall/settings | Member | Observe-mode + counts. |
PUT /api/workspace/firewall/settings | Developer+ | Update workspace firewall settings. |
GET /api/workspace/firewall/policies | Member | List policies. |
GET /api/workspace/firewall/policies/:id | Member | Single policy detail. |
POST /api/workspace/firewall/policies | Developer+ | Create a policy. |
PUT /api/workspace/firewall/policies | Developer+ | Update a policy. |
DELETE /api/workspace/firewall/policies/:id | Developer+ | Delete a policy. |
POST /api/workspace/firewall/rules | Developer+ | Add a rule. |
PUT /api/workspace/firewall/rules | Developer+ | Update a rule. |
DELETE /api/workspace/firewall/rules/:id | Developer+ | Delete a rule. |
Posture, presets & sandboxes
| Method & path | Role | Purpose |
|---|---|---|
GET /api/workspace/firewall/presets | Member | Built-in rule presets. |
GET /api/workspace/firewall/templates | Member | Use-case template gallery. |
POST /api/workspace/firewall/templates/apply | Developer+ | Apply a template → one policy + its rules. |
POST /api/workspace/firewall/autonomy | Developer+ | Apply an autonomy level (tight / balanced / permissive). |
POST /api/workspace/firewall/autonomy/undo/:audit_id | Developer+ | One-click undo from the audit snapshot. |
GET /api/workspace/firewall/simulate | Member | What a level would block (?level=). |
POST /api/workspace/firewall/test | Developer+ | Dry-run a policy against a sample call. |
Observability
| Method & path | Role | Purpose |
|---|---|---|
GET /api/workspace/firewall/discovered-tools | Member | Tools seen, flagged covered / gap. |
GET /api/workspace/firewall/events | Developer+ | List firewall events (filterable). |
GET /api/workspace/firewall/events/by-request/:request_id | Developer+ | Events for one request. |
GET /api/workspace/firewall/events/aggregate | Developer+ | Runs / sessions rollup. |
GET /api/workspace/firewall/trace/by-run | Developer+ | Trace nodes for a run (?run_id=). |
GET /api/workspace/firewall/anomalies | Member | Anomaly feed. |
POST /api/workspace/firewall/anomalies/snooze | Developer+ | Snooze the feed (≤ 7 days). |
MCP servers
Register the Model Context Protocol servers your agents reach, behind one audited gateway. Credentials are stored encrypted and masked on read.| Method & path | Role | Purpose |
|---|---|---|
GET /api/workspace/firewall/mcp_servers | Member | List registered servers. |
GET /api/workspace/firewall/mcp_servers/:id | Member | Server detail. |
POST /api/workspace/firewall/mcp_servers | Developer+ | Register a server (409 on a duplicate name). |
PUT /api/workspace/firewall/mcp_servers | Developer+ | Update a server. |
DELETE /api/workspace/firewall/mcp_servers/:id | Developer+ | Remove a server. |
POST /api/workspace/firewall/mcp_servers/:id/probe | Developer+ | Reachability + tools/list handshake. |
name, an endpoint, an auth_mode
(none / bearer / oauth / basic), and a health status
(ok / degraded / down). See Firewall MCP for
the full lifecycle and skill quarantine.
4. Enforce at the gateway
These run on a firewall-gateway-scoped key, not your session. They’re what your agent loop or MCP client calls at runtime.| Method & path | Purpose |
|---|---|
POST /api/v1/firewall/evaluate | Pre-dispatch verdict for one tool call. |
POST /api/v1/firewall/evaluate_plan | Pre-execution check for a multi-step plan. |
ANY /api/v1/firewall/mcp | The unified MCP gateway endpoint. |
GET /api/v1/firewall/mcp_servers | Enumerate the workspace’s registered servers. |
GET /api/v1/firewall/approvals/:id | Poll a held call’s approval state. |
POST /api/v1/firewall/approvals/:id/callback | HMAC-signed approval callback. |
One concrete example: evaluate a tool call
Before your agent dispatches a tool, ask the gateway for a verdict. Pass the firewall-gateway-scoped key — not your relaysk-orca-… key:
allow, audit, deny, sanitize, or
pending_approval. On deny you skip the call and surface the reason to the
model; on sanitize you forward the cleaned arguments the gateway hands
back (sanitize redacts tool-call arguments only — never the content a tool
returns); on pending_approval you enter the approval loop below.
5. The approval handshake (HITL)
Apending_approval verdict holds the call for a human. The HTTP error while
held is firewall_approval_pending. Clearing it is a three-step loop split
across both route families:
A reviewer resolves the hold
From the console (
PATCH /api/workspace/firewall/approvals/:id,
Developer+), or your own system posts an HMAC-signed callback to
POST /api/v1/firewall/approvals/:id/callback. The callback verifies the
HMAC inline — no other auth is accepted.Your agent polls the approval
GET /api/v1/firewall/approvals/:id with the gateway key, until the
state flips to approved or rejected.6. What a block looks like
| Outcome | HTTP | Code |
|---|---|---|
| Denied tool call (inbound surface) | 400 | firewall_blocked |
| Denied via MCP gateway | tool error | firewall deny: <reason> |
| Held for approval | 400 | firewall_approval_pending |
firewall_blocked is marked skip-retry — re-running the identical call
would just block again, so a retrying client backs off instead of hammering.
The full code list lives in Error codes.
7. Related references
Guardrail API
The content-policy peer —
/api/guardrail/* routes for the text plane.Verdict glossary
Every verdict and what it does to a call.
Glob & JSONPath
The matching grammar behind
tool_name_glob and args_match.Compliance API
Packs, signed reports, residency, and erasure.
8. FAQ
Why does my relay key get a 403 on /api/v1/firewall/evaluate?
Why does my relay key get a 403 on /api/v1/firewall/evaluate?
The gateway routes require a firewall-gateway-scoped key — one minted
with
is_firewall_gateway set (an Admin+ action). A regular relay key,
even a valid one, gets 403. Mint a dedicated gateway key for your agent
runtime.Can a viewer read firewall events?
Can a viewer read firewall events?
No. The
events, events/aggregate, and trace routes are Developer+
because the records carry tool-call argument provenance. Viewers can read
settings, policies, presets, discovered tools, simulate, and the anomaly
feed.Where do I resolve a held approval — console or gateway?
Where do I resolve a held approval — console or gateway?
Either. A human resolves it in the console via
PATCH /api/workspace/firewall/approvals/:id (Developer+), or your own
system posts an HMAC-signed decision to
POST /api/v1/firewall/approvals/:id/callback. The agent polls
GET /api/v1/firewall/approvals/:id regardless of which path resolved it.Does sanitize clean what a tool returns?
Does sanitize clean what a tool returns?
No. A
sanitize verdict redacts the tool-call arguments only — never
the content a tool returns. On the inbound surface, where there are no
call-time arguments yet, sanitize escalates to a block. See
Firewall rules.For how these controls compose with guardrails and the rest of the gateway, see Securing AI agents and Guardrails vs Firewall.
