Skip to content

Rename gateway “API key” surface to Agent ID with compat aliases and X-Agent-ID routing#7114

Merged
lpcox merged 9 commits into
mainfrom
copilot/rename-api-key-to-agent-id
Jun 6, 2026
Merged

Rename gateway “API key” surface to Agent ID with compat aliases and X-Agent-ID routing#7114
lpcox merged 9 commits into
mainfrom
copilot/rename-api-key-to-agent-id

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jun 6, 2026

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)

    • Introduced primary names:
      • TOML: gateway.agent_id
      • JSON stdin: gateway.agentId
      • Env: MCP_GATEWAY_AGENT_ID
      • Go accessors/validation: GetAgentID(), ValidateAgentID()
    • Kept backward-compatible aliases:
      • api_key, apiKey, MCP_GATEWAY_API_KEY, GetAPIKey(), ValidateAPIKey()
    • Added deprecation warnings when legacy names are used.
    • Defined precedence when both are present (new name wins).
  • Session identity routing behavior

    • Added ExtractSessionIDFromHeaders(xAgentID, authorization) and wired server session extraction to:
      1. Prefer X-Agent-ID for session routing
      2. Fallback to Authorization for legacy/current behavior
    • Auth validation still uses Authorization semantics; routing and auth are no longer implicitly conflated in naming.
  • Schema/docs/examples alignment

    • Updated schema to model agentId as primary and apiKey as deprecated alias.
    • Updated README/config/docs/examples to consistently use Agent ID terminology and document migration/compat behavior.
    • Added explicit mention of X-Agent-ID as preferred routing header with Authorization fallback.
  • Test updates

    • Updated config/auth/server tests to assert agentId/agent_id paths.
    • Added compatibility coverage for legacy aliases and precedence rules.
    • Added X-Agent-ID precedence coverage in session extraction and auto-init header forwarding.
// Session routing precedence
sessionID := auth.ExtractSessionIDFromHeaders(
    r.Header.Get("X-Agent-ID"),
    r.Header.Get("Authorization"),
)
// X-Agent-ID wins when present; Authorization remains fallback.

Copilot AI changed the title [WIP] Rename 'API key' to 'Agent ID' to reduce security testing confusion Rename gateway “API key” surface to Agent ID with compat aliases and X-Agent-ID routing Jun 6, 2026
Copilot AI requested a review from lpcox June 6, 2026 21:03
Copilot finished work on behalf of lpcox June 6, 2026 21:03
@lpcox lpcox marked this pull request as ready for review June 6, 2026 21:10
Copilot AI review requested due to automatic review settings June 6, 2026 21:10
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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 / agentId as the primary identifier, with legacy api_key / apiKey kept as deprecated aliases (including env var + Go accessors).
  • Adds header-based session routing precedence: X-Agent-ID first, then Authorization fallback.
  • 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

Comment on lines +123 to 130
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 ""
Comment on lines 301 to 315
@@ -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)
}
}()
Comment on lines 328 to 332
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")

Comment thread internal/config/config_test.go Outdated
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")
Comment on lines +1544 to 1547
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())
})
Comment on lines +460 to +463
// 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())
@lpcox
Copy link
Copy Markdown
Collaborator

lpcox commented Jun 6, 2026

@copilot address review feedback

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jun 6, 2026

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

Copilot finished work on behalf of lpcox June 6, 2026 21:32
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>
lpcox and others added 4 commits June 6, 2026 15:48
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>
@lpcox lpcox merged commit 22366db into main Jun 6, 2026
21 checks passed
@lpcox lpcox deleted the copilot/rename-api-key-to-agent-id branch June 6, 2026 23:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rename 'API key' to 'Agent ID' to reduce security testing confusion

3 participants