Mesh Enforcement (Istio)
The Mitrity Mesh Authorizer governs agent traffic inside an Istio service mesh. It is a third deployment surface, next to Mitrity Gateway and Mitrity MCP Sidecar. Instead of wrapping an MCP server, it runs the same MITRITY decision engine at an Istio mesh decision point.
The same engine evaluates every governed request in the mesh. It checks:
- intent / mission-scope;
- agent-to-agent (A2A) delegation-chain state;
- threat-intel / injection;
- DLP.
When it allows a request, it applies mission-scoped credential injection.
Use the Mesh Authorizer when your agents and the tools they call already run as workloads in an Istio mesh. It lets you govern them without changing application code, and without routing traffic through a separate MCP gateway.
Same decision engine, a different decision point
Mitrity Gateway and Mitrity MCP Sidecar see MCP tools/call requests directly. There, the agent's identity is the agent_id it presents.
The Mesh Authorizer sits behind Istio's authorization layer instead. For every governed request, Istio calls it as an authorization provider on the destination's inbound sidecar. (The technical mechanism is Envoy ext_authz.) The Mesh Authorizer extracts the request, resolves which agent is calling, and runs the exact same governance pipeline as the other two binaries. Allow, deny and credential-injection behavior are identical. Only the integration point differs.
All three surfaces report to the same MITRITY control plane. So you get unified policy, audit and visibility, whichever surface enforces a given request. Each audit event is tagged with the surface that produced it, so you can tell mesh decisions apart from gateway and sidecar decisions.
The identity model: SPIFFE ServiceAccount to agent to policy
In a mesh with mutual TLS, every workload presents a verifiable SPIFFE identity, derived from its Kubernetes namespace + ServiceAccount. The Mesh Authorizer reads that identity from the request (source.principal) and resolves it to a MITRITY agent:
SPIFFE source.principal
spiffe://<trust-domain>/ns/<namespace>/sa/<service-account>
│
▼ (namespace + ServiceAccount → agent)
MITRITY agent
│
▼
that agent's mission profile + policy → allow / deny / inject credentials
This identity logic lives inside the Mesh Authorizer by design. The reason is an Istio constraint: Istio's CUSTOM authorization rules cannot match on source.principal (the caller's SPIFFE identity). So the work is split:
- in Istio, you select which workloads, ports and paths are governed;
- the Mesh Authorizer reads the SPIFFE identity itself, maps it to the bound agent and applies that agent's policy.
You bind a MITRITY agent to its mesh identity (namespace + ServiceAccount) in the dashboard. Per-Agent Identity in the Mesh describes the full binding workflow and the rules that make it work, including why STRICT mTLS is mandatory and why unmapped identities are denied by default.
What the Mesh Authorizer governs
The Mesh Authorizer covers two traffic surfaces:
East-west & agent-to-agent (A2A) traffic
This is the default coverage, and it is always on. It governs:
- East-west (agent → tool): an agent workload calls a tool or service workload inside the mesh.
- A2A (agent → agent): one agent workload calls another. A2A hops are also evaluated for delegation-chain state through the control plane, with cycle, depth and privilege-escalation checks.
Both are governed cleanly. The CUSTOM authorization filter fires on the destination's inbound sidecar, so the Mesh Authorizer sees both the caller's identity and the request.
Egress allowlist (outbound governance)
This capability is opt-in. It governs agent → external traffic against each agent's destination allowlist. It enforces each agent's list of approved outbound domains at the network layer (L3/L4), with the agent's identity intact. It denies egress to a host that is not on the allowlist, or to a host that threat-intel has flagged. Mesh Egress Allowlist explains how it works and how to enable it.
Capability and scope
The table below is the end-to-end statement of what the Mesh Authorizer enforces today. In the status column:
- "Enforced" means the decision blocks traffic;
- "Advisory" means the decision is recorded but does not block;
- "Deny-on-redact" means a DLP redact verdict becomes a deny, rather than a wire-level rewrite.
| Capability | Status at the Mesh Authorizer |
|---|---|
| Intent / mission-scope enforcement | Enforced (allow / deny) |
| A2A delegation-chain state | Enforced (allow / deny) |
| Threat-intel / injection on the tool identity | Enforced (allow / deny) |
| DLP: block action | Enforced (deny) |
| Mission-scoped credential injection | Active: on allow, broker-minted credentials are added as upstream headers |
| AIBOM (tool supply-chain risk) | Advisory-only: recorded on the decision trace; does not deny |
| DLP: redact action | Deny-on-redact (fail-closed) at the Mesh Authorizer. It cannot rewrite the request body on the wire, so a redact verdict becomes a deny. For LLM egress, pair it with the LLM Gateway in mesh mode, which terminates TLS and redacts on the wire in both directions |
| East-west / A2A coverage | Governed cleanly: the CUSTOM authorization filter fires on the destination's inbound sidecar |
| Egress destination/SNI allowlist | Enforced on the in-mesh egress path (opt-in): per-agent allowlist + threat-intel on the external host, with the agent's identity preserved |
What it does not do yet
The Mesh Authorizer has these boundaries:
- DLP on prompts / wire-redaction at the Mesh Authorizer is deny-only. The Authorizer is L3/L4 and does not terminate the agent's TLS, so it cannot rewrite a request body. A redact verdict fails closed to a deny. For LLM egress, body-level inspection and real redaction are available through the LLM Gateway in mesh mode, the in-mesh hop that terminates TLS. For arbitrary external HTTPS, they are not yet available. See Mesh Egress Allowlist.
- AIBOM is advisory at the mesh. Tool supply-chain risk is recorded on the decision trace, but it does not block.
- It does not govern raw external-HTTPS TLS-passthrough egress with per-agent identity. To keep an agent's identity on egress, you need an in-cluster hop that terminates TLS. Routing egress as raw passthrough is a validated dead end for identity-aware governance. See Mesh Egress Allowlist.
Requirements and supported versions
The Mesh Authorizer targets Istio sidecar mode, and it requires STRICT mTLS on every governed namespace. The key constraints:
- Tested on Istio 1.24 / Kubernetes 1.29. The in-mesh and egress end-to-end suites run against this version, and it is the version MITRITY stands behind.
- The API floor is Istio ≥ 1.20. That is the version in which
extensionProviders, the mechanism the Mesh Authorizer relies on, became generally available. Istio 1.20–1.23 and ≥ 1.25 are expected to work on the same API surface, but they are not in the test matrix. Validate them in staging before you rely on them. Do not assume "any 1.20+". - Istio ambient mesh (ztunnel + waypoints) is unsupported. The design assumes that a per-workload Envoy sidecar supplies the SPIFFE identity. Run governed namespaces in sidecar mode.
- STRICT mTLS is mandatory. Without mTLS, no SPIFFE identity is presented, and the Mesh Authorizer fails closed (deny). See Per-Agent Identity in the Mesh.
Deploy in Istio covers the full prerequisites, the Helm install and verification.
Related Documentation
- Deploy in Istio: the Helm install, mesh-wide registration, scoping and verification
- Per-Agent Identity in the Mesh: bind a MITRITY agent to its namespace + ServiceAccount
- Mesh Egress Allowlist: the opt-in egress allowlist for outbound traffic
- LLM Gateway: the mesh-mode L7 hop that governs LLM-provider egress (prompt/response DLP + redaction, model/token/cost/rate guardrails)
- Integration Modes: Mitrity Gateway and Mitrity MCP Sidecar
- Destination Allowlists: manage each agent's approved outbound destinations