mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-06-05 22:44:17 +00:00
2d1b04c637
* 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
14 KiB
14 KiB
OIDC Provider Configuration Guide
Configuration reference for each supported OIDC provider.
Table of Contents
- Provider Support Matrix
- Microsoft Azure AD
- Auth0
- Okta
- Keycloak
- AWS Cognito
- GitLab
- GitHub
- Generic OIDC
- Automatic Scope Filtering
Provider Support Matrix
| Provider | OIDC Support | Refresh Tokens | Auto-Detection | ID Tokens |
|---|---|---|---|---|
| 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 |
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=offlineandprompt=consent - Scope filtering: Automatically removes unsupported
offline_accessscope - Workspace domains: Restrict to specific Google Workspace domains via
hdclaim
Google Cloud Console Setup
- Go to Google Cloud Console
- Create or select a project
- Navigate to APIs & Services > Credentials
- Create OAuth 2.0 Client ID (Web application)
- Add authorized redirect URI:
https://your-domain.com/oauth2/callback - 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
- Go to Azure Portal
- Navigate to Azure Active Directory > App registrations
- Create new registration
- Add redirect URI:
https://your-domain.com/oauth2/callback - Create client secret in Certificates & secrets
- 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
- Go to Auth0 Dashboard
- Create Regular Web Application
- Configure Allowed Callback URLs:
https://your-domain.com/oauth2/callback - Configure Allowed Logout URLs:
https://your-domain.com/oauth2/logout - Enable OIDC Conformant in Advanced Settings
- 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
- Access Okta Admin Console
- Go to Applications > Create App Integration
- Select OIDC - OpenID Connect > Web Application
- Configure Sign-in redirect URIs:
https://your-domain.com/oauth2/callback - Configure Sign-out redirect URIs:
https://your-domain.com/oauth2/logout - Enable Authorization Code and Refresh Token grant types
- 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
- Access Keycloak Admin Console
- Select your realm
- Go to Clients > Create client
- Set Client Protocol: openid-connect
- Set Access Type: confidential
- Add Valid Redirect URIs:
https://your-domain.com/oauth2/callback - Generate client secret in Credentials tab
- 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
- Create Cognito User Pool
- Create App Client with OIDC scopes
- 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
- Callback URLs:
- Configure hosted UI domain (optional)
- 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
- Go to GitLab Settings > Applications
- Create new application
- Add scopes:
openid,profile,email - Set redirect URI:
https://your-domain.com/oauth2/callback - 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
- Go to GitHub Settings > Developer settings > OAuth Apps
- Create new OAuth App
- Set Authorization callback URL:
https://your-domain.com/oauth2/callback - 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-configurationendpoint - 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
- Fetches provider's
.well-known/openid-configuration - Extracts
scopes_supportedfield - Filters requested scopes to only include supported ones
- 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:
- Read GitLab's discovery document
- Detect
offline_accessis NOT inscopes_supported - Filter it out automatically
- 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:
- Check the provider's discovery document:
curl https://provider/.well-known/openid-configuration - Use
overrideScopes: truewith only supported scopes - Review middleware debug logs for filtering decisions