http_fetch, web_search, or any tool that opens an
outbound connection, the destination is the part you most need to govern.
A confused or hijacked agent that can reach 169.254.169.254 reads your
cloud credentials; one that can POST to an attacker host exfiltrates your
data. Agent egress control governs that destination — you author a
host/CIDR allow/deny rule on the firewall’s egress surface, attach it
to a key, and the gateway checks every outbound destination an agent’s
tool reports before the call goes out.
This is a focused use-case page. For the full rule grammar and verdict
semantics see Rule schema and
Verdicts; for how egress sits among the
other enforcement points see Stages.
1. Agent egress control on the egress surface
Of the firewall’s four surfaces,egress is
the one that sees the outbound network destination a tool reports — a
host, an IP literal, or a CIDR. A rule pinned to stage: egress matches on
that destination, not on the tool name or its arguments, which makes it the
SSRF and data-exfiltration control: it answers where can this agent
reach, independent of which tool did the reaching.
Egress is destination scoping, not tool blocking. To stop a tool from
existing at all, deny it by name on the inbound surface
(Block tools). Egress control assumes the
tool may legitimately fetch — it just constrains where to.
2. One example: deny the SSRF destinations
The canonical egress rule denies the cloud metadata endpoint and the private RFC-1918 ranges — the destinations a fetch-shaped tool should never reach. In your workspace console, open a policy and add a rule withstage
egress, verdict deny, and an egress list:
egress_json is a JSON-encoded string carrying the host/CIDR lists —
decoded, it’s {"deny": [...], "allow": [...]}. Each entry matches as a
CIDR, an IP literal, or a case-insensitive hostname. For a
deny verdict the deny list is the in-scope set (destinations the rule
blocks) and the allow list carves exceptions out of it — so the rule above blocks the four ranges but lets
api.openai.com through even if it ever resolved into one. When a
destination is a hostname rather than a literal IP and your list carries
IP/CIDR entries, the name is best-effort resolved and its addresses
re-checked, so metadata.internal still matches a 169.254.0.0/16 deny
even though it isn’t listed by name.
3. You author the CIDR rules — no preset ships them
What thetight autonomy level and its
block_ssrf_egress preset do ship is a set of denies on the
fetch-shaped tool names — http_fetch, web_search, fetch_url,
request, plus their <server>.<tool> MCP variants. That’s a blunt
posture: it refuses the egress-shaped tools outright rather than scoping
where they may reach. Reach for it when an agent has no business making
network calls at all; reach for a destination rule (§2) when it does fetch
but only from an approved set of hosts.
| Approach | What it constrains | Author |
|---|---|---|
tight SSRF preset | Fetch-shaped tool names (denies them) | Built-in |
| Egress CIDR/host rule | The destination a fetch may reach | You |
4. What a blocked egress looks like
When a destination matches an enforcing egress rule, the call is denied before it leaves the gateway and the evaluation is recorded as a firewall event with surfaceegress and verdict deny. In
shadow mode the deny is downgraded to
audit with the reason prefixed [shadow] would …, so you can measure
exactly which destinations a rule would block against real traffic before
you enforce it.
A malformed or entry-less egress list is treated conservatively: an
enforcing
deny rule still gates (a typo can’t silently stop it blocking),
but an allow rule with a broken list will not fire — otherwise a
mistyped allow-list would become allow-all and shadow a default deny. New
rules are validated on save (the list must declare at least one allow or
deny entry), so this only ever guards legacy rows.5. Author from real traffic, then roll out
See the destinations you're actually reaching
See the destinations you're actually reaching
The events log records the destination
host on each
egress-surface event (egress_host/egress_url), so
filter it to surface egress and author your deny list off the
destinations that actually showed up rather than guessing. The
Discovered Tools tab is a per-tool-name rollup (tool names and the
surfaces they fired on) — it tells you which fetch-shaped tools ran,
not the hosts they reached. See Analytics.Dry-run a verdict before you depend on it
Dry-run a verdict before you depend on it
The console Test tab dry-runs a policy against a sample
tool_name + surface (+ optional args) and returns the verdict, the
matched rule, and the reason — nothing is dispatched. It confirms
which rule a call resolves to; to confirm your CIDR/host math against
real destinations, use shadow mode below (the Test payload doesn’t carry
a destination, so egress-list matching is exercised on live egress
traffic). See Test rules.Measure live with shadow mode
Measure live with shadow mode
Turn on shadow mode and the egress
deny is logged as it would fire without blocking. Watch the
events log filtered to surface
egress, confirm it catches the destinations you expect, then flip
shadow off.6. Attach the policy and who can edit it
A policy does nothing until a key resolves to it. Attach in the console by settingfirewall_policy_id on the
key, or make the policy the workspace
default. Resolution is: the key’s attached policy (when it exists and is
enabled), else the workspace default.
All egress-rule configuration runs in the console under your session
(/api/workspace/firewall/*):
| Action | Role |
|---|---|
| Read policies, presets, discovered tools, autonomy Simulate | Member |
| Create / edit / delete egress rules and policies | Developer+ |
Dry-run Test endpoint (POST /test) | Developer+ |
| Read the events log and run aggregates | Developer+ |
Related
Data exfiltration
The threat egress control addresses.
Stages
The four surfaces, and where egress sits.
Verdicts
What deny, audit, and allow do on the wire.
Block tools
Deny a fetch tool by name instead of by destination.
Dangerous tool calls
The broader risk class.
Firewall reference
The full rule + matching reference, including egress lists.
