Skip to main content
BlogBackend

Envoy AI Gateway Is Now Agent Router: What 1.2 Changes

Envoy AI Gateway became Agent Router. I read the rename post and the 1.2 release notes to see what stayed and what breaks for MCP and credentials.

Matthews Wong

Software Engineer

October 202612 min read
Envoy AI Gateway Is Now Agent Router: What 1.2 Changes

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.

ItemBefore the renameAfter the rename
Product nameEnvoy AI GatewayAgent Router (the post says prose only)
Repositoryenvoyproxy/ai-gatewaytheagentrouter/agent-router, old links redirect
Websiteaigateway.envoyproxy.iotheagentrouter.ai, old links redirect to the same pages
CRDs and API groupAIGatewayRoute, AIServiceBackend, BackendSecurityPolicy under aigateway.envoyproxy.ioUnchanged
CLI and namespaceaigw and envoy-ai-gateway-systemUnchanged
Helm charts and imagesai-gateway-helm and ai-gateway-crds-helm on docker.io/envoyproxySame names in 1.2.0; the notes say the ai-gateway prefix is kept
GovernanceEnvoy sub-project within the CNCF, per the announcementStandalone 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.

PatternPer-user RBACNew infrastructureBest for
Shared service accountNoNoneTools without per-user permissions
Header forwardingYesNoneThe user's credential already works downstream
Client credentials (OAuth)Fixed scope onlyApp registrationAn agent acting as itself
Token exchange (RFC 8693)YesSecurity token service and trust configIdentity 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 absent

The 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 Secret

Two 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.

SymptomCauseFix
MCP clients drop right after the upgradeA random session encryption seed replaces the well-known defaultAccept reconnects, set the fallback seed temporarily, or supply your own Secret
401 on MCP OAuth callsThe JWT provider checks iss; a trailing slash mismatch failsSet securityPolicy.oauth.issuer to the exact iss value
Every update to an existing MCPRoute is rejectedCEL references auth.jwt but the route has no securityPolicy.oauthAdd oauth, or remove the JWT references
A BackendSecurityPolicy shows NotAcceptedA cross-namespace Secret has no ReferenceGrantCreate the grant in the Secret's namespace
Dashboard panels split into one series per backendGenAI metrics gained a gen_ai_backend labelWrap queries in sum by
Tenants start seeing 429 responsesToken limits now charge the correct tenantReview 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:

  1. 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.
  2. Be on 1.1.x before you start. The announcement says to upgrade from 1.1.x, not directly from 1.0.x.
  3. 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.
  4. 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.
  5. 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.
  6. 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 NotAccepted

Then 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.

FAQ

Frequently Asked Questions

Short answers to what readers ask most about this topic.

Is Envoy AI Gateway the same project as Agent Router?

Yes. Envoy AI Gateway was renamed Agent Router on 10 September 2026 when it joined the Agentic AI Foundation. The announcement says the code and maintainers are the same, and the CRDs, the aigateway.envoyproxy.io API group and the aigw CLI are not renamed.

Do I need to change my manifests after the Agent Router rename?

No. The announcement says existing manifests apply unchanged, and the 1.2.0 notes keep the ai-gateway prefix on Helm chart and image names. Only links to the old repository and website need updating, and those redirect for now.

What breaks when upgrading to Agent Router 1.2?

The release notes list three breaking changes. MCP sessions end because the chart now generates a random session encryption seed, the MCP OAuth issuer must match the identity provider's iss exactly, and CEL that reads auth.jwt needs securityPolicy.oauth. Cross-namespace Secrets in a BackendSecurityPolicy also need a ReferenceGrant.

Why does a BackendSecurityPolicy become NotAccepted after 1.2?

Since 1.2 every credential type honours the Secret's namespace, and a Secret in another namespace is only usable with a ReferenceGrant. Without one the policy is set to NotAccepted. Tokens already issued keep working until they expire, so the failure may appear late.

How does an MCP gateway pass each user's identity to a backend?

Agent Router can forward chosen client headers to a backend through forwardHeaders, which is opt-in per backend and off by default. The backend then validates the credential itself. For cross-identity-provider cases the project points to OAuth token exchange, which was still in review in its July post.