Files
traefikoidc/docs/PROVIDERS.md
T
lukaszraczylo 2d1b04c637 review fixes apr 2026 (#130)
* Multiple fixes

- refresh coordinator dedup + memory pressure wire
- middleware sse consolidation + timer leak + claim cache
- universal cache sync backfill + isDebug gate
- lazy background task race
- memory monitor stw cached + refresh() api

* fix(auth): suppress OIDC redirects on non-navigation requests

- [x] Add isNonNavigationRequest using Sec-Fetch-Mode and Accept headers
- [x] Add comprehensive TestIsNonNavigationRequest
- [x] Update ServeHTTP to 401 non-navigation and AJAX requests

Fixes #129

* feat(config): add custom CA and insecure skip verify for OIDC TLS

- [x] Add CACertPath, CACertPEM, InsecureSkipVerify to Config
- [x] Implement loadCACertPool for CA bundle loading
- [x] Update HTTPClientConfig with RootCAs and InsecureSkipVerify
- [x] Apply CA pool and skip verify to pooled HTTP clients
- [x] Enhance configKey to distinguish TLS configs
- [x] Add comprehensive ca_cert_test.go

Fixes #125

* feat(oidc): add custom CA certificate support for private OIDC providers

- [x] Add caCertPath, caCertPEM, insecureSkipVerify config options
- [x] Update traefik.yml with new OIDC client config fields
- [x] Add configuration schema descriptions for new options
- [x] Update README table and add Custom CA Certificates section

* Fix the documentation.

* test(redis): add oversized argument rejection test

- [x] Add TestRedisConn_RejectOversizedArgumentBytes
- [x] Import strings package

* Dependencies cleanup
2026-04-19 10:12:00 +01:00

14 KiB

OIDC Provider Configuration Guide

Configuration reference for each supported OIDC provider.

Table of Contents


Provider Support Matrix

Provider OIDC Support Refresh Tokens Auto-Detection ID Tokens
Google Full Yes accounts.google.com Yes
Azure AD Full Yes login.microsoftonline.com, sts.windows.net Yes
Auth0 Full Yes *.auth0.com Yes
Okta Full Yes *.okta.com, *.oktapreview.com, *.okta-emea.com Yes
Keycloak Full Yes host containing keycloak, or /realms/ in path (matches both /auth/realms/ legacy and /realms/ modern) Yes
AWS Cognito Full Yes cognito-idp.*.amazonaws.com Yes
GitLab Full Yes gitlab.com Yes
GitHub OAuth 2.0 Only No github.com No
Generic Full Yes Any OIDC endpoint Yes

Google

Provider URL

providerURL: "https://accounts.google.com"

Configuration

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oidc-google
spec:
  plugin:
    traefikoidc:
      providerURL: "https://accounts.google.com"
      clientID: "your-id.apps.googleusercontent.com"
      clientSecret: "your-client-secret"
      callbackURL: "/oauth2/callback"
      sessionEncryptionKey: "your-32-char-encryption-key-here"
      scopes:
        - openid
        - email
        - profile
      allowedUserDomains:
        - "your-gsuite-domain.com"  # Optional: Workspace restriction
      forceHttps: true
      enablePkce: true

Google-Specific Features

  • Automatic offline access: Middleware adds access_type=offline and prompt=consent
  • Scope filtering: Automatically removes unsupported offline_access scope
  • Workspace domains: Restrict to specific Google Workspace domains via hd claim

Google Cloud Console Setup

  1. Go to Google Cloud Console
  2. Create or select a project
  3. Navigate to APIs & Services > Credentials
  4. Create OAuth 2.0 Client ID (Web application)
  5. Add authorized redirect URI: https://your-domain.com/oauth2/callback
  6. Configure OAuth consent screen (must be "Published" for production)

Microsoft Azure AD

Provider URL

# Single tenant
providerURL: "https://login.microsoftonline.com/{tenant-id}/v2.0"

# Multi-tenant
providerURL: "https://login.microsoftonline.com/common/v2.0"

Basic Configuration

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oidc-azure
spec:
  plugin:
    traefikoidc:
      providerURL: "https://login.microsoftonline.com/common/v2.0"
      clientID: "your-azure-client-id"
      clientSecret: "your-azure-client-secret"
      callbackURL: "/oauth2/callback"
      sessionEncryptionKey: "your-32-char-encryption-key-here"
      scopes:
        - openid
        - profile
        - email
        - offline_access
      allowedRolesAndGroups:
        - "App.Users"
        - "Admin.Group"
      forceHttps: true

With Application ID URI (API Access)

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oidc-azure-api
spec:
  plugin:
    traefikoidc:
      providerURL: "https://login.microsoftonline.com/common/v2.0"
      clientID: "your-azure-client-id"
      clientSecret: "your-azure-client-secret"
      audience: "api://your-azure-client-id"  # Application ID URI
      callbackURL: "/oauth2/callback"
      sessionEncryptionKey: "your-32-char-encryption-key-here"
      forceHttps: true

Users Without Email

userIdentifierClaim: sub  # Options: sub, oid, upn, preferred_username
allowedUsers:
  - "user-object-id-1"
  - "user-object-id-2"

Azure AD Setup

  1. Go to Azure Portal
  2. Navigate to Azure Active Directory > App registrations
  3. Create new registration
  4. Add redirect URI: https://your-domain.com/oauth2/callback
  5. Create client secret in Certificates & secrets
  6. Configure Token Configuration for group claims

Auth0

Provider URL

providerURL: "https://your-domain.auth0.com"

Basic Configuration

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oidc-auth0
spec:
  plugin:
    traefikoidc:
      providerURL: "https://your-domain.auth0.com"
      clientID: "your-auth0-client-id"
      clientSecret: "your-auth0-client-secret"
      callbackURL: "/oauth2/callback"
      sessionEncryptionKey: "your-32-char-encryption-key-here"
      scopes:
        - openid
        - profile
        - email
        - offline_access
      postLogoutRedirectUri: "https://your-app.com"
      forceHttps: true
      enablePkce: true

With Custom API Audience

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oidc-auth0-api
spec:
  plugin:
    traefikoidc:
      providerURL: "https://your-domain.auth0.com"
      clientID: "your-auth0-client-id"
      clientSecret: "your-auth0-client-secret"
      audience: "https://api.your-domain.com"  # API identifier
      strictAudienceValidation: true
      callbackURL: "/oauth2/callback"
      sessionEncryptionKey: "your-32-char-encryption-key-here"
      roleClaimName: "https://your-app.com/roles"  # Namespaced claim
      groupClaimName: "https://your-app.com/groups"
      allowedRolesAndGroups:
        - admin
        - editor

Auth0 Action for Custom Claims

exports.onExecutePostLogin = async (event, api) => {
  const namespace = 'https://your-app.com/';
  if (event.authorization) {
    api.idToken.setCustomClaim(namespace + 'roles', event.authorization.roles);
    api.idToken.setCustomClaim('email', event.user.email);
  }
};

Auth0 Setup

  1. Go to Auth0 Dashboard
  2. Create Regular Web Application
  3. Configure Allowed Callback URLs: https://your-domain.com/oauth2/callback
  4. Configure Allowed Logout URLs: https://your-domain.com/oauth2/logout
  5. Enable OIDC Conformant in Advanced Settings
  6. Create API in APIs section for custom audiences

See AUTH0_AUDIENCE_GUIDE.md for detailed audience configuration.


Okta

Provider URL

providerURL: "https://your-domain.okta.com"
# Or with custom authorization server:
providerURL: "https://your-domain.okta.com/oauth2/default"

Configuration

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oidc-okta
spec:
  plugin:
    traefikoidc:
      providerURL: "https://your-domain.okta.com"
      clientID: "your-okta-client-id"
      clientSecret: "your-okta-client-secret"
      callbackURL: "/oauth2/callback"
      sessionEncryptionKey: "your-32-char-encryption-key-here"
      scopes:
        - openid
        - profile
        - email
        - groups
        - offline_access
      allowedRolesAndGroups:
        - admin
        - "Everyone"
      forceHttps: true
      enablePkce: true

Okta Setup

  1. Access Okta Admin Console
  2. Go to Applications > Create App Integration
  3. Select OIDC - OpenID Connect > Web Application
  4. Configure Sign-in redirect URIs: https://your-domain.com/oauth2/callback
  5. Configure Sign-out redirect URIs: https://your-domain.com/oauth2/logout
  6. Enable Authorization Code and Refresh Token grant types
  7. Configure Groups claim in authorization server

Keycloak

Provider URL

providerURL: "https://keycloak.your-domain.com/realms/{realm-name}"

Configuration

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oidc-keycloak
spec:
  plugin:
    traefikoidc:
      providerURL: "https://keycloak.company.com/realms/your-realm"
      clientID: "your-keycloak-client-id"
      clientSecret: "your-keycloak-client-secret"
      callbackURL: "/oauth2/callback"
      sessionEncryptionKey: "your-32-char-encryption-key-here"
      scopes:
        - openid
        - profile
        - email
        - roles
        - groups
        - offline_access
      allowedRolesAndGroups:
        - admin
        - editor
      forceHttps: true
      enablePkce: true

Internal Network Deployment

For private IP addresses (Docker networks, Kubernetes):

providerURL: "https://192.168.1.100:8443/realms/your-realm"
allowPrivateIPAddresses: true  # Required for private IPs

Keycloak Client Setup

  1. Access Keycloak Admin Console
  2. Select your realm
  3. Go to Clients > Create client
  4. Set Client Protocol: openid-connect
  5. Set Access Type: confidential
  6. Add Valid Redirect URIs: https://your-domain.com/oauth2/callback
  7. Generate client secret in Credentials tab
  8. Configure mappers to add claims to ID Token:
    • Email: User Property mapper with "Add to ID token" enabled
    • Roles: User Client Role mapper with "Add to ID token" enabled
    • Groups: Group Membership mapper with "Add to ID token" enabled

See KEYCLOAK_SETUP_GUIDE.md for detailed step-by-step setup instructions, mapper configuration, troubleshooting, and performance optimization.


AWS Cognito

Provider URL

providerURL: "https://cognito-idp.{region}.amazonaws.com/{user-pool-id}"

Configuration

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oidc-cognito
spec:
  plugin:
    traefikoidc:
      providerURL: "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_ABCDEF123"
      clientID: "your-cognito-client-id"
      clientSecret: "your-cognito-client-secret"
      callbackURL: "/oauth2/callback"
      sessionEncryptionKey: "your-32-char-encryption-key-here"
      scopes:
        - openid
        - profile
        - email
        - aws.cognito.signin.user.admin
      allowedRolesAndGroups:
        - admin
        - users
      forceHttps: true

AWS Cognito Setup

  1. Create Cognito User Pool
  2. Create App Client with OIDC scopes
  3. Configure App Client settings:
    • Callback URLs: https://your-domain.com/oauth2/callback
    • Sign out URLs: https://your-domain.com/oauth2/logout
    • OAuth flows: Authorization code grant
  4. Configure hosted UI domain (optional)
  5. Set up groups for role-based access

GitLab

Provider URL

# GitLab.com
providerURL: "https://gitlab.com"

# Self-hosted
providerURL: "https://gitlab.your-company.com"

Configuration

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oidc-gitlab
spec:
  plugin:
    traefikoidc:
      providerURL: "https://gitlab.com"
      clientID: "your-gitlab-application-id"
      clientSecret: "your-gitlab-application-secret"
      callbackURL: "/oauth2/callback"
      sessionEncryptionKey: "your-32-char-encryption-key-here"
      scopes:
        - openid
        - profile
        - email
        # Note: GitLab doesn't require offline_access scope
        # Refresh tokens are issued automatically with openid
      allowedRolesAndGroups:
        - developers
        - maintainers
      forceHttps: true
      enablePkce: true

GitLab Setup

  1. Go to GitLab Settings > Applications
  2. Create new application
  3. Add scopes: openid, profile, email
  4. Set redirect URI: https://your-domain.com/oauth2/callback
  5. Save and note Application ID and Secret

GitHub

Provider URL

providerURL: "https://github.com"

Configuration

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oauth-github
spec:
  plugin:
    traefikoidc:
      providerURL: "https://github.com/login/oauth"
      clientID: "your-github-client-id"
      clientSecret: "your-github-client-secret"
      callbackURL: "/oauth2/callback"
      sessionEncryptionKey: "your-32-char-encryption-key-here"
      scopes:
        - user:email
        - read:user
      allowedUsers:
        - "github-username"
      forceHttps: true

Limitations

  • OAuth 2.0 only - Not OpenID Connect
  • No ID tokens - Only access tokens for API calls
  • No refresh tokens - Users must re-authenticate on expiry
  • No standard claims - User info requires API calls

Use GitHub only for API access, not for user authentication with claims.

GitHub Setup

  1. Go to GitHub Settings > Developer settings > OAuth Apps
  2. Create new OAuth App
  3. Set Authorization callback URL: https://your-domain.com/oauth2/callback
  4. Note Client ID and generate Client Secret

Generic OIDC

For any OIDC-compliant provider not listed above.

Configuration

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oidc-generic
spec:
  plugin:
    traefikoidc:
      providerURL: "https://oidc.your-provider.com"
      clientID: "your-client-id"
      clientSecret: "your-client-secret"
      callbackURL: "/oauth2/callback"
      sessionEncryptionKey: "your-32-char-encryption-key-here"
      scopes:
        - openid
        - profile
        - email
      forceHttps: true
      enablePkce: true

Requirements

  • Provider must expose .well-known/openid-configuration endpoint
  • Must support authorization code flow
  • ID tokens must contain required claims (email, sub, etc.)

Automatic Scope Filtering

The middleware automatically filters OAuth scopes based on the provider's declared capabilities.

How It Works

  1. Fetches provider's .well-known/openid-configuration
  2. Extracts scopes_supported field
  3. Filters requested scopes to only include supported ones
  4. Falls back to all requested scopes if provider doesn't declare supported scopes

Example: Self-Hosted GitLab

Self-hosted GitLab may reject offline_access scope:

scopes:
  - openid
  - profile
  - email
  - offline_access  # Will be automatically filtered out if unsupported

The middleware will:

  1. Read GitLab's discovery document
  2. Detect offline_access is NOT in scopes_supported
  3. Filter it out automatically
  4. Authentication succeeds

Logging

INFO: ScopeFilter: Filtered unsupported scopes: [offline_access]
DEBUG: ScopeFilter: Final filtered scopes: [openid profile email]

Troubleshooting

If a provider rejects scopes even after filtering:

  1. Check the provider's discovery document: curl https://provider/.well-known/openid-configuration
  2. Use overrideScopes: true with only supported scopes
  3. Review middleware debug logs for filtering decisions