New: Agent approvals, red teaming and model scanning. See how
MITRITY
Docs / Gateway, Sidecar & Mesh / Mesh Enforcement (Istio)

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.
CapabilityStatus at the Mesh Authorizer
Intent / mission-scope enforcementEnforced (allow / deny)
A2A delegation-chain stateEnforced (allow / deny)
Threat-intel / injection on the tool identityEnforced (allow / deny)
DLP: block actionEnforced (deny)
Mission-scoped credential injectionActive: 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 actionDeny-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 coverageGoverned cleanly: the CUSTOM authorization filter fires on the destination's inbound sidecar
Egress destination/SNI allowlistEnforced 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.