feat: support AWS SigV4 authentication for MCP backends#2181
Draft
Flgado wants to merge 2 commits into
Draft
Conversation
Signed-off-by: Joao Folgado <jfolgado94@gmail.com>
Signed-off-by: Joao Folgado <jfolgado94@gmail.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #2181 +/- ##
==========================================
- Coverage 84.41% 84.35% -0.06%
==========================================
Files 134 136 +2
Lines 19156 19327 +171
==========================================
+ Hits 16171 16304 +133
- Misses 1998 2019 +21
- Partials 987 1004 +17 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds
awsCredentialstoMCPBackendSecurityPolicy, enabling the gateway to sign outbound MCP requests with AWS SigV4. This lets MCP clients connect to AWS IAM-fronted MCP servers (AWS MCP Server, Bedrock AgentCore) through the gateway without any AWS-specific client tooling — the gateway handles all signing server-side, replacing the per-clientmcp-proxy-for-aws.Motivation
MCP servers behind AWS IAM cannot be reached with the existing
apiKeyor OAuth mechanisms. Today each client must run a local signing proxy. This duplicates AWS credential handling across every client and prevents a single, centrally managed identity from being used. Moving SigV4 signing into the gateway removes both problems: clients speak plain MCP, and one managed AWS identity signs all traffic.API
New
awsCredentialsfield on the MCP backend security policy, mutually exclusive withapiKey(enforced via CEL):<service>.<region>.amazonaws.com / .api.aws). A clear error is returned when it cannot be inferred and is not set.Design decisions
Why the backend must be an Envoy Gateway
BackendSigV4 signs over the Host header and path that AWS ultimately sees. The MCP proxy sends every request to the local Envoy listener, and Envoy rewrites authority/path to the upstream — so the proxy cannot discover the real host on its own. The controller resolves the upstream FQDN by reading the
Backendresource and bakes it into the signing config ahead of time.This is the only MCP code path that reads the Backend object. Non-AWS routes never need it because Envoy owns host resolution for them.
Signing on every send path
igV4 headers are computed as the last step before a request is sent, on every outbound path: session initialization, single-backend calls (
tools/call), and the multi-backend fan-out (tools/list). Non-AWS backends are never signed, and signatures never leak across backends on the same route.The signature is computed against a temporary request built with the resolved upstream host/path, then only the Authorization / X-Amz-* headers are copied onto the real request. This avoids invalidation when Envoy later rewrites the authority.
Standalone aigw run support
aigw run uses a fake client to back the in-process controller. The object collection step now additionally loads Backend resources into that fake client so backend-host resolution works in standalone mode. The Backend YAML was already written to the Envoy output for cluster building — this just registers it with the controller's client too.
Testing
Proxy: signer built only for AWS backends; signing on the single-backend and fan-out paths; cross-backend isolation (only the AWS backend is signed); invalid credentials rejected at load.
CEL/CRD: valid awsCredentials and apiKey/awsCredentials mutual exclusion.
Manual E2E: aigw run against the AWS MCP Server — tools/list and tools/call (call_aws returning real AWS identity).
Note on SigV4 code duplication with backendauth/aws.go
The existing LLM backend SigV4 signer (internal/backendauth/aws.go) contains nearly identical logic: credential loading, temp file, ContentLength = -1 to avoid signature invalidation by Envoy's chunked transfer-encoding, and copying only Authorization / X-Amz-* headers. This PR intentionally does not refactor that code to avoid a large cross-cutting change. Instead, the new signing logic lives in internal/awsauth/ as a clean, reusable package. A follow-up can migrate backendauth/aws.go to use internal/awsauth/ as well, consolidating both into a single SigV4 implementation.
Out of scope / follow-ups