Active Gateways
Loading…
Request Flow — Azure Deployment
MCP Client
VS Code Copilot · Copilot CLI · Claude
Authorization: Bearer <Entra JWT>
Microsoft Entra ID
issues JWT to client · validates via OIDC discovery
OAuth 2.0 + PKCE
OAuth 2.0 + PKCE
User authentication
☁ Azure VNet
⎈ AKS Cluster
NGINX Ingress
gw.mikegcoleman.com · TLS / Let's Encrypt
management only
Control Plane
admin API
config & catalogs
config & catalogs
checking…
Data Plane
validates JWT via sidecar
routes MCP traffic
routes MCP traffic
checking…
plugin calls (authenticate · get_connection_headers · oauth-*)
entra-sidecar
JWT validation · credential delegation
OAuth broker (DCR + PKCE)
OAuth broker (DCR + PKCE)
Authorization injected per server
DuckDuckGo MCP
in-cluster · no auth
empty headers
empty headers
GitHub MCP
in-cluster · per-user PAT
static credential pattern
static credential pattern
Azure Key Vault
per-user GitHub PATs
OAuth token bundles
pending OAuth state
OAuth token bundles
pending OAuth state
↑ accessed by entra-sidecar via workload identity
Azure PostgreSQL
gateway state
tenants · sessions · audit
tenants · sessions · audit
↑ accessed by Control Plane & Data Plane (private endpoint)
egress to upstream MCP endpoints & external APIs (internet)
api.duckduckgo.com
called by DuckDuckGo MCP
api.github.com
called by GitHub MCP
mcp.granola.ai
OAuth-protected MCP
(no in-cluster wrapper)
(no in-cluster wrapper)
🔄 First Granola call (per user, per ~90 days)
Sidecar discovers Granola's OAuth metadata, dynamically registers an
OAuth client (RFC 7591 DCR), generates a PKCE challenge, and returns
an auth URL. User clicks it → signs in at mcp-auth.granola.ai → IdP
redirects to https://gw.mikegcoleman.com/oauth/callback
→ NGINX routes to sidecar:5555 → token bundle persisted in Key Vault.
Subsequent calls inject the cached access token; refresh tokens
rotate it silently as needed.