Agent Router: MCP session seed still exposed in gateway pod args
Agent Router (formerly Envoy AI Gateway) - incomplete fix for GHSA-r86v-rw5r-2cpj: the extproc sidecar still receives the MCP session seed as a container argument (GHSA-3qgx-4x8m-wwhg)
Fixed in Agent Router 1.2.1 (2026-11-06): #2848 delivers the MCP session seeds to the extproc through the filter config Secret instead of container arguments, and the Helm chart now reads both seeds from Secrets. Track the fix at theagentrouter/agent-router#2848.
- Product
- Agent Router, formerly Envoy AI Gateway (Go module github.com/envoyproxy/ai-gateway, controller, extproc, Helm chart ai-gateway-helm) in theagentrouter/agent-router
- Affected versions
- Agent Router / Envoy AI Gateway 1.2.0 and earlier with an MCPRoute in use. Fixed in 1.2.1 (2026-11-06).
- Severity
- MEDIUM
- Status
- Patched
- Weaknesses
- CWE-214Invocation of Process Using Visible Sensitive Information
- GitHub advisory
- GHSA-3qgx-4x8m-wwhg
Published by the maintainer on 2026-11-06 - CVE
- Pending (requested from GitHub)
- Published
- Credit
- Finder: Aaron Elijah Mars of Aeon. Tool: Aeon (https://www.aeon.fun).
What users should do now
Upgrade to Agent Router 1.2.1 (released 2026-11-06). It includes #2848, which keeps the MCP session seeds out of Pod specs and process command lines.
- Upgrade the controller, the extproc image and the
ai-gateway-helmchart to 1.2.1. Gateway pods that serve MCPRoutes roll once, because the extproc arguments change. Open MCP sessions survive as long as the seed stays the same. - Treat the current seed as exposed. Before 1.2.1 it sat in every gateway Pod object, in etcd (Pod objects are not covered by Secret encryption at rest) and in any audit log that records Pod bodies. After upgrading, rotate it: set a new random
controller.mcp.sessionEncryption.seed, keep the old one ascontroller.mcp.sessionEncryption.fallback.seedonly until clients have reconnected, then remove the fallback. - If you run the controller outside the chart, pass the seeds through the
MCP_SESSION_ENCRYPTION_SEEDandMCP_FALLBACK_SESSION_ENCRYPTION_SEEDenvironment variables instead of the--mcpSessionEncryptionSeedand--mcpFallbackSessionEncryptionSeedflags. The flags still work and take precedence when set, but they put the seed on the process command line. - Until you can upgrade, limit who can
get,listorwatchpods in gateway namespaces. That includes the built-inviewClusterRole and cluster-wide pod watchers such as monitoring, logging and policy agents. Leave the fallback seed unset unless you are in the middle of a rotation.
Summary
The MCP proxy in Agent Router encrypts each client's Mcp-Session-Id with a key derived from a seed. GHSA-r86v-rw5r-2cpj reported that this seed was passed as a literal argument in the pod spec, and was published on 2026-10-07 with 1.2.0 as the patched version. The 1.2.0 change (#2755) only touched the Helm chart: it stored the controller's seed in a Secret and handed it to the controller through an environment variable. It did not change how the controller passes the seed on to the extproc container that its mutating webhook injects into every Envoy gateway pod. That container still got -mcpSessionEncryptionSeed <seed> (and -mcpFallbackSessionEncryptionSeed <seed> when a fallback is set) as literal strings in container.Args. The chart also still passed the controller's fallback seed as a literal argument.
Affected versions
Agent Router, formerly Envoy AI Gateway (Go module github.com/envoyproxy/ai-gateway, Helm chart ai-gateway-helm), 1.2.0 and earlier, on any Gateway targeted by an MCPRoute. Fixed in 1.2.1 (2026-11-06). The fallback seed is only exposed when controller.mcp.sessionEncryption.fallback.seed is set, which the chart recommends during seed rotation and when upgrading from the old default seed. Reviewed on main at f4571d6 (2026-10-09); the same code is in v1.2.0.
Impact
Anyone who can read gateway pods can recover the MCP session-encryption seed, and the fallback seed if one is set. Pod read is a lower RBAC tier than Secret read, so this is the same gap GHSA-r86v-rw5r-2cpj describes. The seed could be read from:
- The gateway Pod objects (
kubectl get pod -o yaml,kubectl describe pod, or anyget,listorwatchon pods in the gateway namespace). - etcd, where Pod objects are not covered by Secret encryption at rest, and Kubernetes audit logs that record Pod create or update bodies.
- The extproc process command line on the node, and the pprof
cmdlineendpoint, which is on by default and listens on 127.0.0.1 inside the pod.
With the seed, an attacker can decrypt any observed Mcp-Session-Id and read the route, subject and backend MCP session IDs inside it. Since GHSA-953h-535j-jg2v the gateway checks that a resumed session belongs to the caller's subject, but a seed holder can re-encrypt a captured victim's backend session IDs under their own subject and resume that session as themselves. On routes without authentication the subject is empty for everyone. A leaked fallback seed is as useful as the primary one, because the gateway accepts IDs that decrypt under it for as long as it is set. The attacker still needs pod read access, a valid identity on authenticated routes, and a captured session ID to take over a specific session; the seed alone does not reveal backend session IDs. This is why the issue is rated Medium. A working exploit is withheld.
Affected code
Permalinks at c7c4bf0, the parent of the fix commit.
- Seed and fallback seed appended to the extproc arguments as literal values when an MCPRoute targets the Gateway: internal/controller/extproc_builder.go#L301-L312
- Those arguments become the injected container's
Args: extproc_builder.go#L166 - The mutating webhook adds that container to every gateway Pod spec: internal/controller/gateway_mutator.go#L335-L349
- extproc could only take the seed from these flags, which default to
default-insecure-seed: cmd/extproc/mainlib/main.go#L155-L160 - Controller side: the primary seed is expanded into the command line from an environment variable, and the fallback seed is templated in as a literal argument: manifests/charts/ai-gateway-helm/templates/deployment.yaml#L120-L124
- IDs that decrypt under the fallback key are accepted: internal/mcpproxy/crypto.go#L107-L117
Fix
- #2848 (commit 6d63a4f, by the maintainer): the controller no longer adds the seeds to the extproc arguments. It writes them into the per-gateway filter config, which is already stored in a Secret and mounted into the extproc, and the extproc builds its session crypto from that config.
- The controller now reads both seeds from the
MCP_SESSION_ENCRYPTION_SEEDandMCP_FALLBACK_SESSION_ENCRYPTION_SEEDenvironment variables. The Helm chart stores the fallback seed in its own Secret and no longer passes either seed as an argument. - The seeds are also left out of the extproc config hash stored as a pod-template annotation, so it can no longer be used to test seed guesses offline.
- Backported to the 1.2 branch as 309d90c and shipped in 1.2.1. Still present on
mainatd41f082(2026-11-06).
Detection (for defenders)
- Check whether your gateway pods carry the seed: look for
-mcpSessionEncryptionSeedor-mcpFallbackSessionEncryptionSeedin the extproc container args. On 1.2.1 the extproc gets only-mcpAddrfor MCP. - Check the controller Deployment for a literal
--mcpFallbackSessionEncryptionSeed=argument. - Review which users and service accounts can read pods in gateway namespaces, and whether your audit logs keep Pod request bodies. If the seed was readable by anyone you do not trust with it, rotate it.
Timeline
- GHSA-r86v-rw5r-2cpj published with 1.2.0 as the patched version.
- Reported privately via GitHub PVR (GHSA-3qgx-4x8m-wwhg): the extproc part of GHSA-r86v-rw5r-2cpj was still present in 1.2.0 and on
main, with a suggested fix. - Maintainer accepts the report (Medium, CWE-214) and opens #2848. We asked for a patched version and a CVE request at publication.
- #2848 merged.
- We asked the maintainer to finish the advisory and request a CVE from GitHub.
- Agent Router 1.2.1 released with the fix; the maintainer publishes GHSA-3qgx-4x8m-wwhg. Public write-up.
Credit
References
- Fix PR (merged 2026-10-23): theagentrouter/agent-router#2848
- Fixed release: Agent Router 1.2.1
- GitHub advisory: GHSA-3qgx-4x8m-wwhg
- CVE: not assigned yet; requested from GitHub
- Original advisory: GHSA-r86v-rw5r-2cpj (MCP session seed passed as a literal container argument)
- Related write-up: Agent Router MCP session hijacking (GHSA-953h-535j-jg2v)
- Affected repository: theagentrouter/agent-router