Single Sign-On (SSO) Authentication¶
MCP Gateway supports enterprise Single Sign-On authentication through OAuth2 and OpenID Connect (OIDC) providers. This enables seamless integration with existing identity providers while maintaining backward compatibility with local authentication.
Overview¶
The SSO system provides:
- Multi-Provider Support: GitHub, Google, IBM Security Verify, and Okta
- Hybrid Authentication: SSO alongside preserved local admin authentication
- Automatic User Provisioning: Creates users on first SSO login
- Security Best Practices: PKCE, CSRF protection, encrypted secrets
- Team Integration: Automatic team assignment and inheritance
- Admin Management: Full CRUD API for provider configuration
Architecture¶
Authentication Flows¶
sequenceDiagram
participant U as User
participant G as Gateway
participant P as SSO Provider
participant D as Database
U->>G: GET /auth/sso/login/github
G->>D: Create auth session
G->>U: Redirect to provider with PKCE
U->>P: Authenticate with provider
P->>G: Callback with auth code
G->>P: Exchange code for tokens (PKCE)
P->>G: Access token + user info
G->>D: Create/update user
G->>U: Set JWT cookie + redirect
Database Schema¶
SSOProvider Table: - Provider configuration (OAuth endpoints, client credentials) - Encrypted client secrets using Fernet encryption - Trusted domains and team mapping rules
SSOAuthSession Table: - Temporary session tracking during OAuth flow - CSRF state parameters and PKCE verifiers - 10-minute expiration for security
Supported Providers¶
GitHub OAuth¶
Perfect for developer-focused organizations with GitHub repositories.
Features: - GitHub organization mapping to teams - Repository access integration - Developer-friendly onboarding
Google OAuth/OIDC¶
Ideal for Google Workspace organizations.
Features: - Google Workspace domain verification - GSuite organization mapping - Professional email verification
IBM Security Verify¶
Enterprise-grade identity provider with advanced security features.
Features: - Enterprise SSO compliance - Advanced user attributes - Corporate directory integration
Okta¶
Popular enterprise identity provider with extensive integrations.
Features: - Enterprise directory synchronization - Multi-factor authentication support - Custom user attributes
Quick Start¶
1. Enable SSO¶
Set the master SSO switch in your environment:
# Enable SSO system
SSO_ENABLED=true
# Optional: Keep local admin authentication (recommended)
SSO_PRESERVE_ADMIN_AUTH=true
2. Configure GitHub OAuth (Example)¶
Register OAuth App¶
- Go to GitHub β Settings β Developer settings β OAuth Apps
- Click "New OAuth App"
- Set Authorization callback URL:
https://your-gateway.com/auth/sso/callback/github
- Note the Client ID and Client Secret
Environment Configuration¶
# GitHub OAuth Configuration
SSO_GITHUB_ENABLED=true
SSO_GITHUB_CLIENT_ID=your-github-client-id
SSO_GITHUB_CLIENT_SECRET=your-github-client-secret
# Optional: Auto-create users and trusted domains
SSO_AUTO_CREATE_USERS=true
SSO_TRUSTED_DOMAINS=["yourcompany.com", "github.com"]
Start Gateway¶
3. Test SSO Flow¶
List Available Providers¶
Response:
Initiate SSO Login¶
Response:
{
"authorization_url": "https://github.com/login/oauth/authorize?client_id=...",
"state": "csrf-protection-token"
}
Provider Configuration¶
GitHub OAuth Setup¶
1. Create OAuth App¶
- GitHub Settings β Developer settings β OAuth Apps
- New OAuth App:
- Application name:
MCP Gateway - YourOrg
- Homepage URL:
https://your-gateway.com
- Authorization callback URL:
https://your-gateway.com/auth/sso/callback/github
2. Environment Variables¶
# GitHub OAuth Configuration
SSO_GITHUB_ENABLED=true
SSO_GITHUB_CLIENT_ID=Iv1.a1b2c3d4e5f6g7h8
SSO_GITHUB_CLIENT_SECRET=1234567890abcdef1234567890abcdef12345678
# Organization-based team mapping (optional)
GITHUB_ORG_TEAM_MAPPING={"your-github-org": "developers-team-id"}
3. Team Mapping (Advanced)¶
Map GitHub organizations to Gateway teams:
{
"team_mapping": {
"your-github-org": {
"team_id": "dev-team-uuid",
"role": "member"
},
"admin-github-org": {
"team_id": "admin-team-uuid",
"role": "owner"
}
}
}
Google OAuth Setup¶
1. Google Cloud Console Setup¶
- Google Cloud Console β APIs & Services β Credentials
- Create Credentials β OAuth client ID
- Application type: Web application
- Authorized redirect URIs:
https://your-gateway.com/auth/sso/callback/google
2. Environment Variables¶
# Google OAuth Configuration
SSO_GOOGLE_ENABLED=true
SSO_GOOGLE_CLIENT_ID=123456789012-abcdefghijklmnop.apps.googleusercontent.com
SSO_GOOGLE_CLIENT_SECRET=GOCSPX-1234567890abcdefghijklmnop
# Google Workspace domain restrictions
SSO_TRUSTED_DOMAINS=["yourcompany.com"]
IBM Security Verify Setup¶
1. IBM Security Verify Configuration¶
- IBM Security Verify Admin Console β Applications
- Add application β Custom Application
- Sign-on β Open ID Connect
- Redirect URI:
https://your-gateway.com/auth/sso/callback/ibm_verify
2. Environment Variables¶
# IBM Security Verify OIDC Configuration
SSO_IBM_VERIFY_ENABLED=true
SSO_IBM_VERIFY_CLIENT_ID=your-client-id
SSO_IBM_VERIFY_CLIENT_SECRET=your-client-secret
SSO_IBM_VERIFY_ISSUER=https://your-tenant.verify.ibm.com/oidc/endpoint/default
Okta Setup¶
1. Okta Admin Console¶
- Applications β Create App Integration
- OIDC - OpenID Connect β Web Application
- Sign-in redirect URIs:
https://your-gateway.com/auth/sso/callback/okta
2. Environment Variables¶
# Okta OIDC Configuration
SSO_OKTA_ENABLED=true
SSO_OKTA_CLIENT_ID=0oa1b2c3d4e5f6g7h8i9
SSO_OKTA_CLIENT_SECRET=1234567890abcdef1234567890abcdef12345678
SSO_OKTA_ISSUER=https://your-company.okta.com
Advanced Configuration¶
Trusted Domains¶
Restrict SSO access to specific email domains:
# JSON array of trusted domains
SSO_TRUSTED_DOMAINS=["yourcompany.com", "partner.org", "contractor.net"]
Only users with email addresses from these domains can authenticate via SSO.
Auto User Creation¶
Control automatic user provisioning:
# Enable automatic user creation (default: true)
SSO_AUTO_CREATE_USERS=true
# Disable to manually approve SSO users
SSO_AUTO_CREATE_USERS=false
Team Mapping Rules¶
Configure automatic team assignment based on SSO provider attributes:
{
"team_mapping": {
"github_org_name": {
"team_id": "uuid-of-gateway-team",
"role": "member",
"conditions": {
"email_domain": "company.com"
}
},
"google_workspace_domain": {
"team_id": "uuid-of-workspace-team",
"role": "owner",
"conditions": {
"email_verified": true
}
}
}
}
API Reference¶
Public Endpoints¶
List Available Providers¶
Response:
Initiate SSO Login¶
Parameters: - provider_id
: Provider identifier (github
, google
, ibm_verify
, okta
) - redirect_uri
: Callback URL after authentication - scopes
: Optional space-separated OAuth scopes
Response:
{
"authorization_url": "https://provider.com/oauth/authorize?...",
"state": "csrf-protection-token"
}
Handle SSO Callback¶
This endpoint is called by the SSO provider after user authentication.
Response:
{
"access_token": "jwt-session-token",
"token_type": "bearer",
"expires_in": 604800,
"user": {
"email": "user@example.com",
"full_name": "John Doe",
"provider": "github"
}
}
Admin Endpoints¶
All admin endpoints require admin.sso_providers
permissions.
Create SSO Provider¶
POST /auth/sso/admin/providers
Authorization: Bearer <admin-jwt-token>
Content-Type: application/json
{
"id": "custom_provider",
"name": "custom_provider",
"display_name": "Custom Provider",
"provider_type": "oidc",
"client_id": "client-id",
"client_secret": "client-secret",
"authorization_url": "https://provider.com/oauth/authorize",
"token_url": "https://provider.com/oauth/token",
"userinfo_url": "https://provider.com/oauth/userinfo",
"issuer": "https://provider.com",
"scope": "openid profile email",
"trusted_domains": ["company.com"],
"auto_create_users": true
}
List All Providers¶
Update Provider¶
PUT /auth/sso/admin/providers/{provider_id}
Authorization: Bearer <admin-jwt-token>
Content-Type: application/json
{
"display_name": "Updated Provider Name",
"is_enabled": false
}
Delete Provider¶
Security Considerations¶
Client Secret Encryption¶
Client secrets are encrypted using Fernet (AES 128) before database storage:
# Automatic encryption in SSOService
provider_data["client_secret_encrypted"] = self._encrypt_secret(client_secret)
PKCE Protection¶
All OAuth flows use PKCE (Proof Key for Code Exchange) for enhanced security:
CSRF Protection¶
OAuth state parameters prevent cross-site request forgery:
Session Security¶
- HTTP-only cookies prevent XSS attacks
- Secure flag for HTTPS deployments
- SameSite=Lax protection
- 10-minute OAuth session expiration
Troubleshooting¶
Common Issues¶
SSO Endpoints Return 404¶
Problem: SSO routes not available Solution: Ensure SSO_ENABLED=true
and restart gateway
# Check SSO status
curl -I http://localhost:8000/auth/sso/providers
# Should return 200 if enabled, 404 if disabled
OAuth Callback Errors¶
Problem: Invalid redirect URI Solution: Verify callback URL matches provider configuration exactly
# Correct format
https://your-gateway.com/auth/sso/callback/github
# Common mistakes
https://your-gateway.com/auth/sso/callback/github/ # Extra slash
http://your-gateway.com/auth/sso/callback/github # HTTP instead of HTTPS
User Creation Fails¶
Problem: Email domain not trusted Solution: Add domain to trusted domains list
Debug Mode¶
Enable verbose SSO logging:
Check logs for detailed OAuth flow information:
Health Checks¶
Verify SSO provider connectivity:
# Test provider endpoints
curl -I https://github.com/login/oauth/authorize
curl -I https://github.com/login/oauth/access_token
curl -I https://api.github.com/user
Migration Guide¶
From Local Auth Only¶
-
Enable SSO alongside existing authentication:
-
Configure first provider (e.g., GitHub)
-
Test SSO flow with test users
-
Gradually migrate production users
-
Optional: Disable local auth after full migration
Adding New Providers¶
-
Implement provider-specific user info normalization in
SSOService._normalize_user_info
-
Add environment variables in
config.py
-
Update bootstrap utilities in
sso_bootstrap.py
-
Test integration thoroughly
Best Practices¶
Production Deployment¶
- Use HTTPS for all SSO callbacks
- Secure client secrets in vault/secret management
- Monitor failed authentications
- Regular secret rotation
- Audit SSO access logs
User Experience¶
- Clear provider labeling (GitHub, Google, etc.)
- Graceful error handling for auth failures
- Fallback to local auth if SSO unavailable
- User session management
Security Hardening¶
- Restrict trusted domains to organization emails
- Enable audit logging for admin operations
- Regular provider configuration reviews
- Monitor unusual auth patterns
Integration Examples¶
Frontend Integration¶
// Check available SSO providers
const providers = await fetch('/auth/sso/providers').then(r => r.json());
// Initiate SSO login
const redirectUrl = `${window.location.origin}/dashboard`;
const ssoResponse = await fetch(
`/auth/sso/login/github?redirect_uri=${encodeURIComponent(redirectUrl)}`
).then(r => r.json());
// Redirect user to SSO provider
window.location.href = ssoResponse.authorization_url;
CLI Integration¶
#!/bin/bash
# CLI SSO authentication helper
GATEWAY_URL="https://your-gateway.com"
PROVIDER="github"
# Get authorization URL
AUTH_RESPONSE=$(curl -s "$GATEWAY_URL/auth/sso/login/$PROVIDER?redirect_uri=urn:ietf:wg:oauth:2.0:oob")
AUTH_URL=$(echo "$AUTH_RESPONSE" | jq -r '.authorization_url')
echo "Open this URL in your browser:"
echo "$AUTH_URL"
echo "Enter the authorization code:"
read -r AUTH_CODE
# Exchange code for token (manual callback simulation)
# Note: In practice, this would be handled by the callback endpoint
API Client Integration¶
import requests
import webbrowser
from urllib.parse import urlparse, parse_qs
# SSO authentication for API clients
class SSOAuthenticator:
def __init__(self, gateway_url, provider):
self.gateway_url = gateway_url
self.provider = provider
def authenticate(self):
# Get authorization URL
response = requests.get(
f"{self.gateway_url}/auth/sso/login/{self.provider}",
params={"redirect_uri": "http://localhost:8080/callback"}
)
auth_data = response.json()
# Open browser for user authentication
webbrowser.open(auth_data["authorization_url"])
# Wait for callback (implement callback server)
# Return JWT token for API access
return self.handle_callback()