OAuth2 and OIDC Authentication
This document describes the OAuth2 and OpenID Connect (OIDC) authentication implementation for Docling Pipelines.
Overview
The authentication system supports:
- OAuth2 Authorization Code Flow with PKCE support
- OpenID Connect (OIDC) for identity verification
- JWT token validation with JWKS
- Multiple providers: Google, Azure AD, and generic OIDC providers
- Flexible authentication: Support for both Bearer tokens and OAuth2 tokens
Features
Supported Providers
- Google OAuth2
- Pre-configured endpoints
- Automatic OIDC discovery
-
ID token validation
-
Azure AD (Microsoft)
- Multi-tenant support
- Azure AD v2.0 endpoints
-
Microsoft Graph integration
-
Generic OIDC
- Works with any OIDC-compliant provider
- Manual endpoint configuration
- Supports Okta, Auth0, Keycloak, GitLab, etc.
Security Features
- State parameter for CSRF protection
- JWT signature verification using JWKS
- Token expiration validation
- Issuer and audience validation
- Secure token storage (in-memory, can be extended to Redis)
Installation
Required Dependencies
The following packages are already included in requirements.txt:
- httpx>=0.28.1 - HTTP client for OAuth2 requests
- python-jose[cryptography] - JWT token handling
- pydantic-settings>=2.12.0 - Configuration management
- fastapi>=0.128.8 - Web framework
Configuration
1. Environment Variables
Copy .env.oauth2.example to .env and configure:
cp .env.oauth2.example .env
2. Google OAuth2 Setup
OAUTH2_ENABLED=true
OAUTH2_PROVIDER=google
OAUTH2_CLIENT_ID=your-client-id.apps.googleusercontent.com
OAUTH2_CLIENT_SECRET=your-client-secret
OAUTH2_REDIRECT_URI=http://localhost:8000/auth/oauth2/callback
JWT_SECRET_KEY=your-jwt-secret-key
Setup Steps:
1. Go to Google Cloud Console
2. Create a new project or select existing
3. Enable Google+ API
4. Create OAuth 2.0 credentials
5. Add authorized redirect URI: http://localhost:8000/auth/oauth2/callback
6. Copy Client ID and Client Secret
3. Azure AD Setup
OAUTH2_ENABLED=true
OAUTH2_PROVIDER=azure
AZURE_TENANT_ID=your-tenant-id
OAUTH2_CLIENT_ID=your-application-id
OAUTH2_CLIENT_SECRET=your-client-secret
OAUTH2_REDIRECT_URI=http://localhost:8000/auth/oauth2/callback
JWT_SECRET_KEY=your-jwt-secret-key
Setup Steps:
1. Go to Azure Portal
2. Navigate to Azure Active Directory > App registrations
3. Create new registration
4. Add redirect URI: http://localhost:8000/auth/oauth2/callback
5. Create client secret under Certificates & secrets
6. Copy Application (client) ID, Directory (tenant) ID, and client secret
4. Generic OIDC Provider
OAUTH2_ENABLED=true
OAUTH2_PROVIDER=generic
OAUTH2_DISCOVERY_URL=https://your-provider.com/.well-known/openid-configuration
OAUTH2_CLIENT_ID=your-client-id
OAUTH2_CLIENT_SECRET=your-client-secret
OAUTH2_REDIRECT_URI=http://localhost:8000/auth/oauth2/callback
OIDC_ISSUER=https://your-provider.com
OIDC_AUDIENCE=your-client-id
JWT_SECRET_KEY=your-jwt-secret-key
API Endpoints
OAuth2 Endpoints
1. Initiate Authorization
GET /auth/oauth2/authorize?provider=google
Redirects to OAuth2 provider's authorization page.
Query Parameters:
- provider (optional): Provider name (google, azure, generic)
- redirect_after (optional): URL to redirect after successful login
2. OAuth2 Callback
GET /auth/oauth2/callback?code=xxx&state=xxx&provider=google
Handles OAuth2 callback and exchanges code for token.
Response:
{
"access_token": "ey...",
"token_type": "bearer"
}
3. List Available Providers
GET /auth/oauth2/providers
Returns list of configured OAuth2 providers.
4. OIDC Discovery
GET /auth/oauth2/discovery/{provider}
Returns OIDC discovery document for a provider.
Existing Endpoints
Get Current User
GET /auth/me
Authorization: Bearer <token>
Returns current authenticated user information.
Protected Route Example
GET /protected
Authorization: Bearer <token>
Example protected endpoint requiring authentication.
Usage Examples
1. Web Application Flow
import httpx
# Step 1: Redirect user to authorization URL
auth_url = "http://localhost:8000/auth/oauth2/authorize?provider=google"
# Step 2: User completes OAuth2 flow in browser
# User is redirected to /auth/oauth2/callback with code and state
# Step 3: Use the returned access token
token = "eyJ..."
# Step 4: Make authenticated requests
async with httpx.AsyncClient() as client:
response = await client.get(
"http://localhost:8000/auth/me",
headers={"Authorization": f"Bearer {token}"}
)
user = response.json()
print(f"Logged in as: {user['username']}")
2. Testing with cURL
# Step 1: Get authorization URL (open in browser)
curl http://localhost:8000/auth/oauth2/authorize?provider=google
# Step 2: After OAuth2 flow, you'll receive a token
TOKEN="your-access-token-here"
# Step 3: Use token to access protected endpoints
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:8000/auth/me
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:8000/protected
Architecture
Components
- OAuth2Config (
oauth2_config.py) - Configuration management for OAuth2 providers
- Provider-specific settings (Google, Azure, Generic)
-
Environment variable loading
-
OAuth2Provider (
oauth2_provider.py) - Base provider class with common OAuth2 logic
- OIDC discovery and JWKS fetching
- Token validation and user extraction
-
Provider implementations: GoogleOAuth2Provider, AzureADOAuth2Provider, GenericOIDCProvider
-
OAuth2Routes (
oauth2_routes.py) - FastAPI router with OAuth2 endpoints
- Authorization flow handling
- Callback processing
-
State management
-
Dependencies (
dependencies.py) - FastAPI dependencies for authentication
- Token validation
- User extraction from tokens
- Flexible authentication (Bearer + OAuth2)
Authentication Flow
1. User → GET /auth/oauth2/authorize
2. Server → Redirect to OAuth2 Provider
3. User → Authenticates with Provider
4. Provider → Redirect to /auth/oauth2/callback?code=xxx&state=xxx
5. Server → Exchange code for tokens
6. Server → Validate ID token
7. Server → Extract user info
8. Server → Create JWT token
9. Server → Return JWT to user
10. User → Use JWT for API requests
Security Considerations
Production Deployment
-
Use HTTPS: Always use HTTPS in production
env OAUTH2_REDIRECT_URI=https://your-domain.com/auth/oauth2/callback -
Secure JWT Secret: Use a strong, random secret key
bash python -c "import secrets; print(secrets.token_urlsafe(32))" -
State Storage: Use Redis or database for state storage in production
-
Token Expiration: Configure appropriate token expiration
env JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30 OAUTH2_SESSION_EXPIRE_MINUTES=60 -
CORS Configuration: Restrict allowed origins
env CORS_ORIGINS=https://your-frontend.com
Best Practices
- Always validate state parameter
- Use PKCE for public clients
- Implement token refresh mechanism
- Store tokens securely (HttpOnly cookies for web apps)
- Implement rate limiting on auth endpoints
- Log authentication events
- Monitor for suspicious activity
Troubleshooting
Common Issues
- Invalid redirect URI
- Ensure redirect URI matches exactly in provider settings
-
Include protocol (http/https) and port
-
Token validation fails
- Check OIDC_ISSUER matches provider's issuer
- Verify OIDC_AUDIENCE is set correctly
-
Ensure system time is synchronized
-
State parameter invalid
- State expires after use
- Don't reuse authorization URLs
-
Check state storage implementation
-
JWKS fetch fails
- Verify OAUTH2_JWKS_URI is accessible
- Check network connectivity
- Ensure provider's JWKS endpoint is available