Default-Deny Egress: Building an Allowlist Your LLM Can't Talk Around

Learn how to build a default-deny egress allowlist for AI agents that an LLM can't bypass. A developer playbook for locking down outbound agent traffic.

8 min read

An autonomous agent is, by design, a program that decides what to do next at runtime. That includes deciding which hosts to connect to, which APIs to call, and what data to put in the request body. The moment you hand an LLM a tool that can make a network request, you have handed it the ability to reach any endpoint on the internet — unless something on the wire says no.

This is why a denylist is the wrong default for agents. You cannot enumerate every malicious domain, every exfiltration endpoint, every attacker-controlled webhook, or every freshly registered typosquat. A default-deny egress allowlist flips the problem: instead of trying to predict every bad destination, you declare the small set of good destinations and drop everything else. This is the posture Agent G enforces as a drop-in egress proxy, and it is the single highest-leverage control you can put around an LLM that acts on its own.

Why Denylists Fail for Autonomous Agents

Traditional outbound filtering assumes a known, mostly-static set of threats. That assumption holds for deterministic software where every network call is written by an engineer and reviewed in a pull request. It collapses for agents.

  • The destination is model-decided. A prompt-injected agent can be steered to POST your customer table to https://attacker.example/collect. No denylist contains that domain because it was registered an hour ago.
  • Encoding and indirection are trivial. Data can leave base64-encoded, chunked across DNS queries, or smuggled through a legitimate service like a webhook relay.
  • The blast radius is the whole internet. One overlooked CIDR, one allowed wildcard, and the agent has an open path.

Default-deny inverts the burden of proof. The agent must justify every destination against an explicit policy, and the proxy fails closed when no rule matches. For a deeper look at exactly which calls an agent emits, see what actually happens on the wire when an LLM acts on its own.

The Anatomy of an Egress Allowlist

A naive allowlist is just a list of domains. A production-grade allowlist for agents is a layered policy that matches on several dimensions of each outbound request. The more dimensions you can assert, the harder it is for the LLM to talk around the rule.

1. Identity: Who is making the call?

Every rule should be scoped to an agent identity, not applied globally. A retrieval agent that only needs to reach your vector store should not inherit the allowlist of a coding agent that needs package registries. Tie policy to a non-human identity so a compromised agent cannot borrow another agent's reach. Agent G evaluates identity at the network boundary on every request — issuance alone is never enough.

2. Destination: Where is it going?

Allow specific fully-qualified domains, not wildcards where you can avoid them. api.openai.com is a rule; *.openai.com is a liability. Resolve and pin against the IPs your DNS returns, and explicitly deny the cloud metadata endpoint 169.254.169.254 and other link-local ranges so a single tool call can't pivot into SSRF against your instance metadata service.

3. Method and path: What operation?

An agent that reads from an API rarely needs to DELETE against it. Allow GET https://api.internal/customers/* while denying POST and DELETE on the same host. This is where allowlisting stops being a firewall feature and becomes tool-call governance.

4. Payload: What's in the body?

Even an allowed destination can become an exfiltration channel. Inspecting request bodies for credentials, PII, and encoded secrets closes the gap where an agent dumps your database into an otherwise-legitimate Slack webhook.

Building the Allowlist: A Step-by-Step Playbook

Step 1: Observe before you enforce

Never start in blocking mode. Deploy the proxy in log-only mode for a representative window — typically one to two weeks across staging and a canary slice of production. The goal is a complete inventory of every host, method, and path your agents actually use. Agent G's wire-level logs give you this inventory without code changes, and you can stream them to Splunk, Datadog, or Sentinel for analysis.

You will be surprised. Most teams discover shadow dependencies: a telemetry SDK phoning home, a library fetching remote config, an LLM provider's secondary CDN domain. Capturing these now prevents a wave of false-positive blocks on day one.

Step 2: Derive rules from observed traffic

