initializdocs
AgentsRuntime

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_request or web_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_blocked audit 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.

On this page