Skip to content

fix: ensure that plaintext API key secret ref is not exposed in MCP backend HTTPRoute#2134

Open
aishwaryaraimule21 wants to merge 11 commits into
envoyproxy:mainfrom
aishwaryaraimule21:cred-inj-mcp-httproute
Open

fix: ensure that plaintext API key secret ref is not exposed in MCP backend HTTPRoute#2134
aishwaryaraimule21 wants to merge 11 commits into
envoyproxy:mainfrom
aishwaryaraimule21:cred-inj-mcp-httproute

Conversation

@aishwaryaraimule21
Copy link
Copy Markdown

@aishwaryaraimule21 aishwaryaraimule21 commented May 13, 2026

Description

When an MCPRoute has a backendRef with securityPolicy.apiKey configured (either via secretRef or inline), the controller resolves the secret and embeds the plaintext API key directly into the generated HTTPRoute resource. This happens in two places:

  1. Header injection — the key is written as a literal value in an HTTPRouteFilter of type RequestHeaderModifier (e.g., Authorization: Bearer <plaintext-token>).
  2. Query parameter injection — the key is appended to the URL path in a URLRewrite filter (e.g., /mcp?api_key=<plaintext-token>).

fixes #2141

Possible Solutions

  1. This can be solved for Header injection by using https://gateway.envoyproxy.io/docs/api/extension_types/#httpcredentialinjectionfilter. However, APIKey for QueryParams will still continue to be stored in plaintext. Note: This PR implements this approach.
  2. By contrast, the existing BackendSecurityPolicy (used by AIGatewayRoute / AIServiceBackend) stores the resolved credential inside a Kubernetes Secret (the filter config secret consumed by extproc), which benefits from RBAC, encryption at rest, and audit logging. MCPRoute should adopt a similar approach.
  3. Explore if we can add support for QueryParams in CredentialInjectionFilter in Envoy Gateway.

Affected code:

  • internal/controller/mcp_route.go`

Testing

Created MCPRoute with credential injection into Authorization header.
Credential got created and HTTPRouteFilter with Credential Injection filter got created. List tools and tool calls work as expected. Credential and filter got deleted on removing backend and deleting MCPRoute.

Created MCPRoute with credential injection into a custom header.
Credential got created and HTTPRouteFilter with Credential Injection filter got created. List tools and tool calls work as expected. Credential and filter got deleted on removing backend and deleting MCPRoute.

Created MCPRoute with inline API Key into Authorization header.
No change in behaviour.

Created MCPRoute with API Key injected into query param
No change in behaviour.

… filters

Signed-off-by: Aishwarya <aishwarya.raimule@nutanix.com>
…viours of queryparam, inline

Signed-off-by: Aishwarya <aishwarya.raimule@nutanix.com>
@aishwaryaraimule21 aishwaryaraimule21 marked this pull request as ready for review May 14, 2026 16:17
@aishwaryaraimule21 aishwaryaraimule21 requested a review from a team as a code owner May 14, 2026 16:17
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label May 14, 2026
Copy link
Copy Markdown
Contributor

@Hritik003 Hritik003 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, minor nit

Comment on lines +773 to +775
Data: map[string][]byte{
"credential": []byte(credentialValue),
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use the named constant from EG just so that this is tightly coupled to Envoy Gateway's filter expectations?

…e InjectedCredentialKey instead of the deprecated credential key.

Signed-off-by: Aishwarya <aishwarya.raimule@nutanix.com>
…1/ai-gateway into cred-inj-mcp-httproute

Signed-off-by: Aishwarya <aishwarya.raimule@nutanix.com>
Signed-off-by: Aishwarya <aishwarya.raimule@nutanix.com>
…edentials in URLs

Signed-off-by: Aishwarya <aishwarya.raimule@nutanix.com>
…1/ai-gateway into cred-inj-mcp-httproute

Signed-off-by: Aishwarya <aishwarya.raimule@nutanix.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: MCP backend API Keys are embedded as plaintext in HTTPRoute

2 participants