Key Takeaway
Envoy AI Gateway became Agent Router on 10 September 2026 and joined the Agentic AI Foundation, with no change to its CRDs, aigw CLI or API group. Version 1.2 is the real change: MCP authorization now fails closed, sessions bind to their user, and cross-namespace credentials need a ReferenceGrant.
I opened the rename announcement expecting a migration guide. What I found was a promise instead: your manifests from yesterday apply tomorrow. For a gateway that holds provider API keys and fronts MCP tools, nothing changes is the sentence I trust least, so I read the 1.2 release notes line by line to find out what it left out.
This post covers the rename and the foundation move, the 1.0 stability promise, the July per-user identity design, and the 1.2 changes to MCP authorization and multi-team credentials. I did not run 1.2 in a cluster for this post. Everything is read from the project's own announcements, release notes and docs, and where I assemble a config myself I say so.
The rename changed the name, not the API surface
On 9 September 2026 the maintainers announced that Envoy AI Gateway becomes Agent Router, effective 10 September. Their summary is three short sentences: same code, same maintainers, new home. The table lists what I could confirm from the announcement and from the 1.2.0 release notes.
| Item | Before the rename | After the rename |
|---|---|---|
| Product name | Envoy AI Gateway | Agent Router (the post says prose only) |
| Repository | envoyproxy/ai-gateway | theagentrouter/agent-router, old links redirect |
| Website | aigateway.envoyproxy.io | theagentrouter.ai, old links redirect to the same pages |
| CRDs and API group | AIGatewayRoute, AIServiceBackend, BackendSecurityPolicy under aigateway.envoyproxy.io | Unchanged |
| CLI and namespace | aigw and envoy-ai-gateway-system | Unchanged |
| Helm charts and images | ai-gateway-helm and ai-gateway-crds-helm on docker.io/envoyproxy | Same names in 1.2.0; the notes say the ai-gateway prefix is kept |
| Governance | Envoy sub-project within the CNCF, per the announcement | Standalone project in the Agentic AI Foundation; Apache 2.0 licence and weekly meeting continue |
The consequence is practical. Nothing in a GitOps repository needs editing for the rename, and the Helm commands in your pipelines keep working. What does need a sweep is documentation and scripts that link to the old repository or website. Redirects cover them for now, but a link you control is better than a redirect you depend on.
Why a foundation move, and which foundation
The Linux Foundation announced the Agentic AI Foundation on 9 December 2025 with three founding projects: Anthropic's Model Context Protocol, Block's goose and OpenAI's AGENTS.md. Its platinum members at launch were Amazon Web Services, Anthropic, Block, Bloomberg, Cloudflare, Google, Microsoft and OpenAI. The stated aim is a neutral, open home for agentic AI.
The rename post says the project began as an Envoy sub-project within the CNCF and is becoming a standalone project under the Agentic AI Foundation, which it describes as the home of the agentic stack. It does not give a more detailed reason, so the next sentence is my inference: a gateway whose most important job is MCP traffic now sits in the same foundation as MCP itself. It is still built on Envoy and Envoy Gateway, so the data plane is the same one you already run.
A Korean-language write-up describes Agent Router as the second gateway in the foundation, next to agentgateway, a Rust data plane, and says the practical difference is that Agent Router is a control plane that configures Envoy. I treat that as a third-party comparison. One claim in it I could check against the official docs: authorization CEL can read tool arguments through request.mcp.params.
What 1.0 promised before the rename
Version 1.0 shipped on 23 June 2026 as the first stable release. The five CRDs, AIGatewayRoute, AIServiceBackend, BackendSecurityPolicy, GatewayConfig and MCPRoute, are served at v1beta1, and the stated commitment is blunt: the APIs will never break unless there is a critical security issue. The 1.0 post counts 16 AI providers, a full MCP gateway and multimodal support.
Read that promise precisely. It covers the shape of the API, and several of the 1.2 breaking changes are behaviour and validation changes inside a stable shape: a CRD rule that now rejects an expression, a policy that now honours a namespace. The 1.0 post publishes no benchmark numbers and no Envoy Gateway or Kubernetes compatibility matrix, so the 1.2 release notes are where the version constraints actually live.
Per-user identity: the July design behind the 1.2 work
The 5 July post starts from a failure every MCP rollout meets. Teams begin with one shared service account per tool, kept as a Kubernetes Secret, so comments post under the bot's name, users reach data their own accounts cannot, and downstream RBAC is bypassed with no visible error. The post separates two questions: does the gateway trust the request, and whose identity does the backend see. The table is its answer to the second.
| Pattern | Per-user RBAC | New infrastructure | Best for |
|---|---|---|---|
| Shared service account | No | None | Tools without per-user permissions |
| Header forwarding | Yes | None | The user's credential already works downstream |
| Client credentials (OAuth) | Fixed scope only | App registration | An agent acting as itself |
| Token exchange (RFC 8693) | Yes | Security token service and trust config | Identity across an identity provider boundary |
Header forwarding is opt-in. The MCP proxy builds a fresh upstream request for every call and does not forward client headers by default; a backend receives only the headers listed in its forwardHeaders. During fan-out, such as a tools/list call, each backend still gets only its own opted-in headers. One trap is spelled out: credentials injected by a backend's securityPolicy overwrite forwarded headers with the same name, so give forwarded user identity its own header.
The trade-off is stated plainly in the post. Passthrough keeps no token vault, so there is nothing to store, rotate or breach, but revocation is not central because the client platform holds the credential. And the gateway does not validate a personal access token; the backend does, so keep inbound authentication at the front door or the gateway becomes an open proxy. Token exchange was still in review at the time and remains on the 1.2 what's-next list.
1.2 hardening: MCP authorization that fails closed
The 1.2 announcement groups the MCP work under one idea, put tools in front of real users. Authorization rules read JWT claims only from tokens Envoy has verified, and the issuer must match the configured one. A CEL policy that errors at runtime now denies the call instead of being skipped. A session is bound to the user who started it, so another user cannot reuse its session ID. And the Helm chart generates a random session encryption seed instead of shipping a shared default.
The release notes show where this bites. Claims, scopes and the session subject come only from a JWT Envoy verified, so without securityPolicy.oauth they are empty. New CRD validation rejects authorization or backendSelector CEL that references auth.jwt on such a route. Existing routes keep their stored spec, but every later update is rejected, claim lookups fail and deny, and scope checks evaluate to false. The configuration below is my assembly of fields from the docs and notes, not a published example.
apiVersion: aigateway.envoyproxy.io/v1beta1
kind: MCPRoute
metadata:
name: issues
namespace: default
spec:
parentRefs:
- name: envoy-ai-gateway
kind: Gateway
group: gateway.networking.k8s.io
path: "/mcp"
prefixMode: Never # clients see search_issues, not github__search_issues
securityPolicy:
mergeType: StrategicMerge # keep gateway-level rate limits and ext-auth in force
oauth:
# Must equal the identity provider's iss claim byte for byte,
# including a trailing slash. A mismatch is a 401 after 1.2.
issuer: "https://keycloak.example.com/realms/master"
audiences:
- "https://api.example.com/mcp"
protectedResourceMetadata:
resource: "https://api.example.com/mcp"
scopesSupported: ["profile", "email"]
authorization:
rules:
- source:
jwt:
scopes: ["read"]
target:
tools:
- backend: github
tool: search_issues
# An erroring expression now DENIES. Guard the claim with has()
# so a missing claim is a deliberate no, not an accident.
cel: has(request.auth.jwt.claims.tenant) && request.headers["x-tenant-id"] == request.auth.jwt.claims.tenant
backendRefs:
- name: github
kind: Backend
group: gateway.envoyproxy.io
path: "/mcp"
toolSelector:
include: ["search_issues"] # required for a backend in Never mode
forwardHeaders:
- name: Authorization # the user's own token, when they send one
securityPolicy:
apiKey:
secretRef:
name: github-service-key
injectionPolicy: IfNotPresent # shared key only if the header is absentThe client-compatibility options each have a rule attached. With prefixMode Never, a backend must list its tools in toolSelector.include, and two Never-mode backends exposing the same tool name mark the route NotAccepted; resources always keep the prefix. injectionPolicy IfNotPresent applies to header injection only and cannot be combined with queryParam. mergeType accepts StrategicMerge or JSONMerge, and Replace is rejected.
Test the deny path, not just the happy one. After upgrading, send a request with a valid token that lacks the claim your CEL reads and confirm it is refused. Fail-closed behaviour is only a feature if you have seen it fail closed.
Many teams, one gateway: credentials now need a ReferenceGrant
This is the change with the quietest failure. The release notes say that before 1.2 some Secret references, namely Azure client secrets, GCP credentials files and OIDC client secrets, were read from other namespaces with no check. For others, such as API keys and AWS credentials files, the namespace was ignored, so a cross-namespace reference either failed or silently used a same-named Secret in the policy's own namespace. That second case is a wrong credential used without any error.
In 1.2 every credential type honours the namespace. A BackendSecurityPolicy may use a Secret in another namespace only if that namespace allows it with a ReferenceGrant, and a missing grant sets the policy to NotAccepted. Already-issued tokens keep working until they expire, so the failure can surface hours after the upgrade. A grant that names an object covers only that object, and revoking a grant takes effect immediately. The manifest below is the one from the upgrade guidance.
# Created in the namespace that OWNS the Secret (credentials),
# naming the namespace of the policy that wants to read it (ai-backends).
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-backend-security-policy-secrets
namespace: credentials
spec:
from:
- group: aigateway.envoyproxy.io
kind: BackendSecurityPolicy
namespace: ai-backends
to:
- group: ""
kind: Secret
name: openai-api-key # setting name limits the grant to this one SecretTwo smaller fixes matter to the same teams. Rotated credentials now apply immediately, which repairs a 1.1.0 regression where calls could use a stale key until the next reconcile. And per-tenant token limits charge the correct tenant, which the announcement flags as a reason tenants may now see 429 responses: limits that were previously charged to the wrong tenant now bite where they should.
What breaks on upgrade, and how it shows up
The post and the notes together give six upgrade symptoms. I have arranged them by what an on-call engineer would actually see, because the cause is rarely obvious from the symptom.
| Symptom | Cause | Fix |
|---|---|---|
| MCP clients drop right after the upgrade | A random session encryption seed replaces the well-known default | Accept reconnects, set the fallback seed temporarily, or supply your own Secret |
| 401 on MCP OAuth calls | The JWT provider checks iss; a trailing slash mismatch fails | Set securityPolicy.oauth.issuer to the exact iss value |
| Every update to an existing MCPRoute is rejected | CEL references auth.jwt but the route has no securityPolicy.oauth | Add oauth, or remove the JWT references |
| A BackendSecurityPolicy shows NotAccepted | A cross-namespace Secret has no ReferenceGrant | Create the grant in the Secret's namespace |
| Dashboard panels split into one series per backend | GenAI metrics gained a gen_ai_backend label | Wrap queries in sum by |
| Tenants start seeing 429 responses | Token limits now charge the correct tenant | Review per-tenant limits before the upgrade |
The GitOps trap is easy to miss. With helm template the chart cannot remember a generated seed, so every render produces a new one and every sync would end all MCP sessions. The notes say to set controller.mcp.sessionEncryption.existingSecret or the seed value explicitly.
A missing ReferenceGrant does not stop traffic on the day. Tokens already issued keep working until they expire, so the first symptom can arrive hours later and look like an unrelated outage. Check policy status right after the upgrade instead of waiting for it.
What I could not settle: neither the 1.0 nor the 1.2 post publishes a measurement of what verified-JWT checks and CEL evaluation cost per request. If MCP tool calls sit on a latency budget, measure it on your own traffic before and after.
What to do on Monday
Treat the rename as a non-event and the upgrade as the project. In order:
- Inventory first: list every MCPRoute, BackendSecurityPolicy and ReferenceGrant, and mark the policies whose Secrets live in another namespace and the routes whose CEL reads auth.jwt.
- Be on 1.1.x before you start. The announcement says to upgrade from 1.1.x, not directly from 1.0.x.
- Upgrade Envoy Gateway to v1.9.2 and the Gateway API CRDs to v1.6 first, and do not enable Envoy Gateway's mergeBackends option with Agent Router yet.
- Decide the session seed: accept reconnects, keep sessions with the fallback seed for one upgrade, or create your own Secret if you render with helm template.
- Fix the routes and add the grants before the new controller sees them: exact issuer, oauth on every JWT-reading route, null-safe CEL, one ReferenceGrant per cross-namespace Secret.
- Upgrade Agent Router, then check policy status for NotAccepted, update dashboards for the gen_ai_backend label, and delete the legacy filter-config.yaml Secrets.
# 0. Inventory before touching anything
kubectl get mcproutes -A
kubectl get backendsecuritypolicies -A
kubectl get referencegrants -A
# 1. Gateway API CRDs and Envoy Gateway first (commands from the v1.2.0 notes)
helm template eg-crds oci://docker.io/envoyproxy/gateway-crds-helm \
--version v1.9.2 \
--set crds.gatewayAPI.enabled=true \
--set crds.envoyGateway.enabled=true \
| kubectl apply --force-conflicts --server-side -f -
# 2. Your own session seed, so a GitOps render does not mint a new one each time
kubectl create secret generic mcp-session-seed -n envoy-ai-gateway-system \
--from-literal=seed="$(openssl rand -hex 32)"
# 3. Agent Router 1.2.0. Chart and image names keep the ai-gateway prefix.
helm upgrade -i aieg-crd oci://docker.io/envoyproxy/ai-gateway-crds-helm \
--version v1.2.0 --namespace envoy-ai-gateway-system
# The existingSecret flag is my addition to the notes' command (step 2 above).
helm upgrade -i aieg oci://docker.io/envoyproxy/ai-gateway-helm \
--version v1.2.0 --namespace envoy-ai-gateway-system \
--set controller.mcp.sessionEncryption.existingSecret=mcp-session-seed
# 4. The late failure: a policy without a ReferenceGrant is NotAccepted
kubectl get backendsecuritypolicies -A -o yaml | grep -n NotAcceptedThen put two dates in the calendar. The legacy cache_creation_input_tokens field is scheduled for removal in v1.3.0, so read cache_write_tokens instead. And the what's-next list names OAuth token exchange, a dedicated MCPBackend CRD and agent-to-agent traffic, all of which would change how you model identity and backends.
The rule I take from this: a rename announcement tells you what the maintainers did not touch, and the release notes tell you what they did. Agent Router 1.2 closes gaps that a shared gateway should never have had, silent cross-namespace credentials and unverified claims among them, and it closes them by failing loudly. Budget for the loud failures.
Sources
- Agent Router blog: Agent Router 1.2, safe to share across users and teams
- Agent Router blog: Envoy AI Gateway is becoming Agent Router
- Agent Router blog: Multi-User MCP in Production, per-user identity at the gateway layer
- Agent Router blog: Announcing Envoy AI Gateway 1.0
- GitHub: Agent Router v1.2.0 release notes
- Agent Router docs: Model Context Protocol (MCP) gateway
- Linux Foundation: formation of the Agentic AI Foundation
- Dale Seo: Agent Router, the second agent gateway in AAIF (Korean, third party)

