displayName: Traefik OIDC type: middleware import: github.com/lukaszraczylo/traefikoidc summary: | OpenID Connect authentication middleware for Traefik. Replaces forward-auth + oauth2-proxy with a single plugin that auto-detects all major OIDC providers (Google, Azure AD, Auth0, Okta, Keycloak, AWS Cognito, GitLab, generic) and OAuth 2.0 for GitHub. Features: ID-token validation with auto-discovery, session encryption, proactive token refresh, RBAC via roles/groups claims, domain restriction, templated downstream headers, security headers (CSP, HSTS, CORS), rate limiting, PKCE, opaque-token introspection (RFC 7662), back/front-channel logout, Dynamic Client Registration (RFC 7591), and Redis-backed shared state for multi-replica deployments. Full documentation: https://github.com/lukaszraczylo/traefikoidc testData: # Required providerURL: https://accounts.google.com clientID: 1234567890.apps.googleusercontent.com clientSecret: your-client-secret # Alternative: RFC 7523 private_key_jwt client authentication (Entra ID, # Okta, Auth0, Keycloak). Replaces clientSecret with a signed JWT assertion. # See README "Client authentication via private key JWT". # clientAuthMethod: private_key_jwt # clientAssertionKeyID: my-key-2026 # clientAssertionAlg: RS256 # default; or PS256/384/512, ES256/384/512 # # File path option: # clientAssertionKeyPath: /etc/traefik/oidc/client-key.pem # # Or inline PEM (PKCS#8 / PKCS#1 / SEC1): # clientAssertionPrivateKey: | # -----BEGIN PRIVATE KEY----- # MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDexampleexample # -----END PRIVATE KEY----- sessionEncryptionKey: potato-secret-is-at-least-32-bytes-long callbackURL: /oauth2/callback # Common production knobs logoutURL: /oauth2/logout postLogoutRedirectURI: / forceHTTPS: true # default; only set false for plaintext HTTP local dev logLevel: info rateLimit: 100 # Access control allowedUserDomains: - company.com allowedRolesAndGroups: - admin - developer excludedURLs: - /health - /metrics # Scopes are appended to the defaults ["openid", "profile", "email"] scopes: - roles # Templated headers forwarded to backends. Values are Go templates and must # be written with plain double braces — the catalog analyzer feeds them to # the plugin verbatim (issue #151; quadruple braces do NOT get collapsed). # Only when your dynamic config file is rendered by Traefik's file-provider # Go templating do the braces need escaping there, e.g. # value: "{{`{{.Claims.email}}`}}" # (see README "Templated headers"). headers: - name: X-User-Email value: "{{.Claims.email}}" - name: Authorization value: "Bearer {{.AccessToken}}" # Security headers (default profile is enabled out of the box) securityHeaders: enabled: true profile: default # Optional: Redis for multi-replica deployments. See docs/REDIS.md. # redis: # enabled: true # address: redis:6379 # password: urn:k8s:secret:redis:password # cacheMode: hybrid # Optional: bearer-token authentication for M2M (machine-to-machine) API # clients. Default off. When enabled, requests presenting # "Authorization: Bearer " are validated against the configured OIDC # provider (signature/issuer/audience/exp) and forwarded without creating # a cookie session. The bearer path REJECTS ID tokens, requires a non- # default audience, and never trusts the `email` claim as the identifier. # See docs/BEARER_AUTH.md for the full threat model. # # enableBearerAuth: true # opt-in # audience: https://api.example.com # REQUIRED when bearer is enabled # bearerIdentifierClaim: sub # default; used as X-Forwarded-User. `email` is rejected. # stripAuthorizationHeader: true # default; drops the raw token before forwarding # bearerEmitWWWAuthenticate: true # default; RFC 6750 hint on 401s # bearerOverridesCookie: false # default; cookie wins when both are present # requireTokenIntrospection: false # opt-in; calls RFC 7662 introspection per request # introspectionURL: https://idp.example.com/oauth/introspect # manual override; set when discovery omits introspection_endpoint # maxTokenAgeSeconds: 86400 # 24h cap on iat (rejects clock-skew/forever tokens) # maxIdentifierLength: 256 # cap on the sanitised principal identifier # bearerFailureThreshold: 20 # consecutive 401s/IP that trip the throttle # bearerFailureWindowSeconds: 60 # rolling window over which 401s are counted # bearerFailurePenaltySeconds: 60 # 429 + Retry-After duration after threshold trips # Optional: RFC 8707 resource indicator, alternative to `audience` for # supporting IdPs. See docs/RFC8707.md for exact request behavior and # provider support. # resource: https://api.example.com