On June 23, 2026, Tetrate announced that Envoy AI Gateway reached v1.0 — the first AI gateway built directly on the CNCF's Envoy Gateway project, with its core CRDs declared stable after 16 months of Bloomberg and Nutanix running it against real production traffic. Buried in that release is a detail that matters more to anyone running their own MCP server than the headline "AI gateway" framing suggests: MCPRoute and MCPRouteSecurityPolicy graduated to stable alongside it, shipping CEL-based per-tool authorization and per-tool observability as production-hardened, not experimental, primitives.
That's the concrete thing this post is about: what those two CRDs actually let you write, and whether they're enough to skip building a custom MCP authorization layer for a platform that exposes tools like deploy, rollback, or get_logs to AI agents.
The project's origin story explains why the MCP layer is as production-hardened as it is. Bloomberg proposed the effort to the Envoy Gateway community to solve its own problem — routing generative-AI traffic with the same reliability and governance guarantees Envoy already gave its regular service mesh — and has been running the result in production since. Nutanix joined for the same reason and is now folding it into Nutanix Agent Gateway and Nutanix Enterprise AI. That's a materially different bar than a project reaching 1.0 on roadmap momentum alone: the CEL rule engine and the tool-filtering logic below were exercised against real tenant traffic for over a year before the API was frozen.
What Actually Shipped at v1.0
Envoy AI Gateway's stable API surface, all served at v1beta1 with a commitment not to break it outside a critical CVE fix, is six CRDs:
| CRD | Job |
|---|---|
AIGatewayRoute | Routes LLM chat/completions traffic to one or more backends, with token-aware load balancing |
AIServiceBackend | Declares an upstream model provider (OpenAI-compatible, Bedrock, self-hosted vLLM, etc.) |
BackendSecurityPolicy | Attaches credentials (API keys, IAM roles) to a backend without putting secrets in the route |
GatewayConfig | Gateway-wide settings (rate limiting, failover) |
MCPRoute | Routes MCP requests to one or more backend MCP servers, with streamable-HTTP transport and JSON-RPC 2.0 |
MCPRouteSecurityPolicy | Applies OAuth 2.0 and CEL-based authorization to an MCPRoute |
The last two are the ones worth stopping on. MCPRoute can multiplex several backend MCP servers behind a single client-facing endpoint — a client connects once and sees a merged tool list — and it does spec-compliant OAuth 2.0 with JWKS validation and Protected Resource Metadata out of the box. MCPRouteSecurityPolicy is where the authorization logic lives, and it's the piece a hand-rolled MCP server almost never gets right on the first attempt: filtering, forwarding, and per-call policy.
The Mechanics: Tool Filtering, JWT Forwarding, and CEL Rules
Three things happen at the MCPRouteSecurityPolicy layer, in order, for every MCP request:
- Tool filtering on
tools/list. Include/exclude rules mean a caller'stools/listresponse only ever contains tools they're allowed to see — an agent that shouldn't knowrollbackexists doesn't get it listed, it isn't just blocked from calling it after the fact. - OAuth 2.0 JWT claim forwarding. The gateway validates the caller's JWT and forwards its claims to the backend MCP server, so the server-side tool handler can see who's calling without re-implementing token validation itself.
- CEL-based authorization on
tools/call. Rules are evaluated in order — first match wins — against three fields:Target(which tool),Source(which client/identity), and a CEL boolean expression evaluated against the request and JWT claims. The first matching rule's action (Allow/Deny) applies; if nothing matches,defaultActiondecides.
Concretely, restricting a rollback tool to on-call engineers acting against non-production environments looks like this:
apiVersion: aigateway.envoyproxy.io/v1beta1
kind: MCPRouteSecurityPolicy
metadata:
name: platform-mcp-policy
spec:
targetRefs:
- name: platform-mcp-route
rules:
- target: rollback
source: "*"
cel: "jwt.claims.role == 'oncall' || request.args.environment != 'production'"
action: Allow
- target: rollback
source: "*"
cel: "true"
action: Deny
defaultAction: DenyThe first rule allows rollback when the caller's JWT carries an oncall role claim, or the target environment isn't production; anything else matching rollback falls through to an explicit deny; and any tool not mentioned at all is denied by defaultAction. That's a policy an agent-facing deploy tool needs on day one — and it's declarative YAML sitting in front of the MCP server, not a switch statement inside its handler code that has to be re-audited every time a new tool is added.
Per-tool observability rides on the same request path: every tools/call emits OpenTelemetry GenAI-semantic-convention spans and OpenInference traces, so "which agent called which tool, with what arguments, and did the policy allow it" is a trace query rather than something you have to instrument by hand inside each tool handler.
Two details matter for anyone about to write these rules for real. First, rule order is significant and there's no automatic "most specific wins" resolution — the deny-everything-else rule for rollback in the example above has to come after the conditional allow, or it shadows it. Second, defaultAction: Deny is the only safe default for a deploy-tool gateway; leaving it at Allow (or omitting it, since an unset default is effectively permissive) means every tool added to the backend MCP server in the future is reachable by every caller until someone remembers to write a rule for it. A platform's CI for its own MCPRouteSecurityPolicy should treat "new tool has zero matching rules" as a merge-blocking check, not a runtime surprise.
Where This Overlaps — and Doesn't — With MCP's Own EMA Extension
The Model Context Protocol's Enterprise-Managed Authorization (EMA) extension went stable around the same time, and it's easy to mistake it for a competing standard. It isn't — it solves a different layer of the same problem. EMA is about connection-level identity: a client gets an Identity Assertion JWT Authorization Grant (ID-JAG) from the organization's IdP during SSO and exchanges it for access to an MCP server, with no per-server consent screen. Anthropic, Microsoft, Okta, and servers like Asana, Atlassian, Figma, and Linear already support it. That answers "is this user/client allowed to connect to this MCP server at all."
Envoy AI Gateway's MCPRouteSecurityPolicy answers the next question down: given a connected, authenticated caller, is this specific tool call, against this specific target, allowed right now? EMA can hand the gateway a JWT with clean identity claims; the CEL rules decide what that identity can actually do once inside. The two compose — EMA at the front door, CEL policy at every tool call — rather than one replacing the other. That's also the meaningful contrast with Snowflake's May 2026 acquisition of Natoma, which folds a similar per-tool-call policy layer into a paid control-plane product: Envoy AI Gateway ships the same shape of governance as CNCF-hosted, Apache-licensed infrastructure you run yourself, not a capability you buy access to.
What This Buys a Self-Hosted, Deploy-From-Chat PaaS
A platform that lets AI agents call deploy, rollback, scale, or get_logs through its own MCP server has, until now, had to build three things from scratch to do this safely: a rule engine deciding which identity can call which tool under which condition, a per-call audit trail, and a tools/list filter so agents don't even see actions they can't take. MCPRoute plus MCPRouteSecurityPolicy deliver all three as CRDs running in front of the MCP server, with the hardening of 16 months of Bloomberg production traffic behind them — Bloomberg is running it live, and Nutanix is folding it into Nutanix Agent Gateway and Nutanix Enterprise AI, which is a different level of battle-testing than a platform team's first attempt at the same logic.
What it doesn't remove is the platform-specific mapping work: something still has to turn a platform's own users, teams, and service accounts into the JWT claims the CEL rules key off (role, environment, team), and the MCP server's tool handlers still need to enforce tenant scoping on the resources those tools touch — the gateway authorizes which tool, not which tenant's data that tool call may read. Adopting it also means running Envoy Gateway and Kubernetes Gateway API CRDs at all, which is a real prerequisite for a platform not already on that stack, not a zero-cost drop-in. For a platform already running Cluster API and a Kubernetes-native ingress layer, though, the honest accounting is: identity mapping and tenant scoping were always platform-specific work, but the policy engine, the audit trail, and the tool-visibility filter no longer have to be built in-house at all.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own, with AI agents as first-class operators through an MCP server. Star the repo on GitHub or deploy your first app today.
Sources
- Envoy AI Gateway Reaches v1.0, Establishing the Open Source Standard for Enterprise AI Traffic — PR Newswire
- Announcing Envoy AI Gateway 1.0 — A Stable, Production-Ready AI Gateway
- Envoy AI Gateway v1.0 — General Availability Release Notes
- Envoy AI Gateway Reaches 1.0: A Stable Foundation for Enterprise AI Traffic — Tetrate
- Model Context Protocol (MCP) Gateway — Envoy AI Gateway Docs
- Enterprise-Managed Authorization: Zero-touch OAuth for MCP — Model Context Protocol Blog
- AI Model Context Protocol Adds Centralised Auth for Enterprise — InfoQ
- Install with Helm — Envoy Gateway Docs