Turn the observed inventory into explicit allow rules, scoped as tightly as the data supports. For each destination, ask: which agent identity needs it, which methods, which paths, and what payload shape is legitimate? Express this as policy-as-code so it lives in Git, gets reviewed in pull requests, and ships through CI like any other infrastructure change.

A minimal rule in Agent G's policy model looks like this conceptually:

  • identity: rag-agent
  • allow: GET https://vectordb.internal/query
  • allow: POST https://api.openai.com/v1/* with body DLP scanning enabled
  • default: deny

Step 3: Switch to default-deny with escalation

Flip the final rule from log to deny. The critical design choice here is what happens when a request matches no allow rule. Three responses are useful:

  • Block outright for low-trust agents and high-risk methods.
  • Escalate to a human approver for ambiguous-but-plausible calls — this is where human-in-the-loop approval shines, letting a developer approve a new destination in seconds rather than blocking a legitimate workflow.
  • Flag and allow only during a controlled grace period, never as a permanent posture.

This tiering — auto-allow, flag, block, escalate — is what makes default-deny survivable in production instead of an outage generator. It is the same model that underpins zero-trust for AI agents: never trust a destination implicitly, verify every call.

Step 4: Handle the edge cases an LLM will find

Agents are creative. A robust allowlist anticipates the talk-arounds:

  • DNS as a side channel. If you allow arbitrary DNS resolution, an agent can tunnel data through subdomain queries. Inspect and constrain resolution at the proxy rather than trusting the resolver.
  • IP-literal connections. Block raw-IP destinations that bypass your domain rules unless explicitly allowed.
  • Redirects. An allowed host that 302-redirects to a denied one must be re-evaluated against policy, not followed blindly.
  • Encrypted payloads. Without TLS inspection, your body-level DLP is blind. Agent G performs TLS interception that inspects encrypted egress without breaking tool calls.

Why the LLM Can't Talk Around It

The defining property of a default-deny allowlist enforced on the wire is that it sits outside the agent's trust boundary. The LLM can be jailbroken, prompt-injected, fed a poisoned tool description, or convinced it is running in a test sandbox — and none of that changes the proxy's decision. The model's reasoning never touches the enforcement point.

This is the structural advantage of network-layer control over in-process guardrails. A library-based guardrail runs inside the same process the attacker is manipulating; bypass the library and the call still goes out. An egress proxy evaluates the actual packets after the agent has already decided to send them. The agent cannot argue with a TCP connection that gets dropped. For the full argument, see inference-boundary vs network-boundary AI security.

Operating the Allowlist Over Time

A default-deny posture is not set-and-forget; it is a living policy. Three operational habits keep it healthy:

  • Make adding a rule cheap. If approving a new destination is bureaucratic, developers will route around your proxy entirely. Keep the policy in version control and let pull requests carry the audit trail.
  • Review escalations as signal. A spike in escalations to a new domain is either a legitimate feature shipping or an agent being manipulated. Both deserve a human look.
  • Treat denials as observability. Every dropped request is a data point. A 403 behind your egress proxy is not always a bug — sometimes it is the system working exactly as intended.

Where Agent G Fits

Agent G implements this entire playbook as a drop-in egress proxy: identity-scoped allowlists, method- and path-level rules, body inspection for secrets and PII, TLS interception, human-in-the-loop escalation, and tamper-evident logging of every decision. You point your agents' outbound traffic at it, start in log-only mode, derive your allowlist from real traffic, and flip to default-deny — typically in an afternoon, with sub-2ms added latency.

Default-deny egress is the control that turns "we hope the agent behaves" into "the agent physically cannot reach anywhere we didn't approve." That is the difference between governance and enforcement.

Ready to lock down your agents' outbound path? Read the deployment docs, review pricing, or request access to start enforcing a default-deny allowlist your LLM can't talk around.

Agent G

Drop-in guardrails for the agentic era.

Intercept every network call your AI makes. Block destructive actions, enforce approvals, log everything.

Request access