Production-ready OIDC authentication middleware. Drop-in replacement for oauth2-proxy and forward-auth with support for 9+ identity providers.
Enterprise-grade authentication for your Traefik deployments
Works with Google, Azure AD, Auth0, Okta, Keycloak, Cognito, GitLab, and any OIDC-compliant provider
Automatically detects and configures provider-specific settings from OIDC discovery
RFC 7591 Dynamic Client Registration for automatic client setup without manual configuration
Intelligently filters OAuth scopes based on provider capabilities from discovery documents
Comprehensive security headers including CORS, CSP, HSTS, and customizable profiles
Limit access to specific email domains, individual users, or role-based groups
Restrict access based on roles and groups from OIDC claims
Secure session handling with proactive token refresh before expiry
Built-in protection against brute force attacks with configurable limits
Template-based headers using OIDC claims and tokens for downstream services
Proof Key for Code Exchange for enhanced security in authorization code flow
Bounded caches with LRU eviction, automatic cleanup, and zero goroutine leaks
Distributed caching with Redis for multi-replica deployments with circuit breaker and health checks
RFC 7662 Token Introspection support for opaque access tokens and enhanced validation
Works with all major identity providers out of the box
Full OIDC
Full OIDC
Full OIDC
Full OIDC
Full OIDC
Full OIDC
Full OIDC
OAuth 2.0
| Feature | Azure AD | Auth0 | Okta | Keycloak | |
|---|---|---|---|---|---|
| ID Tokens | ✓ | ✓ | ✓ | ✓ | ✓ |
| Refresh Tokens | ✓ | ✓ | ✓ | ✓ | ✓ |
| Auto-Configuration | ✓ | ✓ | ✓ | ✓ | ✓ |
| Custom Claims | Limited | ✓ | ✓ | ✓ | ✓ |
| Group/Role Claims | Limited | ✓ | ✓ | ✓ | ✓ |
| Self-Hosted | ✗ | ✗ | ✗ | ✗ | ✓ |
Get started in under 5 minutes
Add to your Traefik static configuration or Docker Compose command:
# docker-compose.yml - Traefik service command
command:
- "--experimental.plugins.traefikoidc.modulename=github.com/lukaszraczylo/traefikoidc"
- "--experimental.plugins.traefikoidc.version=v0.7.10"
# Or in traefik.yml static config
experimental:
plugins:
traefikoidc:
moduleName: github.com/lukaszraczylo/traefikoidc
version: v0.7.10
Add middleware configuration via Docker labels:
# docker-compose.yml - Service labels
labels:
- "traefik.http.middlewares.oidc-auth.plugin.traefikoidc.providerURL=https://accounts.google.com"
- "traefik.http.middlewares.oidc-auth.plugin.traefikoidc.clientID=your-client-id"
- "traefik.http.middlewares.oidc-auth.plugin.traefikoidc.clientSecret=your-client-secret"
- "traefik.http.middlewares.oidc-auth.plugin.traefikoidc.callbackURL=/oauth2/callback"
- "traefik.http.middlewares.oidc-auth.plugin.traefikoidc.sessionEncryptionKey=your-32-byte-secret-key-here!!"
Use the middleware on your services via labels:
# docker-compose.yml - Protected service
services:
my-app:
image: my-app:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.my-app.rule=Host(`app.example.com`)"
- "traefik.http.routers.my-app.middlewares=oidc-auth"
- "traefik.http.routers.my-app.tls=true"
- "traefik.http.routers.my-app.tls.certresolver=letsencrypt"
Flexible options for any deployment scenario
| Parameter | Description |
|---|---|
providerURL |
Base URL of your OIDC provider |
clientID |
OAuth 2.0 client identifier |
clientSecret |
OAuth 2.0 client secret |
sessionEncryptionKey |
32+ byte key for session encryption |
callbackURL |
OAuth callback path (e.g., /oauth2/callback) |
| Parameter | Default | Description |
|---|---|---|
forceHTTPS |
false | Required for TLS termination at load balancer (AWS ALB, etc.) |
allowedUserDomains |
none | Restrict to specific email domains |
allowedUsers |
none | Specific email addresses allowed access |
allowedRolesAndGroups |
none | Restrict to users with specific roles or groups |
roleClaimName |
"roles" | JWT claim for roles (supports namespaced claims like https://myapp.com/roles) |
groupClaimName |
"groups" | JWT claim for groups (supports namespaced claims) |
excludedURLs |
none | Paths that bypass authentication |
enablePKCE |
false | Enable PKCE for enhanced security |
rateLimit |
100 | Maximum requests per second |
sessionMaxAge |
86400 | Maximum session age in seconds (24 hours default) |
cookiePrefix |
_oidc_raczylo_ | Custom prefix for session cookies |
cookieDomain |
auto-detected | Explicit domain for session cookies (multi-subdomain) |
audience |
clientID | Custom audience for access token validation |
strictAudienceValidation |
false | Reject sessions with audience mismatch |
allowOpaqueTokens |
false | Enable opaque (non-JWT) access token support |
requireTokenIntrospection |
false | Require RFC 7662 introspection for opaque tokens |
disableReplayDetection |
false | Disable JTI replay detection (for multi-replica without Redis) |
# docker-compose.yml labels
labels:
- "traefik.http.middlewares.google-oidc.plugin.traefikoidc.providerURL=https://accounts.google.com"
- "traefik.http.middlewares.google-oidc.plugin.traefikoidc.clientID=1234567890.apps.googleusercontent.com"
- "traefik.http.middlewares.google-oidc.plugin.traefikoidc.clientSecret=your-client-secret"
- "traefik.http.middlewares.google-oidc.plugin.traefikoidc.callbackURL=/oauth2/callback"
- "traefik.http.middlewares.google-oidc.plugin.traefikoidc.sessionEncryptionKey=your-32-byte-encryption-key!!"
- "traefik.http.middlewares.google-oidc.plugin.traefikoidc.allowedUserDomains=yourcompany.com,subsidiary.com"
- "traefik.http.middlewares.google-oidc.plugin.traefikoidc.excludedURLs=/health,/metrics,/api/public"
- "traefik.http.middlewares.google-oidc.plugin.traefikoidc.forceHTTPS=true"
- "traefik.http.middlewares.google-oidc.plugin.traefikoidc.logLevel=info"
For multi-replica deployments, use Redis for distributed session and JTI replay detection:
| Parameter | Default | Description |
|---|---|---|
redis.enabled |
false | Enable Redis caching |
redis.address |
- | Redis server address (host:port) |
redis.password |
- | Redis password |
redis.db |
0 | Redis database number |
redis.keyPrefix |
traefikoidc: | Key prefix for namespacing |
redis.cacheMode |
redis | Cache mode: memory, redis, or hybrid |
redis.poolSize |
10 | Connection pool size |
redis.enableCircuitBreaker |
true | Enable circuit breaker for Redis failures |
redis.enableHealthCheck |
true | Enable periodic health checks |
redis.enableTLS |
false | Enable TLS for Redis connections |
# docker-compose.yml labels
labels:
- "traefik.http.middlewares.oidc-secure.plugin.traefikoidc.providerURL=https://accounts.google.com"
- "traefik.http.middlewares.oidc-secure.plugin.traefikoidc.clientID=your-client-id"
- "traefik.http.middlewares.oidc-secure.plugin.traefikoidc.clientSecret=your-client-secret"
- "traefik.http.middlewares.oidc-secure.plugin.traefikoidc.callbackURL=/oauth2/callback"
- "traefik.http.middlewares.oidc-secure.plugin.traefikoidc.sessionEncryptionKey=your-32-byte-encryption-key!!"
- "traefik.http.middlewares.oidc-secure.plugin.traefikoidc.securityHeaders.enabled=true"
- "traefik.http.middlewares.oidc-secure.plugin.traefikoidc.securityHeaders.profile=api"
- "traefik.http.middlewares.oidc-secure.plugin.traefikoidc.securityHeaders.corsEnabled=true"
- "traefik.http.middlewares.oidc-secure.plugin.traefikoidc.securityHeaders.corsAllowCredentials=true"
- "traefik.http.middlewares.oidc-secure.plugin.traefikoidc.securityHeaders.strictTransportSecurity=true"
Production-ready configurations for Docker Compose and Kubernetes
Complete Docker Compose setup with Traefik OIDC middleware:
version: "3.8"
services:
traefik:
image: traefik:v3.2
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--experimental.plugins.traefikoidc.modulename=github.com/lukaszraczylo/traefikoidc"
- "--experimental.plugins.traefikoidc.version=v0.7.10"
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- web
whoami:
image: traefik/whoami
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`app.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web"
- "traefik.http.routers.whoami.middlewares=oidc-auth"
# OIDC Middleware Configuration
- "traefik.http.middlewares.oidc-auth.plugin.traefikoidc.providerURL=https://accounts.google.com"
- "traefik.http.middlewares.oidc-auth.plugin.traefikoidc.clientID=YOUR_CLIENT_ID"
- "traefik.http.middlewares.oidc-auth.plugin.traefikoidc.clientSecret=YOUR_CLIENT_SECRET"
- "traefik.http.middlewares.oidc-auth.plugin.traefikoidc.callbackURL=/oauth2/callback"
- "traefik.http.middlewares.oidc-auth.plugin.traefikoidc.sessionEncryptionKey=your-32-byte-encryption-key!!"
- "traefik.http.middlewares.oidc-auth.plugin.traefikoidc.forceHTTPS=false"
networks:
- web
networks:
web:
external: true
Multi-replica deployment with Redis for distributed session management:
version: "3.8"
services:
redis:
image: redis:alpine
command: redis-server --requirepass yourpassword
networks:
- web
traefik:
image: traefik:v3.2
deploy:
replicas: 3
labels:
# OIDC Middleware with Redis
- "traefik.http.middlewares.oidc.plugin.traefikoidc.providerURL=https://accounts.google.com"
- "traefik.http.middlewares.oidc.plugin.traefikoidc.clientID=YOUR_CLIENT_ID"
- "traefik.http.middlewares.oidc.plugin.traefikoidc.clientSecret=YOUR_CLIENT_SECRET"
- "traefik.http.middlewares.oidc.plugin.traefikoidc.callbackURL=/oauth2/callback"
- "traefik.http.middlewares.oidc.plugin.traefikoidc.sessionEncryptionKey=your-64-char-key"
# Redis Configuration
- "traefik.http.middlewares.oidc.plugin.traefikoidc.redis.enabled=true"
- "traefik.http.middlewares.oidc.plugin.traefikoidc.redis.address=redis:6379"
- "traefik.http.middlewares.oidc.plugin.traefikoidc.redis.password=yourpassword"
- "traefik.http.middlewares.oidc.plugin.traefikoidc.redis.cacheMode=hybrid"
networks:
- web
networks:
web:
external: true
Built with enterprise security requirements in mind
A better alternative to oauth2-proxy and forward-auth
| Feature | Traefik OIDC | oauth2-proxy | forward-auth |
|---|---|---|---|
| Native Plugin | ✓ | ✗ | ✗ |
| No Extra Service | ✓ | ✗ | ✗ |
| Auto Provider Detection | ✓ | ✗ | ✗ |
| Dynamic Client Registration | ✓ | ✗ | ✗ |
| Automatic Scope Filtering | ✓ | ✗ | ✗ |
| Built-in Security Headers | ✓ | ✗ | ✗ |
| Template Headers | ✓ | ✓ | ✓ |
| Memory Efficient | ✓ LRU caches | Varies | Varies |
Get started with Traefik OIDC in minutes. Full documentation and examples available on GitHub.