Rename gateway “API key” surface to Agent ID with compat aliases and X-Agent-ID routing#7114
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates MCP Gateway’s terminology and interfaces to treat the session-routing identifier as an Agent ID (primary) rather than an “API key”, while maintaining backward-compatible aliases and introducing explicit X-Agent-ID-based session routing.
Changes:
- Migrates gateway configuration surface to
agent_id/agentIdas the primary identifier, with legacyapi_key/apiKeykept as deprecated aliases (including env var + Go accessors). - Adds header-based session routing precedence:
X-Agent-IDfirst, thenAuthorizationfallback. - Aligns schema, docs, examples, and integration/unit tests with the new terminology and compatibility behavior.
Show a summary per file
| File | Description |
|---|---|
| test/integration/tools_json_test.go | Updates JSON config fixture to use gateway.agentId. |
| test/integration/tavily_test.go | Updates integration fixtures to use gateway.agentId. |
| test/integration/safeinputs_http_test.go | Updates integration fixture to use gateway.agentId. |
| test/integration/playwright_test.go | Updates integration config maps to use agentId. |
| test/integration/github_test.go | Updates integration fixtures to use gateway.agentId. |
| test/integration/difc_config_test.go | Updates DIFC integration fixtures to use agentId. |
| test/integration/binary_test.go | Updates JSON config maps used in binary invocation tests to agentId. |
| test/integration/auth_config_test.go | Updates auth header output tests to configure agentId. |
| README.md | Documents agent_id/agentId primary field, deprecated aliases, and X-Agent-ID routing. |
| internal/server/session.go | Switches session extraction to ExtractSessionIDFromHeaders(X-Agent-ID, Authorization). |
| internal/server/session_auto_init.go | Forwards X-Agent-ID in auto-init internal requests. |
| internal/server/session_auto_init_test.go | Adds coverage asserting X-Agent-ID forwarding behavior. |
| internal/server/middleware.go | Updates SDK logging to use X-Agent-ID precedence for session context logging. |
| internal/server/http_helpers_test.go | Adds tests for X-Agent-ID precedence and malformed header handling. |
| internal/config/validation_test.go | Updates stdin JSON fixtures to agentId. |
| internal/config/validation_schema_test.go | Updates schema validation fixtures to agentId. |
| internal/config/validation_env.go | Changes required env var to MCP_GATEWAY_AGENT_ID with legacy fallback acceptance. |
| internal/config/validation_env_test.go | Updates env validation tests for new env var and fallback behavior. |
| internal/config/schema/mcp-gateway-config.schema.json | Promotes agentId to primary and marks apiKey deprecated alias; requires either. |
| internal/config/load_from_stdin_coverage_test.go | Updates stdin JSON fixtures to agentId. |
| internal/config/expand_raw_json_test.go | Updates real-world JSON fixture to agentId. |
| internal/config/config_test.go | Updates stdin JSON parsing tests to assert AgentID and adds new accessor tests. |
| internal/config/config_stdin.go | Adds agentId field, tracks which keys were set, normalizes aliases during conversion. |
| internal/config/config_guardpolicies_test.go | Updates stdin JSON fixtures to agentId. |
| internal/config/config_env.go | Adds GetGatewayAgentIDFromEnv() with precedence and deprecation logging; keeps alias accessor. |
| internal/config/config_difc_test.go | Updates stdin JSON fixtures and assertions to AgentID. |
| internal/config/config_core.go | Adds AgentID primary field + normalization logic; GetAgentID() accessor; keeps deprecated alias. |
| internal/config/config_core_test.go | Updates tests to GetAgentID() and AgentID naming. |
| internal/cmd/root.go | Uses GetAgentID(); generates random identifier if not configured; passes identifier into server creation. |
| internal/cmd/output.go | Uses GetAgentID() and outputs Authorization header value accordingly. |
| internal/auth/header.go | Renames validation helper to ValidateAgentID with deprecated alias; adds ExtractSessionIDFromHeaders. |
| internal/auth/header_test.go | Updates tests for renamed validation and adds coverage for new session ID extraction helper. |
| example-http-config.json | Updates example gateway config to agentId. |
| docs/ENVIRONMENT_VARIABLES.md | Documents MCP_GATEWAY_AGENT_ID as primary with deprecated alias. |
| docs/CONFIGURATION.md | Updates TOML/JSON examples and field table to agent_id/agentId primary + alias. |
| config.example.toml | Updates example gateway field to agent_id. |
| AGENTS.md | Updates agent guidance/examples to agent_id and documents X-Agent-ID routing precedence. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 37/37 changed files
- Comments generated: 6
| agentIDHeader := r.Header.Get("X-Agent-ID") | ||
| authHeader := r.Header.Get("Authorization") | ||
| sessionID := auth.ExtractSessionID(authHeader) | ||
| sessionID := auth.ExtractSessionIDFromHeaders(agentIDHeader, authHeader) | ||
|
|
||
| if sessionID == "" { | ||
| logSession.Printf("Session extraction failed: missing or invalid Authorization header, remote=%s", r.RemoteAddr) | ||
| logger.LogError("client", "Rejected MCP client connection: missing or invalid Authorization header, remote=%s, path=%s", r.RemoteAddr, r.URL.Path) | ||
| logSession.Printf("Session extraction failed: missing or invalid X-Agent-ID/Authorization header, remote=%s", r.RemoteAddr) | ||
| logger.LogError("client", "Rejected MCP client connection: missing or invalid X-Agent-ID/Authorization header, remote=%s, path=%s", r.RemoteAddr, r.URL.Path) | ||
| return "" |
| @@ -282,14 +310,14 @@ func TestValidateExecutionEnvironment(t *testing.T) { | |||
| os.Setenv("MCP_GATEWAY_DOMAIN", origDomain) | |||
| } | |||
| if origAPIKey != "" { | |||
| os.Setenv("MCP_GATEWAY_API_KEY", origAPIKey) | |||
| os.Setenv("MCP_GATEWAY_AGENT_ID", origAPIKey) | |||
| } | |||
| }() | |||
| t.Run("with missing env vars", func(t *testing.T) { | ||
| os.Unsetenv("MCP_GATEWAY_PORT") | ||
| os.Unsetenv("MCP_GATEWAY_DOMAIN") | ||
| os.Unsetenv("MCP_GATEWAY_API_KEY") | ||
| os.Unsetenv("MCP_GATEWAY_AGENT_ID") | ||
|
|
| require.NotNil(t, stdinCfg.Gateway.Port, "Gateway port is nil") | ||
| assert.Equal(t, port, *stdinCfg.Gateway.Port, "Gateway port not correct") | ||
| assert.Equal(t, "test-key", stdinCfg.Gateway.APIKey, "Gateway API key not correct") | ||
| assert.Equal(t, "test-key", stdinCfg.Gateway.AgentID, "Gateway API key not correct") |
| t.Run("Legacy APIKey still maps to agent ID", func(t *testing.T) { | ||
| cfg := &Config{Gateway: &GatewayConfig{AgentID: "legacy-id"}} | ||
| assert.Equal(t, "legacy-id", cfg.GetAgentID()) | ||
| }) |
| // TestGetAgentID_LegacyAPIKeyFallback verifies that GetAgentID falls back to APIKey alias. | ||
| func TestGetAgentID_LegacyAPIKeyFallback(t *testing.T) { | ||
| cfg := &Config{Gateway: &GatewayConfig{AgentID: "legacy-id"}} | ||
| assert.Equal(t, "legacy-id", cfg.GetAgentID()) |
|
@copilot address review feedback |
Addressed the review feedback in commit 9b8e725. Included fixes for session ID hardening (malformed Authorization + path-segment validation), hermetic env-var tests covering both MCP_GATEWAY_AGENT_ID and MCP_GATEWAY_API_KEY, and corrected legacy APIKey fallback assertions/messages in config tests. |
Add pre-agent-steps to all smoke test workflows that build a Docker image from the current checkout and tag it as :local. This ensures smoke tests validate the actual code on the branch rather than the latest published container image from main. Changes: - Add pre-agent-steps with docker build to all 9 smoke workflows - Change sandbox.mcp.version from 'latest' to 'local' - Recompile all affected lock files Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Docker build requires guards/github-guard/github-guard-rust.wasm which is gitignored and must be built from source. Add Rust toolchain setup with wasm32-wasip1 target and run make -C guards/github-guard build before docker build. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Revert smoke .md files to use sandbox.mcp.version: 'latest' (so gh aw compile produces valid lock files), and add a post-compilation script that patches the .lock.yml files to build from source. The script injects a build step AFTER 'Download container images' so the locally-built image overwrites the pulled registry image. This ensures smoke tests validate the actual code on the branch. Usage: gh aw compile smoke-copilot && scripts/patch-smoke-local-build.sh # To revert: gh aw compile Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Extract Python injection logic into scripts/_inject_local_build.py to avoid shell escaping issues that broke YAML indentation and dollar-sign handling. Recompile and re-patch all smoke lock files. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rename user-facing log messages and error strings to use 'agent ID' terminology instead of 'API key', reflecting the true purpose of this identifier as a session routing value rather than a secret. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The gateway currently labels a session-routing identifier as an “API key,” which creates security-review confusion and blurs auth vs identity semantics. This change promotes Agent ID terminology as primary, keeps legacy names as deprecated aliases, and adds explicit header-based session routing via
X-Agent-ID.Config/API terminology migration (non-breaking)
gateway.agent_idgateway.agentIdMCP_GATEWAY_AGENT_IDGetAgentID(),ValidateAgentID()api_key,apiKey,MCP_GATEWAY_API_KEY,GetAPIKey(),ValidateAPIKey()Session identity routing behavior
ExtractSessionIDFromHeaders(xAgentID, authorization)and wired server session extraction to:X-Agent-IDfor session routingAuthorizationfor legacy/current behaviorAuthorizationsemantics; routing and auth are no longer implicitly conflated in naming.Schema/docs/examples alignment
agentIdas primary andapiKeyas deprecated alias.X-Agent-IDas preferred routing header with Authorization fallback.Test updates
agentId/agent_idpaths.X-Agent-IDprecedence coverage in session extraction and auto-init header forwarding.