The Mesh Calls Out, and Nobody Is Listening

On the inside, your mesh is now Zero Trust: mTLS on STRICT, default on deny. And towards the outside? There it calls whoever it wants.

Date
Topic
Egress
Sources
3
Reading time
2 min
Version
Translation

Read the German original

outboundTrafficPolicy is set to ALLOW_ANY out of the box. The sidecar simply lets traffic to unknown external destinations pass through. Every library that calls a license server, every forgotten webhook: everything goes out, none of it is in any inventory. In an incident, you cannot even say what normal would look like.

Graphic: OMNI52 Open the figure at full size
Figure as text

Side-by-side comparison of two egress operating modes: on the left, ALLOW_ANY as the factory setting, a workload with a sidecar from which red dashed arrows lead to unnamed external destinations (a library's license server, a forgotten webhook, nobody knows); on the right, REGISTRY_ONLY as a forced inventory, with three labeled paths to ServiceEntry entries for the payment API, SSO and telemetry. Below, the three ServiceEntry hygiene classics: protocol HTTP where TLS is actually running; resolution NONE where DNS belongs; wildcard hosts that keep the inventory from being one.

REGISTRY_ONLY turns this around. The sidecar only knows what is in the registry, and every external destination needs a ServiceEntry. That is less a security feature than a forced inventory: for the first time, someone has to write down which destinations the system talks to, and the catalog lives in Git as YAML.

The catalog is only as good as its upkeep. I keep seeing three mistakes: a port declared as http where TLS runs over it, and then the proxy fails on traffic it is supposed to understand. resolution: NONE where DNS belongs, and then the sidecar routes blindly to whatever address the application asks for. And host patterns so broad that the inventory stops being one. A wildcard on an entire domain is not an entry, it is a shrug.

Ownership along the line from reports #4 and #6: a ServiceEntry with local effect belongs to the tenant who needs the destination. Mesh-wide approvals belong to the platform. And against the dead ServiceEntries from report #3, the only thing that helps is one owner per entry who is also allowed to delete it again.

For decision makers, it is a single question: does the list of all external dependencies exist, and who approved it? ALLOW_ANY means the list does not exist.

The reflex at this point is almost always the same: “Then we will build an egress gateway in front of it.” Why that alone is not a security concept is the topic for next week.

About the author

Portrait of Uli Renz

Uli Renz has been building and hardening service meshes in highly regulated enterprise environments since Istio 1.4. The patterns in these reports come from that work.

If your mesh already runs in production, the Posture Check is the place to start: 13 review areas, each finding rated by severity and backed by evidence from the config. In 90 minutes we go through the list together.

Request a strategy call

The request form on istio-consulting.de is in German.