New: Agent approvals, red teaming and model scanning. See how
MITRITY
Docs / Gateway, Sidecar & Mesh / Mesh Egress Allowlist

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, when an agent calls an external host. It enforces each agent's approved-destination list at the network layer, with the agent's identity intact. It denies egress to a host that is not on that agent's allowlist, or to a host that threat-intel has flagged.

This capability is opt-in and off by default. Enable it when you want the same per-agent destination control that the gateway and sidecar provide, applied to the outbound traffic of agents in the mesh.

What it enforces

The mesh egress allowlist governs agent → external traffic against the per-agent destination allowlist. That is the same "approved outbound domains" list that you manage in the dashboard for any agent. On each egress request, it:

  1. resolves the calling agent from its SPIFFE identity (namespace + ServiceAccount; see Per-Agent Identity in the Mesh);
  2. classifies the request as outbound;
  3. checks the external host against that agent's destination allowlist;
  4. allows the request if the host is on the allowlist, and denies it if the host is not on the allowlist or if threat-intel flags the host.

It works at the 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 is not yet available. That covers prompt/body inspection and redaction for egress traffic, also called DLP on prompts / wire-redaction. 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, the patterns and the DLP events that egress produces are documented under Destination Allowlists.

How per-agent identity survives egress

Egress governance depends on one important mechanism. 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 works like this:

  1. The agent's egress goes through an in-cluster egress hop over mesh mTLS, which preserves the agent's SPIFFE identity.
  2. That hop terminates TLS in-mesh, toward the upstream.
  3. The hop's 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. External-HTTPS TLS-passthrough egress is destination/SNI-only at best, and it is not productionized. For per-agent egress governance, the egress hop must terminate TLS in-mesh, as in 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:

  1. Egress is locked down to a registry. Set Istio's outbound traffic policy to REGISTRY_ONLY, so that external hosts are reachable only through declared ServiceEntry destinations. Otherwise, agents can bypass the hop.
  2. An in-cluster egress hop that terminates TLS toward the upstream. Per-agent identity depends on it, and a passthrough hop will not work (see above).
  3. 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:

ValueEffect
istio.egress.enabledmaster 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.inMeshEgressHostthe in-cluster egress hop the hosts route to (must terminate TLS for per-agent identity)
istio.egress.authorizationPolicy.namespacenamespace of the egress hop workload
istio.egress.authorizationPolicy.selectorrequired: 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. This is mesh-wide config; see Deploy in Istio. Then declare each governed external host as a ServiceEntry routed to the egress hop.

Verifying egress enforcement

From a governed agent workload, a call to an allowed external host should succeed. A call to a host outside the allowlist, or to 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 that this page keeps referring to is generic. It is 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, the LLM Gateway does what the L3/L4 allowlist cannot. Per agent, resolved from the same SPIFFE (namespace, ServiceAccount) identity, it:

  • reads the prompt and the model's response;
  • applies DLP block and redaction on the wire, in both directions;
  • enforces the per-policy model allowlist, token caps, cost budgets and rate limits.

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:

SurfaceTrafficDepth
Mesh Authorizer (this page)east-west, A2A, and coarse egress to arbitrary hostsL3/L4: identity + destination/SNI allowlist + threat-intel
LLM Gateway (mesh mode)the LLM-provider egress data pathL7: 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. Combine it with the egress lockdown that this page already describes:

  1. Deploy the LLM Gateway in mesh mode as the in-cluster hop. It terminates TLS and re-originates to Anthropic / OpenAI.
  2. With outboundTrafficPolicy.mode: REGISTRY_ONLY, declare each LLM-provider host (api.anthropic.com, api.openai.com, and any others you use) as a ServiceEntry routed to the gateway hop, not straight out.
  3. Keep those provider hosts off the agents' own destination allowlists, so that a direct-to-provider call the Mesh Authorizer sees is denied.

As a result, an agent's LLM call reaches the provider only through the gateway, where it is fully governed. That holds whether the agent points its base_url at the gateway explicitly, or the ServiceEntry routes it there transparently. An attempt to skip the hop and dial the provider directly is denied at the network layer.

Boundaries

The mesh egress allowlist has these 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.