Egress control
Deny-all-by-default outbound networking with a per-agent domain allowlist, enforced in layers.
An agent that can call any tool can, in principle, send data anywhere. The agent runtime closes that risk with egress control: by default a deployed agent has no outbound network access at all, and every external host it may reach must be on its allowlist.
Deny-all by default
Each agent carries its own egress policy, fixed at build time. The default posture is deny-all: no outbound connections except localhost. From there, the platform builds the agent's allowlist from what the agent actually needs:
- Explicit domains you configure for the agent.
- Skill and tool requirements — a skill or tool that declares the API hosts it talks to gets those domains added automatically.
- Platform services — the model gateway, channel platforms (for example Slack), and the platform's own verification endpoints are included so the agent can function.
Allowlist entries match exactly (api.example.com) or by wildcard
(*.example.com matches subdomains). Anything not matched is blocked.
Layers of enforcement
The same allowlist is enforced at several levels, so there is no gap between what the agent's code does and what its scripts or subprocesses do:
- In-process enforcement — every HTTP request made by the agent's own
tools (such as
http_requestorweb_search) is checked against the allowlist before it leaves the process. - Subprocess enforcement — skill scripts and approved command-line
binaries (for example
curl) are routed through a local proxy that applies the same allowlist rules. - Network-level enforcement — in the agent's deployment environment, a network policy generated from the same allowlist restricts traffic at the infrastructure level, backstopping the in-process controls.
Beyond domain matching, the runtime defends against common bypass techniques: disguised IP address formats are rejected, DNS answers are re-validated before connecting (preventing DNS-rebinding tricks), cloud metadata addresses are always blocked, and credentials are stripped when a request is redirected to a different origin.
Private network access
Private and internal IP ranges are blocked by default — an allowlisted domain name cannot be used to smuggle a connection to an internal address, and cloud metadata endpoints are unreachable no matter what the policy says.
When an agent genuinely needs an internal service, its egress policy can open specific private network ranges instead of the whole private address space: addresses inside the listed ranges become reachable, and everything else private stays blocked. Two properties are worth knowing:
- Always-blocked addresses stay blocked. Cloud metadata and similar sensitive addresses cannot be opened by any range entry — no allowlist punches a hole in them.
- Ranges are validated when the agent is built. A malformed or ambiguous range — for example one that mixes a single host address with a wide network mask — is rejected at build time, so a typo surfaces as a build failure rather than a policy that is silently wider than intended. Listing the entire address space is permitted but simply equivalent to allowing all private addresses; if that is really the intent, the broader allow-private setting states it more clearly.
Raw TCP connections
Not everything an agent reaches speaks HTTP — databases, caches, and
message brokers use their own wire protocols. The runtime supports raw TCP
egress through the same local proxy, governed by a port-aware
allowlist. Each entry names a host and port (db.internal:5432), a
wildcard host with an exact port (*.brokers.internal:9092), or a host on
any port (metrics.internal:*). As with HTTP, anything not listed is
refused before the connection is dialed, and the raw-TCP path is disabled
entirely unless the agent declares at least one TCP destination.
Because internal databases usually live on private addresses, a raw TCP destination typically also needs a private network range (above) — the target must pass both checks.
The HTTP allowlist is host-based, not port-based: once raw TCP is enabled, a hostname allowlisted for HTTPS is reachable on any port over the TCP path. If a host needs port-level control, list it as an explicit host-and-port TCP entry instead of an HTTP domain.
Raw TCP attempts are audited like HTTP ones — each is recorded with the host, port, and decision — though they are not attributed to a specific task the way HTTP requests are.
What happens on a blocked call
When the agent (or one of its scripts) tries to reach a host that is not allowlisted:
- The request fails immediately with a clear "egress blocked" error naming the domain — the connection is never attempted.
- The agent sees the failure as a tool error and can report it or try a different approach; it cannot retry its way around the policy.
- An
egress_blockedaudit event is emitted with the blocked domain, and it surfaces in the platform's Security area so operators can see exactly which agent tried to reach what, and when.
Allowed calls are recorded too (as egress_allowed events), giving a
complete picture of an agent's outbound behavior. HTTP egress events carry
the task and invocation identifiers of the work that caused them —
including requests made by skill scripts and subprocesses through the
local proxy — so outbound traffic is attributable to a specific task, not
just visible in aggregate.
If an agent legitimately needs a new external API, the fix is to add the domain to the agent's configuration (or use a skill that declares it) and redeploy — the allowlist is part of the agent, not a runtime toggle.
Full runtime detail — proxy behavior, private-range validation rules, and the raw-TCP path — lives in the developer section: Egress control.