soft guideINFRASTRUCTURE & ADVISORY

Case study 02

One way out to the internet

Every outbound connection from a cluster leaves through a single gateway that allowlists hostnames, behind three independent fences: routing, CNI policy and an L7 proxy.

Role
Designed the egress model: an allowlisting proxy as the only exit for CI runners and cluster control traffic, FQDN policies for workloads. The baseline extends the same exit to every pod and node.
Available as
Secure package · also sold on its own
Application podPrivate tier, no route outEgress gatewayEnvoy CONNECT · allowlist · 403 logNAT → InternetFixed source IPslabel opt-inallowlisteddirect to the internet: no route, dropped by policy, refused by the security groupFENCE 1 · ROUTE TABLEFENCE 2 · CILIUM toFQDNsFENCE 3 · ENVOY ALLOWLIST

The problem

In most clusters any pod can open a connection to anywhere. Exfiltration, a cryptominer or a compromised dependency calling home needs nothing more. Network policies alone are one mistake away from open: a broad rule, a missing selector, an agent left in audit mode.

The approach

Node and pod subnets have no default route. Only a dedicated egress tier routes to NAT, and only the egress gateway runs there. The gateway is an Envoy CONNECT proxy that forwards allowlisted host:port pairs and answers everything else with a 403 and a log line. Around it, a Cilium toFQDNs policy repeats the allowlist at the CNI layer, and a security group lets only that tier send HTTPS out of the VPC. AWS APIs go through VPC endpoints and never touch the gateway.

The details that matter

Wildcards only for a vendor's own zone, never a public suffix or a multi-tenant storage domain: those are exfiltration channels, not allowlist entries. Nodes pull container images through the same gateway, so even image pulls follow the policy. The allowlist doubles as documentation of everything the platform talks to.

What changed

Leaving the network became a decision someone reviews, not a default. A new external dependency is a one-line change in a pull request, and an unexpected destination shows up as a 403 and a dropped flow instead of a successful connection.

Described as a pattern: names, numbers of systems and identifiers from the environments where this was built are left out.

Start a conversation

Bring your infrastructure
into focus.

Tell me what you are building, operating, or trying to improve.

Let’s talk