Skip to content

OAuth Proxy Quick Reference

Quick lookup guide for OAuth Proxy integration

OAuth Proxy API Endpoints

Dynamic Client Registration

http
POST /api/v1/oauth-proxy/{proxy_id}/register
Content-Type: application/json

{
  "redirect_uris": ["https://your-app.com/callback"],
  "client_name": "Your App Name",
  "token_endpoint_auth_method": "client_secret_post",
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"]
}

Response:

json
{
  "client_id": "gateway_...",
  "client_secret": "gw_secret_...",
  "client_id_issued_at": 1704614400
}

Authorization

http
GET /api/v1/oauth-proxy/{proxy_id}/authorize?
  response_type=code&
  client_id={client_id}&
  redirect_uri={redirect_uri}&
  state={state}&
  code_challenge={challenge}&
  code_challenge_method=S256&
  scope=read+write

Token Exchange

http
POST /api/v1/oauth-proxy/{proxy_id}/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&
code={auth_code}&
redirect_uri={redirect_uri}&
client_id={client_id}&
client_secret={client_secret}&
code_verifier={verifier}

Response:

json
{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "gw_refresh_...",
  "scope": "read write"
}

Token Refresh

http
POST /api/v1/oauth-proxy/{proxy_id}/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&
refresh_token={refresh_token}&
client_id={client_id}&
client_secret={client_secret}

Well-Known Endpoints

http
GET /.well-known/oauth-authorization-server?proxy_id={proxy_id}

Returns OAuth server metadata (endpoints, supported methods, etc.)

Code Snippets

JavaScript: PKCE Generation

javascript
// Generate code verifier
function generateCodeVerifier() {
  const array = new Uint8Array(32);
  crypto.getRandomValues(array);
  return btoa(String.fromCharCode(...array))
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=/g, '');
}

// Generate code challenge
async function generateCodeChallenge(verifier) {
  const encoder = new TextEncoder();
  const data = encoder.encode(verifier);
  const digest = await crypto.subtle.digest('SHA-256', data);
  return btoa(String.fromCharCode(...new Uint8Array(digest)))
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=/g, '');
}

JavaScript: Authorization URL

javascript
const authURL = new URL(`https://gateway.com/api/v1/oauth-proxy/${proxyID}/authorize`);
authURL.searchParams.set('response_type', 'code');
authURL.searchParams.set('client_id', clientID);
authURL.searchParams.set('redirect_uri', redirectURI);
authURL.searchParams.set('state', state);
authURL.searchParams.set('code_challenge', codeChallenge);
authURL.searchParams.set('code_challenge_method', 'S256');

JavaScript: Token Exchange

javascript
const response = await fetch(`https://gateway.com/api/v1/oauth-proxy/${proxyID}/token`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: new URLSearchParams({
    grant_type: 'authorization_code',
    code: code,
    redirect_uri: redirectURI,
    client_id: clientID,
    client_secret: clientSecret,
    code_verifier: codeVerifier
  })
});
const tokens = await response.json();

JavaScript: MCP Request

javascript
const response = await fetch('https://gateway.com:9001/mcp', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${gatewayJWT}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    jsonrpc: '2.0',
    method: 'tools/list',
    params: {},
    id: Math.random().toString(36)
  })
});

Python: PKCE Generation

python
import secrets
import hashlib
import base64

def generate_code_verifier():
    return base64.urlsafe_b64encode(secrets.token_bytes(32)).decode().rstrip('=')

def generate_code_challenge(verifier):
    digest = hashlib.sha256(verifier.encode()).digest()
    return base64.urlsafe_b64encode(digest).decode().rstrip('=')

Python: Token Exchange

python
import requests

response = requests.post(
    f'https://gateway.com/api/v1/oauth-proxy/{proxy_id}/token',
    data={
        'grant_type': 'authorization_code',
        'code': code,
        'redirect_uri': redirect_uri,
        'client_id': client_id,
        'client_secret': client_secret,
        'code_verifier': code_verifier
    }
)
tokens = response.json()

OAuth Proxy Configuration Reference

Gateway Proxy Configuration

json
{
  "config": {
    "oauth_proxy_enabled": true,
    "oauth_proxy_mode": "gateway",
    "oauth_proxy_provider_id": 1,
    "oauth_proxy_allowed_redirects": [
      "https://your-app.com/callback"
    ],
    "oauth_proxy_require_consent": false
  }
}

OAuth Proxy Provider Configuration

yaml
Provider Type: okta  # or google, github, azure_ad
Client ID: your-client-id
Client Secret: your-client-secret
Authorization URL: https://provider.com/oauth/authorize
Token URL: https://provider.com/oauth/token
Scopes: read write

Common Errors

ErrorCauseSolution
invalid_redirect_uriRedirect URI not in allowed listAdd to oauth_proxy_allowed_redirects
invalid_grantPKCE validation failedVerify code_verifier matches challenge
invalid_clientClient credentials invalidCheck client_id and client_secret
unauthorized_clientClient not registeredRegister client via DCR endpoint
access_deniedUser denied consentUser must approve OAuth flow

OAuth Proxy Token Storage

Secure Storage Pattern

javascript
// Encrypt before storing
const encrypted = await encrypt(JSON.stringify(tokenData), key);
await db.store(userId, { token: encrypted });

// Decrypt when retrieving
const encrypted = await db.retrieve(userId);
const tokenData = JSON.parse(await decrypt(encrypted, key));

OAuth Proxy Testing

Manual OAuth Flow Test

bash
# 1. Get authorization URL
curl "https://gateway.com/api/v1/oauth-proxy/1/authorize?\
  response_type=code&\
  client_id=CLIENT_ID&\
  redirect_uri=https://app.com/callback&\
  state=test123"

# 2. Exchange code (after redirect)
curl -X POST https://gateway.com/api/v1/oauth-proxy/1/token \
  -d "grant_type=authorization_code" \
  -d "code=AUTH_CODE" \
  -d "client_id=CLIENT_ID" \
  -d "client_secret=CLIENT_SECRET" \
  -d "code_verifier=VERIFIER"

Quick Checklist

  • [ ] OAuth provider configured in Gateway
  • [ ] MCP proxy created with OAuth Proxy enabled
  • [ ] Client registered via DCR
  • [ ] PKCE implementation (code verifier + challenge)
  • [ ] OAuth flow implemented (authorize → callback → token exchange)
  • [ ] Gateway JWT stored securely
  • [ ] MCP requests include Authorization: Bearer {jwt} header
  • [ ] Error handling implemented
  • [ ] Token refresh logic (optional)