MCP-Bastion 4.0.0

MCP-Bastion Documentation

HTTP proxy & boundary

# Gateway boundary mode

MCP-Bastion is in-process middleware by default: security applies only when traffic passes through the wrapped handler. An attacker with direct access to an unwrapped MCP port can bypass pillars entirely.

Boundary mode means treating Bastion as a mandatory network hop - the only MCP entrypoint clients can reach. This closes the structural gap vs commercial gateways without rewriting Bastion as a full SaaS product.

Threat model

Mode Bypass risk When to use
Embedded middleware Host app must call MCPBastionMiddleware on every path Libraries, single-process servers you control
Proxy boundary Clients cannot reach upstream MCP except via Bastion Production, multi-tenant, third-party MCP servers
Embedded + network policy Defense in depth Kubernetes / VPC with NetworkPolicy

Proxy boundary checklist

  1. Bind upstream MCP to loopback - 127.0.0.1 only; never expose raw MCP on 0.0.0.0 without auth.
  2. Expose only the Bastion proxy - Docker: ../Dockerfile + ../deploy/docker-compose.proxy.yml; only port 8080 published.
  3. Require edge authentication - enable edge_auth or agent_iam so anonymous clients cannot call tools:
edge_auth:
  enabled: true
  secret_env: BASTION_EDGE_SECRET
agent_iam:
  enabled: true
  require_token: true
  1. TLS termination - Caddy/nginx in front; see ../deploy/docker-compose.proxy.yml and TRANSPORT_HARDENING.md.
  2. NetworkPolicy / security groups - allow ingress to proxy port only; deny direct routes to upstream MCP port.
  3. No alternate transports - if upstream offers stdio + HTTP, disable or firewall the path that skips Bastion.
  4. Stateless readiness (opt-in) - enable mcp_transport.discovery on the proxy so orchestrators can GET /.well-known/mcp.json without hitting upstream. See HYBRID_MCP_TRANSPORT.md.

Docker quick start (boundary)

docker pull ghcr.io/vaquarkhan/mcp-bastion-proxy:v2.0.0
docker run -p 8080:8080 -e BASTION_EDGE_SECRET=... ghcr.io/vaquarkhan/mcp-bastion-proxy:v2.0.0

Clients must send the edge token in request metadata (bastion_edge_token by default). Without it, requests fail closed when edge_auth.enabled: true.

What Bastion cannot enforce alone

  • Kernel/network isolation - use firewall, service mesh, or sidecar placement.
  • Per-user upstream OAuth to GitHub/Notion - roadmap P2; use an external gateway until shipped.
  • Cryptographic attestation that the host process loaded middleware - use proxy boundary + mTLS between client and proxy.