docling-pipelines

OAuth2 and OIDC Authentication

This document describes the OAuth2 and OpenID Connect (OIDC) authentication implementation for Docling Pipelines.

Overview

The authentication system supports:

Features

Supported Providers

  1. Google OAuth2
    • Pre-configured endpoints
    • Automatic OIDC discovery
    • ID token validation
  2. Azure AD (Microsoft)
    • Multi-tenant support
    • Azure AD v2.0 endpoints
    • Microsoft Graph integration
  3. Generic OIDC
    • Works with any OIDC-compliant provider
    • Manual endpoint configuration
    • Supports Okta, Auth0, Keycloak, GitLab, etc.

Security Features

Installation

Required Dependencies

The following packages are already included in requirements.txt:

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:

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

  1. OAuth2Config (oauth2_config.py)
    • Configuration management for OAuth2 providers
    • Provider-specific settings (Google, Azure, Generic)
    • Environment variable loading
  2. 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
  3. OAuth2Routes (oauth2_routes.py)
    • FastAPI router with OAuth2 endpoints
    • Authorization flow handling
    • Callback processing
    • State management
  4. 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

  1. Use HTTPS: Always use HTTPS in production
    OAUTH2_REDIRECT_URI=https://your-domain.com/auth/oauth2/callback
    
  2. Secure JWT Secret: Use a strong, random secret key
    python -c "import secrets; print(secrets.token_urlsafe(32))"
    
  3. State Storage: Use Redis or database for state storage in production

  4. Token Expiration: Configure appropriate token expiration
    JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30
    OAUTH2_SESSION_EXPIRE_MINUTES=60
    
  5. CORS Configuration: Restrict allowed origins
    CORS_ORIGINS=https://your-frontend.com
    

Best Practices

Troubleshooting

Common Issues

  1. Invalid redirect URI
    • Ensure redirect URI matches exactly in provider settings
    • Include protocol (http/https) and port
  2. Token validation fails
    • Check OIDC_ISSUER matches provider’s issuer
    • Verify OIDC_AUDIENCE is set correctly
    • Ensure system time is synchronized
  3. State parameter invalid
    • State expires after use
    • Don’t reuse authorization URLs
    • Check state storage implementation
  4. JWKS fetch fails
    • Verify OAUTH2_JWKS_URI is accessible
    • Check network connectivity
    • Ensure provider’s JWKS endpoint is available

Additional Resources