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+writeToken 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 writeCommon Errors
| Error | Cause | Solution |
|---|---|---|
invalid_redirect_uri | Redirect URI not in allowed list | Add to oauth_proxy_allowed_redirects |
invalid_grant | PKCE validation failed | Verify code_verifier matches challenge |
invalid_client | Client credentials invalid | Check client_id and client_secret |
unauthorized_client | Client not registered | Register client via DCR endpoint |
access_denied | User denied consent | User 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)