lukaszraczylo 9402f1bca5 Token blacklist, cache and metadata improvements
TokenBlacklist Improvements:
Fixed size limit enforcement to properly maintain max size of 1000 tokens
Improved eviction strategy to remove expired tokens first before removing oldest
Added proper cleanup of tokens during Add operation to prevent size overflow
Fixed oldest token eviction logic to ensure correct token removal
Added proper locking mechanisms to prevent race conditions
Cache Improvements:
Fixed cleanup mechanism to only remove truly expired items
Improved eviction strategy in LRU cache to prioritize expired items
Added smarter eviction in evictOldest to scan for expired items first
Fixed aggressive cleanup that was removing valid items
Maintained proper LRU ordering while handling evictions
MetadataCache:
Verified proper implementation of metadata caching with hourly refresh
Confirmed proper handling of cache extension on fetch failures
Validated thread-safe operations with proper RWMutex usage
2025-02-09 23:53:05 +00:00
2025-01-07 13:19:41 +00:00
2025-01-21 19:31:51 +00:00
2025-01-06 11:01:20 +00:00
2025-01-07 13:19:41 +00:00
2025-01-07 13:19:41 +00:00
2025-01-21 19:31:51 +00:00
2025-01-21 19:31:51 +00:00
2025-01-21 19:31:51 +00:00
2025-02-01 12:16:50 +00:00
2025-02-01 12:16:50 +00:00
2025-02-01 12:16:50 +00:00
2025-01-21 19:31:51 +00:00
2025-02-05 19:04:44 +00:00

Traefik OIDC middleware

This middleware is supposed to replace the need for the forward-auth and oauth2-proxy when using traefik as a reverse proxy to support the OIDC authentication.

Middleware has been tested with Auth0 and Logto.

Traefik version compatibility

Code follows closely the current traefik helm chart versions. If plugin fails to load - it's time to update to the latest version of the traefik helm chart.

Configuration options

Middleware currently supports following scenarios:

  • Setting custom callback and logout URLs via callbackURL and logoutURL
  • Allowing for access only from the listed domains if allowedUserDomains is set, otherwise it relies entirely on the OIDC provider
  • Using excluded URLs which do NOT require the OIDC authentication
  • Rate limiting requests to prevent the bruteforce attacks

How to configure...

  • sessionEncryptionKey should be at least 32 bytes long.
Keeping secrets secret

This works ONLY in kubernetes environments. Don't forget to create secret traefik-middleware-oidc with fields ISSUER, CLIENT_ID and SECRET keys.

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oidc-with-open-urls
  namespace: traefik
spec:
  plugin:
    traefikoidc:
      providerURL: urn:k8s:secret:traefik-middleware-oidc:ISSUER
      clientID: urn:k8s:secret:traefik-middleware-oidc:CLIENT_ID
      clientSecret: urn:k8s:secret:traefik-middleware-oidc:SECRET
      sessionEncryptionKey: vvv
      callbackURL: /cool-oidc/callback
      logoutURL: /cool-oidc/logout
      postLogoutRedirectURI: /my-website/you-have-logged-out # Optional post logout URL redirection
      scopes:
        - openid
        - email
        - profile
      excludedURLs: # Determines the list of URLs which are NOT a subject to authentication
        - /login # covers /login, /login/me, /login/reminder etc.
        - /my-public-data
Excluded URLs with open access
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oidc-with-open-urls
  namespace: traefik
spec:
  plugin:
    traefikoidc:
      providerURL: xxx
      clientID: yyy
      clientSecret: zzz
      sessionEncryptionKey: vvv
      callbackURL: /cool-oidc/callback
      logoutURL: /cool-oidc/logout
      scopes:
        - openid
        - email
        - profile
      excludedURLs: # Determines the list of URLs which are NOT a subject to authentication
        - /login # covers /login, /login/me, /login/reminder etc.
        - /my-public-data
Allowed email domains

Assuming that your OIDC provider allows anyone to log in, you may want to limit the access to people using emains in specific domain.

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oidc-only-my-users
  namespace: traefik
