AI Egress Control Implementation: Allowlisting the Destination Does Not Govern the Payload
Teams implement AI egress control with DNS filtering, SNI inspection, forward proxies, Kubernetes NetworkPolicy, and Cilium FQDN rules. Each governs the destination of AI traffic without reading the prompt, and Kubernetes NetworkPolicy cannot express FQDNs at all. This article gives working Cilium and Envoy egress config, explains why each layer stops at the destination, and shows why reading the payload requires sitting on the decrypted HTTP path.

Egress control for AI traffic starts with a list of destinations. A platform team allowlists the provider API hostnames its workloads are permitted to reach, and blocks the rest. That list is longer than most teams expect:
Getting this list right is the start of egress control and not the finish. Every mechanism a team reaches for governs the destination of AI traffic, and the destination is not the thing that leaks. I want to walk the implementations engineers actually deploy, show working config for the two that matter most, and be precise about where each one stops.
Why IP allowlisting is the wrong primitive
The instinct to allowlist by IP fails on the first provider you try. Anthropic publishes fixed IP ranges, but they are for Anthropic's own inbound endpoint at 160.79.104.0/23 and its outbound tool calls at 160.79.104.0/21. They are not the addresses you reach when you call api.anthropic.com, which resolves to Cloudflare anycast in the 104.18.x.x space that rotates. Pin an IP allowlist to the API endpoint and it breaks when the anycast address moves, which is why the vendor itself steers you to domain-based filtering. AI endpoints live behind CDNs, and CDN addresses are not stable allowlist entries.
The destination-layer mechanisms, and where each stops
Every control below decides whether a request may reach a host. None reads the prompt.
DNS filtering blocks resolution of non-allowlisted names. It is bypassed by hardcoded IPs and by DNS-over-HTTPS, and it sees a hostname, never a payload.
SNI-based filtering reads the server name in the TLS ClientHello. It cannot see prompt content because the handshake carries none, and Encrypted Client Hello blinds it entirely, leaving passive inspection with only a cover domain. The CDT writeup on ECH is the clearest primer on why SNI inspection is a shrinking control.
A CONNECT-tunnel forward proxy such as Squid, without interception, sees the CONNECT target host and then tunnels end-to-end TLS it cannot read. To read the body you have to SSL-bump, terminating TLS with a corporate CA, and Squid's own peek-and-splice constraints mean peeking at the server certificate can foreclose bumping the connection.
TLS interception with a corporate CA is the only network-layer way to see the prompt body. The cost is that you now decrypt and re-encrypt all AI traffic, distribute a CA to every client, and inherit certificate-pinning and ECH breakage.
Kubernetes NetworkPolicy deserves its own callout because engineers reach for it first and it cannot do the job. NetworkPolicy expresses egress as CIDR and IP only, with no FQDN selector. Provider hostnames move IPs, so plain NetworkPolicy is structurally wrong for allowlisting AI providers, and the standards gap is tracked in NPEP-133.
Working config: Cilium FQDN egress
Cilium closes the FQDN gap with a DNS proxy that watches DNS answers and programs the resolved addresses. The load-bearing detail, from Cilium's DNS-based policy docs, is that every FQDN rule needs a companion DNS rule to kube-dns or name resolution fails:
Two correctness notes that bite people: matchPattern: "*.openai.azure.com" does not match the bare apex openai.azure.com, because *. requires a subdomain label, and without the DNS allow rule the pod cannot resolve the name it is otherwise permitted to reach. This is a real destination allowlist. It still reads no prompt content.
Working config: Envoy egress cluster
An Envoy egress cluster to a provider needs DNS-based endpoint discovery and TLS origination with the correct SNI:
Set sni or the provider's TLS routing fails, and configure validation_context or the connection is encrypted while the upstream certificate goes unverified. Envoy on the egress path can terminate TLS, which puts you on the decrypted HTTP path where payload inspection becomes possible. That is the transition point this whole article is building toward.
The problem allowlisting never solves
Allowlisting api.openai.com proves the destination is sanctioned. It says nothing about what leaves in the body. A permitted domain is still a live exfiltration channel: PII, source code, secrets, and a poisoned prompt all ride the same allowed TLS session to the same allowed host. DNS, SNI, and CONNECT controls terminate at the destination decision, and none of them reads the JSON request body.
The only layers that inspect payload are a TLS-terminating L7 proxy or a MITM interception point. Both require sitting on the decrypted HTTP path. This is the architectural line between egress control and egress governance: the network stack decides where traffic may go, and only something on the decrypted request can decide what may leave inside it. Destination allowlisting is necessary and is not sufficient, which is why monitoring AI egress at the network layer alone leaves the payload ungoverned.
DeepInspect
This is the gap DeepInspect closes. Your Cilium and Envoy egress rules decide which provider hosts a workload may reach. DeepInspect decides what may leave inside the request to those hosts.
DeepInspect is a stateless proxy on the AI request path. It terminates the AI request, so it sits on the decrypted HTTP payload rather than the encrypted tunnel, binds the call to the identity the application supplies, classifies the prompt content across PII, PHI, MNPI, source code, and jurisdictional categories, and applies a pass, block, or modify decision before the request reaches the permitted destination. It commits a signed record of that decision. The network layer keeps doing its job of constraining destinations, and DeepInspect adds the payload governance that destination allowlisting structurally cannot provide, inline and fail-closed. Book a demo today.
Frequently asked questions
- Why not just allowlist provider IP addresses?
Because AI endpoints sit behind CDNs with rotating addresses. Anthropic's published IP ranges, for example, are for its own inbound and outbound tool endpoints, not for reaching
api.anthropic.com, which resolves to Cloudflare anycast that changes. An IP allowlist pinned to an API endpoint breaks when the address moves. Domain-based filtering is what the providers themselves recommend, which is why Cilium FQDN rules and Envoy DNS clusters are the right primitives rather than static IP sets.- Can Kubernetes NetworkPolicy allowlist AI providers?
Not by hostname. NetworkPolicy expresses egress as CIDR and IP ranges only, with no FQDN selector, and provider hostnames move IPs, so a plain NetworkPolicy is structurally unable to allowlist AI providers reliably. Cilium extends this with
toFQDNs, backed by a DNS proxy that programs the resolved addresses, and it requires a companion DNS rule to kube-dns. The FQDN gap in the base API is tracked in NPEP-133 but is not yet a stable NetworkPolicy feature.- Does SNI or DNS filtering see the prompt?
No. DNS filtering sees the hostname being resolved, and SNI filtering sees the server name in the TLS handshake. Neither carries prompt content, so neither can tell whether a request to a permitted provider contains source code, PII, or secrets. Encrypted Client Hello further blinds SNI inspection by hiding the real server name behind a cover domain. Reading the prompt requires terminating TLS and inspecting the decrypted HTTP body.
- What does allowlisting a provider domain actually protect against?
It constrains where AI traffic can go, which blocks a workload from reaching an unsanctioned or malicious endpoint and reduces the destination surface. That is worthwhile. What it does not do is govern the content of requests to sanctioned providers, so an allowed domain remains a channel through which sensitive data can leave. Destination control and payload governance are two different layers, and a defensible egress posture runs both.
- How do I inspect the payload without breaking everything?
You have to sit on the decrypted HTTP path, either through a TLS-terminating L7 proxy or a MITM interception point. A purpose-built AI gateway terminates the AI request specifically, so it inspects the prompt body without imposing full-estate TLS interception on unrelated traffic. It classifies the request content, applies policy, and forwards to the destination your egress rules already permit. That keeps the network controls doing destination enforcement and adds payload governance only where AI traffic actually flows.