OAuth2 Proxy Integration
Agent Gateway can integrate with OAuth2 Proxy to add authentication using GitHub, Google, Azure AD, and other OAuth providers.
What you’ll build
In this tutorial, you’ll:
- Create a GitHub OAuth application for authentication
- Set up OAuth2 Proxy with Docker
- Configure Agent Gateway to use external authorization
- Protect MCP endpoints with OAuth login
- Extract and log user identity from authenticated requests
Prerequisites
- Agent Gateway installed
- Docker installed and running
- A GitHub account (for creating an OAuth app)
Step 1: Create a GitHub OAuth Application
- Go to GitHub Developer Settings
- Click OAuth Apps → New OAuth App
- Fill in the application details:
- Application name:
Agent Gateway Dev(or any name) - Homepage URL:
http://localhost:3000 - Authorization callback URL:
http://localhost:4180/oauth2/callback
- Application name:
- Click Register application
- Copy the Client ID
- Click Generate a new client secret and copy the Client Secret
Step 2: Set up your environment
Create a working directory and set your credentials:
mkdir oauth2-proxy-test && cd oauth2-proxy-test
# Set your GitHub OAuth credentials
export OAUTH2_PROXY_CLIENT_ID=your-github-client-id
export OAUTH2_PROXY_CLIENT_SECRET=your-github-client-secret
# Generate a random cookie secret
export OAUTH2_PROXY_COOKIE_SECRET=$(python3 -c 'import os,base64; print(base64.b64encode(os.urandom(32)).decode()[:32])')Step 3: Start OAuth2 Proxy
Run OAuth2 Proxy in Docker:
docker run -d --name oauth2-proxy \
-p 4180:4180 \
--add-host=host.docker.internal:host-gateway \
-e OAUTH2_PROXY_CLIENT_ID=$OAUTH2_PROXY_CLIENT_ID \
-e OAUTH2_PROXY_CLIENT_SECRET=$OAUTH2_PROXY_CLIENT_SECRET \
-e OAUTH2_PROXY_COOKIE_SECRET=$OAUTH2_PROXY_COOKIE_SECRET \
-e OAUTH2_PROXY_COOKIE_SECURE=false \
quay.io/oauth2-proxy/oauth2-proxy:latest \
--provider=github \
--email-domain=* \
--upstream=file:///dev/null \
--http-address=0.0.0.0:4180 \
--set-xauthrequest \
--reverse-proxy=trueVerify it’s running:
docker logs oauth2-proxyStep 4: Create the Agent Gateway configuration
Create a config.yaml file:
cat > config.yaml << 'EOF'
frontendPolicies:
accessLog:
add:
# Log the authenticated user's GitHub username and email
github.user: 'extauthz.githubUser'
github.email: 'extauthz.githubEmail'
binds:
- port: 3000
listeners:
- name: default
protocol: HTTP
routes:
# Route OAuth2 Proxy endpoints (login, callback, etc.)
- name: oauth2-proxy
matches:
- path:
pathPrefix: /oauth2
policies:
urlRewrite:
authority: none
backends:
- host: localhost:4180
# Protected MCP application
- name: application
backends:
- mcp:
targets:
- name: everything
stdio:
cmd: npx
args: ["@modelcontextprotocol/server-everything"]
policies:
cors:
allowOrigins: ["*"]
allowHeaders: ["*"]
exposeHeaders: ["Mcp-Session-Id"]
extAuthz:
host: localhost:4180
includeRequestHeaders:
- cookie
protocol:
http:
# Check authentication status
path: '"/oauth2/auth"'
# Redirect unauthenticated users to login
redirect: '"/oauth2/start?rd=" + request.path'
# Extract user info from OAuth2 Proxy response headers
metadata:
githubUser: response.headers["x-auth-request-user"]
githubEmail: response.headers["x-auth-request-email"]
addRequestHeaders:
x-forwarded-host: request.host
includeResponseHeaders:
- x-auth-request-user
EOFConfiguration explained
| Setting | Description |
|---|---|
frontendPolicies.accessLog.add |
Log GitHub username/email from authenticated requests |
routes[0] (oauth2-proxy) |
Routes /oauth2/* requests to OAuth2 Proxy for login/callback |
routes[1] (application) |
Protected MCP endpoint with external authorization |
extAuthz.host |
OAuth2 Proxy address for auth checks |
extAuthz.protocol.http.path |
Endpoint OAuth2 Proxy uses to validate auth |
extAuthz.protocol.http.redirect |
Where to send unauthenticated users |
extAuthz.protocol.http.metadata |
Extract user info from OAuth2 Proxy headers |
Step 5: Start Agent Gateway
agentgateway -f config.yamlStep 6: Test the authentication flow
Test unauthenticated access
curl -i http://localhost:3000/mcpExpected response (redirect to login):
HTTP/1.1 302 Found
location: /oauth2/start?rd=/mcpTest in browser
- Open http://localhost:3000/mcp in your browser
- You’ll be redirected to GitHub for authentication
- After logging in, you’ll be redirected back to the MCP endpoint
- The Agent Gateway logs will show your GitHub username and email
Verify user info in logs
After authenticating, check the Agent Gateway logs:
# Look for github.user and github.email in the access logAuthentication flow
┌──────────┐ ┌──────────────┐ ┌─────────────┐ ┌────────┐
│ Client │────▶│Agent Gateway │────▶│OAuth2 Proxy │────▶│ GitHub │
└──────────┘ └──────────────┘ └─────────────┘ └────────┘
│ │ │ │
│ 1. Request /mcp │ │ │
│─────────────────▶│ │ │
│ │ 2. Check auth │ │
│ │───────────────────▶│ │
│ │ 3. 401 (no cookie) │ │
│ │◀───────────────────│ │
│ 4. 302 Redirect │ │ │
│◀─────────────────│ │ │
│ 5. Login page │ │ │
│─────────────────────────────────────▶│ │
│ │ │ 6. OAuth flow │
│ │ │◀───────────────▶│
│ 7. Set cookie │ │ │
│◀────────────────────────────────────│ │
│ 8. Request /mcp │ │ │
│ (with cookie) │ │ │
│─────────────────▶│ │ │
│ │ 9. Check auth │ │
│ │───────────────────▶│ │
│ │ 10. 202 + headers │ │
│ │◀───────────────────│ │
│ 11. MCP response │ │ │
│◀─────────────────│ │ │Using other OAuth providers
OAuth2 Proxy supports many providers. Update the Docker command:
docker run -d --name oauth2-proxy \
-p 4180:4180 \
--add-host=host.docker.internal:host-gateway \
-e OAUTH2_PROXY_CLIENT_ID=$GOOGLE_CLIENT_ID \
-e OAUTH2_PROXY_CLIENT_SECRET=$GOOGLE_CLIENT_SECRET \
-e OAUTH2_PROXY_COOKIE_SECRET=$OAUTH2_PROXY_COOKIE_SECRET \
-e OAUTH2_PROXY_COOKIE_SECURE=false \
quay.io/oauth2-proxy/oauth2-proxy:latest \
--provider=google \
--email-domain=* \
--upstream=file:///dev/null \
--http-address=0.0.0.0:4180 \
--set-xauthrequest \
--reverse-proxy=trueAzure AD
docker run -d --name oauth2-proxy \
-p 4180:4180 \
--add-host=host.docker.internal:host-gateway \
-e OAUTH2_PROXY_CLIENT_ID=$AZURE_CLIENT_ID \
-e OAUTH2_PROXY_CLIENT_SECRET=$AZURE_CLIENT_SECRET \
-e OAUTH2_PROXY_COOKIE_SECRET=$OAUTH2_PROXY_COOKIE_SECRET \
-e OAUTH2_PROXY_COOKIE_SECURE=false \
quay.io/oauth2-proxy/oauth2-proxy:latest \
--provider=azure \
--oidc-issuer-url=https://login.microsoftonline.com/$AZURE_TENANT_ID/v2.0 \
--email-domain=* \
--upstream=file:///dev/null \
--http-address=0.0.0.0:4180 \
--set-xauthrequest \
--reverse-proxy=trueCleanup
Stop and remove the containers:
docker stop oauth2-proxy && docker rm oauth2-proxy
cd .. && rm -rf oauth2-proxy-testProduction considerations
For production deployments:
- Set
OAUTH2_PROXY_COOKIE_SECURE=trueand use HTTPS - Restrict
email-domainto your organization’s domain - Use a persistent cookie secret (not randomly generated)
- See the OAuth2 Proxy documentation for additional security options