traefik-oidc-auth

repository·main·Indexed 18 days ago

https://github.com/sevensolutions/traefik-oidc-auth

A Traefik plugin that implements OpenID Connect (OIDC) as a relying party to secure upstream services behind a Traefik proxy. It intercepts requests to ensure users are authenticated via a configured OIDC provider. Tested against Traefik v3+, it supports providers such as Keycloak, ZITADEL, Kanidm, Microsoft EntraID, Authentik, Pocket ID, and Logto. Features include PKCE support, session management via cookies, claim-based authorization, and custom request header injection using Go templates.

Tokens
24.9K
Snippets
61
Records
91
Agent score
63%

What's inside traefik-oidc-auth

  1. What is Traefik OpenID Connect Middleware

    main

    Traefik OpenID Connect Middleware is a Traefik plugin designed to secure upstream services by acting as an OpenID Connect (OIDC) relying party. It intercepts requests and ensures the user is authenticated via a configured OIDC provider before allowing access to the protected service.

    Important Compatibility Notes:

    • It is only tested against Traefik v3+.
    • The middleware is under active development and may undergo breaking changes.
  2. Check supported Identity Providers

    main

    The traefik-oidc-auth middleware supports several well-known identity providers. Before starting your setup, verify if your provider is listed as supported (✅). If a provider is marked as not supported (❌), it may be due to protocol limitations (e.g., GitHub only supporting OAuth instead of OIDC) or lack of testing.

    Supported Providers:

    • ZITADEL
    • Kanidm
    • Keycloak
    • Microsoft Entra ID
    • Authentik
    • Pocket ID
    • Logto

    Not Supported / Untested:

    • HashiCorp Vault (Untested)
    • GitHub (Not supported via OIDC)
  3. Share session cookies across subdomains

    main

    If you are protecting multiple subdomains that share a parent domain (e.g., app1.example.com and app2.example.com), you can optimize performance and user experience by storing the session cookie at the common parent level using SessionCookie.Domain.

    Warning: Sharing a session cookie via SessionCookie.Domain can affect authorization. Since authorization is only checked when the session is created, a user logged into one application via a middleware will also be considered logged in for any other application sharing that same session cookie, even if they have different authorization rules.

    middlewares:
      oidc-auth:
        plugin:
          traefik-oidc-auth:
            CallbackUri: "https://login.example.com/oidc/callback"
            SessionCookie:
              Domain: ".example.com"
            Provider:
              Url: "https://ident.example.com/"
              ClientId: "<YourClientId>"
              ClientSecret: "<YourClientSecret>"
            Scopes: ["openid", "profile", "email"]
  4. How the Traefik OIDC Authentication plugin works

    main

    The Traefik OIDC Authentication plugin acts as a middleware for the Traefik reverse proxy to secure upstream services using OAuth 2.0. It intercepts incoming requests and manages the authentication lifecycle so that individual microservices do not need to implement OAuth flows themselves.

    Authentication Flow

    1. Authentication Verification: The plugin checks for a valid OAuth token stored in a Cookie.
    2. Token Validation: It verifies the token against the configured OAuth provider to ensure it is valid and not expired.
    3. User Authorization: It confirms the user has required permissions (via claim validation or role matching).
    4. Request Handling:
      • Valid Token: The request is forwarded to the upstream service.
      • Missing/Invalid Token: The plugin redirects the user to the OAuth provider's authorization endpoint or returns an HTTP error (e.g., 401 Unauthorized).

    Request Scenarios

    • When no Cookie is present: The plugin redirects the user to the OAuth provider. After successful login and consent, the provider redirects the user to the plugin's callback (/oidc/callback). The plugin then exchanges the code for tokens, validates authorization, creates a session/cookie, and redirects the user back to the original requested page.
    • When a Cookie is present: The plugin fetches the JWKS (JSON Web Key Set) from the OAuth provider to validate the token locally. If valid, the request is forwarded; if invalid or expired, the user is redirected to the OAuth provider for login.
  5. How PKCE code verifiers are handled in parallel login flows

    main

    To prevent race conditions in applications that fire parallel unauthenticated requests (such as SPAs or multi-tab restores), traefik-oidc-auth stores the PKCE code_verifier inside the OIDC state parameter rather than in a standalone cookie.

    When UsePkce: true is enabled, the middleware includes the verifier in the OidcState JSON object under the key cv. This ensures that each unique login attempt carries its own verifier via the state query parameter, preventing parallel redirects from overwriting a shared cookie and causing Invalid code verifier errors from the Identity Provider (IdP).

  6. Use AuthorizationHeader or AuthorizationCookie for external tokens

    main

    You can authenticate requests using an externally generated access token provided via a header or a cookie. This is common for non-browser clients.

    Important Behavior:

    • When using these methods, no session is created by the middleware.
    • Because these are often non-browser clients, it is recommended to set UnauthenticatedBehavior and UnauthorizedBehavior to Unauthorized. This ensures a missing or invalid token results in a plain 401/403 response instead of a redirect to the IdP login page.

    Configuration

    • AuthorizationHeader: Specify the Name of the header containing the token.
    • AuthorizationCookie: Specify the Name of the cookie containing the token.
    • You can use both simultaneously.
  7. How ClaimAssertion evaluation works

    main

    Authorization rules are evaluated based on the following lifecycle:

    1. Default Behavior: AssertClaims is evaluated once when the user logs in and the session is created. The result is cached in the session and reused for subsequent requests. Even if claims change (e.g., via a silent token refresh), the cached result is used.
    2. Per-Request Evaluation: If you need to enforce rules that might change during a session (like acr claims for step-up authentication), set CheckOnEveryRequest to true. This prevents caching and re-evaluates the assertion on every request.
    3. Stateless Authorization: When using AuthorizationHeader or AuthorizationCookie, CheckOnEveryRequest is effectively always true because there is no persistent session to cache the result.

    Note on Unauthorized Results: If an initial check fails, the 'unauthorized' result is cached in the session. Depending on your UnauthorizedBehavior configuration, users may see a 403 or be bounced through the IDP once before seeing the 403 page.

  8. Use environment variables and files for configuration

    main

    Properties marked with an asterisk (*) in the configuration table support environment variable substitution using the ${VAR_NAME} syntax.

    Environment Variables

    Use ${MY_VAR} to inject a single environment variable. Note that this does not support complex templating (e.g., https://auth.${DOMAIN}/auth is invalid).

    File-based Secrets

    For better security (especially in Docker/Kubernetes), you can read sensitive values like Secret or ClientSecret from mounted files using the ${file:/path/to/file} syntax. The content is automatically trimmed of whitespace.

    Secret: "${file:/run/secrets/oidc_secret}"
    Provider:
      ClientSecret: "${file:/run/secrets/oidc_client_secret}"
    Provider:
      Url: "${MY_PROVIDER_URL}"
      ClientSecret: "${MY_CLIENT_SECRET}"
  9. Configure the traefik-oidc-auth middleware on Kubernetes

    main

    When running on Kubernetes, you can use a Middleware CRD and reference sensitive values (like the encryption secret and the clientSecret) from a Kubernetes Secret using the urn:k8s:secret:<secret-name>:<key> syntax.

    1. Create a Kubernetes Secret containing your pluginSecret and providerClientSecret.
    2. Define a Middleware resource where the plugin.traefik-oidc-auth.secret and plugin.traefik-oidc-auth.provider.clientSecret point to the keys in your Secret.
    3. Attach the Middleware to an IngressRoute.
    apiVersion: v1
    kind: Secret
    metadata:
      name: oidc-secret
      namespace: traefik
    type: Opaque
    stringData:
      pluginSecret: "MLFs4TT99kOOq8h3UAVRtYoCTDYXiRcZ"
      providerClientSecret: "<YourClientSecret>"
    ---
    apiVersion: traefik.io/v1alpha1
    kind: Middleware
    metadata:
      name: oidc
      namespace: traefik
    spec:
      plugin:
        traefik-oidc-auth:
          secret: "urn:k8s:secret:oidc-secret:pluginSecret"
          provider:
            clientId: "abcd-12345"
            clientSecret: "urn:k8s:secret:oidc-secret:providerClientSecret"
    ---
    apiVersion: traefik.io/v1alpha1
    kind: IngressRoute
    metadata:
      name: whoami
      namespace: traefik
    spec:
      routes:
        - kind: Rule
          match: Host(`whoami.mycluster.com`)
          middlewares:
            - name: oidc
          services:
            - kind: Service
              name: whoami
              port: 80
  10. Setup ZITADEL as an Identity Provider

    main

    To use ZITADEL with traefik-oidc-auth, follow these steps in the ZITADEL Admin Console:

    1. Create a Project: Create a new Project in the ZITADEL Admin Console.
    2. Create an Application: Within the Project, create a new Application of type Web.
      • With PKCE: Select PKCE as the authentication method.
      • Without PKCE: Select CODE as the authentication method.
    3. Configure Redirect URIs: Specify your application's public URL and append /oidc/callback (e.g., https://my-app.mydomain.com/oidc/callback).
      • Note: Use HTTPS. If using HTTP, you must enable ZITADEL's Development Mode.
    4. Configure Token Settings: Navigate to Token Settings within the Application and change the Auth Token Type to JWT. This is required for the middleware to function correctly.
  11. Register an application in Microsoft Entra ID

    main

    To use Microsoft Entra ID as an identity provider, you must register your application in the Azure Portal:

    1. Log in to the Azure Portal and navigate to Microsoft Entra ID.
    2. In the left navigation panel, go to Manage > App registrations.
    3. Click New Registration and provide a name.
    4. Select the appropriate option for authorized users.
    5. Under Redirect URI (optional), specify the public URL of your application and append the path /oidc/callback (e.g., https://my-app.mydomain.com/oidc/callback).