Problem
Per the OWASP Agentic Top 10 — ASI-07 (Insecure Multi-Agent Orchestration), communication between agents and tool gateways should be encrypted and signed to prevent tampering.
Current behavior: The MCP gateway communicates with the agent over plain HTTP on localhost:8080 with only an API key for authentication. There is no TLS, no message signing, and no replay protection.
Current Communication Architecture
From mcp_setup_generator.go and mcp_gateway_config.go in gh-aw:
Agent (Copilot/Claude/Codex)
↓ HTTP (plain text)
↓ Port 8080, host.docker.internal (or localhost)
↓ API key in header (MCP_GATEWAY_API_KEY, ~45 chars base64)
↓ --network host
MCP Gateway Container (gh-aw-mcpg)
↓ HTTP/stdio
↓ Per-server env vars (tokens, secrets)
MCP Servers (GitHub, Playwright, custom)
Gateway startup (mcp_setup_generator.go:L500-650):
docker run -i --rm --network host \
-e MCP_GATEWAY_PORT=8080 \
-e MCP_GATEWAY_DOMAIN=host.docker.internal \
-e MCP_GATEWAY_API_KEY=<random-base64> \
github/gh-aw-mcpg:vX.Y.Z
Secrets passed as env vars (mcp_environment.go:L61-201):
GITHUB_MCP_SERVER_TOKEN — GitHub API token
GH_AW_SAFE_OUTPUTS — safe outputs config
GH_AW_SAFE_OUTPUTS_API_KEY — safe outputs auth
GH_AW_MCP_SCRIPTS_API_KEY — MCP scripts auth
- Custom HTTP MCP header secrets
ACTIONS_ID_TOKEN_REQUEST_* — OIDC tokens
All secrets are visible to any process inside the gateway container.
Parent Issue
Part of github/gh-aw#28770 (OWASP Agentic Top 10 Compliance Evaluation)
Proposed Solution
Phase 1: mTLS (Encrypted Channel)
- Certificate Generation — Generate ephemeral self-signed CA + client/server certs during the
start-mcp-gateway step in gh-aw
- Gateway TLS Listener — MCPG accepts TLS connections on port 8080 with server cert, validates client cert
- Agent Configuration — Pass client cert + CA to agent engine so HTTP calls use mTLS
- Certificate Rotation — Certs are ephemeral per-run (generated at startup, destroyed at teardown)
Phase 2: Message Signing
- Request Signing — Agent signs each MCP request with an HMAC (shared secret derived from API key)
- Signature Verification — Gateway verifies HMAC before processing any request
- Replay Protection — Include timestamp + nonce in signed payload; reject messages older than 30s or with seen nonces
- Response Signing — Gateway signs responses so agent can verify integrity
Phase 3: Secret Isolation
- Per-Server Secret Scoping — Each MCP server only receives its own secrets (not all env vars)
- Secret Masking — Secrets are loaded from encrypted files rather than env vars where possible
- Audit Trail — Log (without values) which secrets were accessed by which server
Key MCPG Changes
- Add TLS server configuration (cert/key loading, client CA verification)
- Add HMAC signature verification middleware
- Add nonce/timestamp replay protection
- Add per-server secret scoping in server process spawning
- Configuration:
MCP_GATEWAY_TLS_CERT, MCP_GATEWAY_TLS_KEY, MCP_GATEWAY_CA_CERT, MCP_GATEWAY_HMAC_SECRET
Key gh-aw Changes (Companion)
Changes needed in github/gh-aw to support this:
mcp_setup_generator.go — generate ephemeral certs, pass to Docker via mounts
mcp_gateway_config.go — add TLS configuration fields
mcp_environment.go — add cert paths to env vars
- Engine
RenderMCPConfig() — include client cert paths in agent MCP config
Acceptance Criteria
Problem
Per the OWASP Agentic Top 10 — ASI-07 (Insecure Multi-Agent Orchestration), communication between agents and tool gateways should be encrypted and signed to prevent tampering.
Current behavior: The MCP gateway communicates with the agent over plain HTTP on localhost:8080 with only an API key for authentication. There is no TLS, no message signing, and no replay protection.
Current Communication Architecture
From
mcp_setup_generator.goandmcp_gateway_config.goin gh-aw:Gateway startup (
mcp_setup_generator.go:L500-650):Secrets passed as env vars (
mcp_environment.go:L61-201):GITHUB_MCP_SERVER_TOKEN— GitHub API tokenGH_AW_SAFE_OUTPUTS— safe outputs configGH_AW_SAFE_OUTPUTS_API_KEY— safe outputs authGH_AW_MCP_SCRIPTS_API_KEY— MCP scripts authACTIONS_ID_TOKEN_REQUEST_*— OIDC tokensAll secrets are visible to any process inside the gateway container.
Parent Issue
Part of github/gh-aw#28770 (OWASP Agentic Top 10 Compliance Evaluation)
Proposed Solution
Phase 1: mTLS (Encrypted Channel)
start-mcp-gatewaystep in gh-awPhase 2: Message Signing
Phase 3: Secret Isolation
Key MCPG Changes
MCP_GATEWAY_TLS_CERT,MCP_GATEWAY_TLS_KEY,MCP_GATEWAY_CA_CERT,MCP_GATEWAY_HMAC_SECRETKey gh-aw Changes (Companion)
Changes needed in
github/gh-awto support this:mcp_setup_generator.go— generate ephemeral certs, pass to Docker via mountsmcp_gateway_config.go— add TLS configuration fieldsmcp_environment.go— add cert paths to env varsRenderMCPConfig()— include client cert paths in agent MCP configAcceptance Criteria