Mesh Egress Allowlist
By default the Mitrity Mesh Authorizer governs traffic inside the mesh (east-west and agent-to-agent, or A2A). The mesh egress allowlist extends governance to traffic leaving the mesh: an agent calling an external host. It enforces each agent's approved-destination list at the network layer, with the agent's identity intact, and denies egress to a host that is not on that agent's allowlist (or a host flagged by threat-intel).
This capability is opt-in and off by default. Enable it when you want the same per-agent destination control the gateway and sidecar provide, applied to mesh-resident agents' outbound traffic.
What it enforces
The mesh egress allowlist governs agent → external traffic against the per-agent destination allowlist -- the same "approved outbound domains" list you manage in the dashboard for any agent. On each egress request it:
- Resolves the calling agent from its SPIFFE identity (namespace + ServiceAccount -- see Per-Agent Identity in the Mesh).
- Classifies the request as outbound.
- Checks the external host against that agent's destination allowlist.
- Allows the request if the host is on the allowlist; denies it if the host is not on the allowlist, or if threat-intel flags the host.
It is network-layer (L3/L4): it sees the agent identity and the destination host/SNI, but it does not terminate the agent's own TLS, so it does not inspect the egress body or prompt. Content inspection on egress -- prompt/body inspection and redaction for egress traffic (DLP on prompts / wire-redaction) -- is not yet available -- see Boundaries.
You manage the destination list itself in the dashboard, not here. This page is about turning egress enforcement on in the mesh; the allowlist entries, patterns, and the DLP events egress produces are documented under Destination Allowlists.
How per-agent identity survives egress
There is an important mechanism behind egress governance. Istio's CUSTOM authorization filter fires on the destination's inbound sidecar -- so for the Authorizer to see both the agent's identity and the external host, the egress has to reach an inbound sidecar that the Authorizer governs.
The proven path routes the agent's egress through an in-cluster egress hop over mesh mTLS (which preserves the agent's SPIFFE identity), and that hop terminates TLS in-mesh toward the upstream. Its inbound sidecar runs the egress authorization policy, so the Authorizer sees the agent identity and the real external host, resolves the agent, and enforces the allowlist on that host.
Why not just route raw external HTTPS straight out? Routing egress as raw TLS passthrough through an Istio egress gateway is a validated dead-end for identity-aware governance: on a real Istio cluster the authorization callout never reached the Authorizer (the passthrough handshake completed before any decision, and the agent's identity was not delivered). True external-HTTPS TLS-passthrough egress is destination/SNI-only at best and is not productionized. For per-agent egress governance, the egress hop must terminate TLS in-mesh -- the path above. Do not expect MITRITY to govern arbitrary passthrough egress with per-agent identity.
Enabling mesh egress enforcement
Mesh egress enforcement requires three things in place:
- Egress is locked down to a registry. Set Istio's outbound traffic policy to
REGISTRY_ONLYso external hosts are reachable only through declaredServiceEntrydestinations -- otherwise agents can bypass the hop. - An in-cluster egress hop that terminates TLS toward the upstream. Per-agent identity depends on this; a passthrough hop will not work (see above).
- The governed agents have a populated destination allowlist -- DLP enabled with their approved outbound destinations set in the dashboard.
Enable egress governance on the Mesh Authorizer Helm release and point it at your egress hop:
| Value | Effect |
|---|---|
istio.egress.enabled | master switch for the mesh egress allowlist (default false) |
istio.egress.hosts[] | the governed external hosts (host / port / protocol) -- one ServiceEntry is created per host |
istio.egress.inMeshEgressHost | the in-cluster egress hop the hosts route to (must terminate TLS for per-agent identity) |
istio.egress.authorizationPolicy.namespace | namespace of the egress hop workload |
istio.egress.authorizationPolicy.selector | required -- labels of the egress hop workload (not the agents) |
helm upgrade mitrity-mesh-authorizer \
oci://ghcr.io/mitrity-io/charts/mitrity-extauthz --version 0.12.0 \
--namespace mitrity-system --reuse-values \
--set istio.egress.enabled=true \
--set istio.egress.inMeshEgressHost=<your-in-mesh-tls-terminating-egress-host> \
--set istio.egress.authorizationPolicy.namespace=istio-system \
--set istio.egress.authorizationPolicy.selector.app=<egress-hop-workload-label>
Also set meshConfig.outboundTrafficPolicy.mode: REGISTRY_ONLY on your Istio install (mesh-wide config -- see Deploy in Istio) and declare each governed external host as a ServiceEntry routed to the egress hop.
Verifying egress enforcement
From a governed agent workload, an allowed external host should succeed and a host outside the allowlist (or a threat host) should be denied:
# An external host on the agent's allowlist -> ALLOW.
kubectl exec -n agents deploy/<some-agent> -c <app> -- \
curl -s -o /dev/null -w '%{http_code}\n' https://<allowlisted-host>/<path>
# A host NOT on the agent's allowlist -> DENY (403).
kubectl exec -n agents deploy/<some-agent> -c <app> -- \
curl -s -D - -o /dev/null https://<non-allowlisted-host>/<path>
A denied egress also produces an unauthorized_destination DLP event in the dashboard, with the agent's identity preserved -- see Destination Allowlists for the DLP event types and how to review them.
Governing LLM egress: the LLM Gateway as the hop
The in-cluster TLS-terminating egress hop this page keeps referring to is generic -- any workload that terminates the agent's TLS in-mesh and re-originates to the upstream. For LLM traffic specifically, that hop is the Mitrity LLM Gateway in mesh mode. Because it terminates the agent's TLS it does what the L3/L4 allowlist cannot: it reads the prompt and the model's response, applies DLP block and true wire-redaction in both directions, and enforces the per-policy model allowlist, token caps, cost budgets, and rate limits -- per agent, resolved from the same SPIFFE (namespace, ServiceAccount) identity. One centralized gateway serves the whole fleet (it authenticates as your environment's mesh-edge credential).
This gives the mesh two complementary surfaces on one decision engine:
| Surface | Traffic | Depth |
|---|---|---|
| Mesh Authorizer (this page) | east-west, A2A, and coarse egress to arbitrary hosts | L3/L4 -- identity + destination/SNI allowlist + threat-intel |
| LLM Gateway (mesh mode) | the LLM-provider egress data path | L7 -- prompt/response DLP + redaction, model allowlist, token/cost/rate guardrails |
Forcing LLM egress through the gateway (no bypass)
Body-level LLM governance only holds if agents cannot reach the provider directly. Compose it with the egress lockdown this page already describes:
- Deploy the LLM Gateway in mesh mode as the in-cluster hop (it terminates TLS and re-originates to Anthropic / OpenAI).
- With
outboundTrafficPolicy.mode: REGISTRY_ONLY, declare each LLM-provider host (api.anthropic.com,api.openai.com, and any others you use) as aServiceEntryrouted to the gateway hop -- not straight out. - Keep those provider hosts off the agents' own destination allowlists, so a direct-to-provider call the Mesh Authorizer sees is denied.
The result: an agent's LLM call reaches the provider only through the gateway, where it is fully governed, whether the agent points its base_url at the gateway explicitly or is transparently routed there by the ServiceEntry. An attempt to skip the hop and dial the provider directly is denied at the network layer.
Boundaries
The mesh egress allowlist is honest about its limits:
- Network-layer only. It enforces a per-agent destination / SNI allowlist (plus threat-intel on the destination) at L3/L4, with the agent's identity. It does not terminate the agent's TLS, so it does not inspect the egress body or prompt.
- Body-level egress governance is LLM-specific today. Prompt/body inspection and redaction on egress require in-mesh TLS termination of the agent's own traffic. For LLM egress that hop exists -- the LLM Gateway in mesh mode (see above). For arbitrary external HTTPS, body inspection is not yet available and a DLP redact verdict fails closed to a deny.
- Raw external-HTTPS passthrough egress is not governed per-agent. Per-agent identity requires the in-cluster TLS-terminating hop, as described above.
Related Documentation
- Destination Allowlists -- manage each agent's approved outbound destinations and review egress DLP events
- Mesh Enforcement (Istio) -- the concept and capability table
- Deploy in Istio -- install, mesh-wide config, and scoping
- Per-Agent Identity in the Mesh -- how the agent's identity is resolved