spec:
  plugin:
    traefikoidc:
      providerURL: xxx
      clientID: yyy
      clientSecret: zzz
      sessionEncryptionKey: vvv
      callbackURL: /new-oidc/callback
      logoutURL: /new-oidc/logout
      scopes:
        - openid
        - email
        - profile
      allowedUserDomains:
        - raczylo.com
Allowed groups and roles

In case of multiple roles / groups and access separation for various endpoints you will need to create multiple traefik middlewares. Following example allows access for users who have additional role guest-endpoints assigned.

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oidc-guest-endpoints
  namespace: traefik
spec:
  plugin:
    traefikoidc:
      providerURL: xxx
      clientID: yyy
      clientSecret: zzz
      sessionEncryptionKey: vvv
      callbackURL: /my-oidc/callback
      logoutURL: /my-oidc/logout
      scopes:
        - openid
        - email
        - profile
        - roles     # This line queries the OIDC provider for roles
      forceHTTPS: true
      allowedRolesAndGroups:
        - guest-endpoints  # This line specifies the roles or groups allowed to access content
      allowedUserDomains:
        - raczylo.com

Docker compose example

docker-compose.yaml

version: "3.7"

services:
  traefik:
    image: traefik:v3.0.1
    command:
      - "--experimental.plugins.traefikoidc.modulename=github.com/lukaszraczylo/traefikoidc"
      - "--experimental.plugins.traefikoidc.version=v0.2.1"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik-config/traefik.yml:/etc/traefik/traefik.yml
      - ./traefik-config/dynamic-configuration.yml:/etc/traefik/dynamic-configuration.yml
    labels:
      - "traefik.http.routers.dash.rule=Host(`dash.localhost`)"
      - "traefik.http.routers.dash.service=api@internal"

    ports:
      - "80:80"

  hello:
    image: containous/whoami
    labels:
      - traefik.enable=true
      - traefik.http.routers.hello.entrypoints=http
      - traefik.http.routers.hello.rule=Host(`hello.localhost`)
      - traefik.http.services.hello.loadbalancer.server.port=80
      - traefik.http.routers.hello.middlewares=my-plugin@file

  whoami:
    image: jwilder/whoami
    labels:
      - traefik.enable=true
      - traefik.http.routers.whoami.entrypoints=http
      - traefik.http.routers.whoami.rule=Host(`whoami.localhost`)
      - traefik.http.services.whoami.loadbalancer.server.port=8000
      - traefik.http.routers.whoami.middlewares=my-plugin@file

traefik-config/traefik.yaml

log:
  level: INFO

experimental:
  localPlugins:
    traefikoidc:
      moduleName: github.com/lukaszraczylo/traefikoidc

# API and dashboard configuration
api:
  dashboard: true
  insecure: true

entryPoints:
  http:
    address: ":80"
    forwardedHeaders:
      insecure: true

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
  file:
    filename: /etc/traefik/dynamic-configuration.yml

traefik-config/dynamic-configuration.yaml

http:
  middlewares:
    my-plugin:
      plugin:
        traefikoidc:
          providerURL: https://accounts.google.com
          clientID: 1234567890.apps.googleusercontent.com
          clientSecret: secret
          callbackURL: /oauth2/callback
          logoutURL: /oauth2/logout
          scopes: # If not provided, default scopes will be used (openid, email, profile)
            - openid
            - email
            - profile
          allowedUserDomains: # If not provided - will rely entirely on the OIDC yes/no
            - raczylo.com
          sessionEncryptionKey: potato-secret
          forceHTTPS: false
          logLevel: debug # debug, info, warn, error
          rateLimit: 100 # Simple rate limiter to prevent brute force attacks
          excludedURLs: # Determines the list of URLs which are NOT a subject to authentication
            - /login # covers /login, /login/me, /login/reminder etc.
            - /my-public-data
S
Description
Mirror of github.com/lukaszraczylo/traefikoidc
Readme MIT 5.1 MiB
Languages
Go 99.8%