traefik-forward-auth

module
v0.0.0-...-ec15290 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 3, 2024 License: MIT

README

Traefik Forward Auth

A minimal service that provides authentication and SSO with OAuth2, OpenID Connect, and Tailscale Whois, for the Traefik reverse proxy.

This project began as a fork of thomseddon/traefik-forward-auth. Since version 3, it has been completely rewritten and is not compatible with the upstream project anymore.

Highlights

  • Supports authentication with Google, Microsoft Entra ID (formerly Azure AD), GitHub, and generic OpenID Connect providers (including Auth0, Okta, etc).
  • Single Sign-On with Tailscale Whois (similarly to Tailscale's nginx-auth)
  • Protect multiple Traefik services with a single instance of traefik-forward-auth.

Releases

The Docker image is available on GitHub Packages. Container images are multi-arch and run on linux/amd64, linux/arm64, and linux/arm/v7.

Using the 3 tag is recommended:

ghcr.io/italypaleale/traefik-forward-auth:3

You can also pin to the latest patch release as found in the Releases page:

ghcr.io/italypaleale/traefik-forward-auth:3.x.x

Quickstart

Authenticate with Google

This example uses Docker Compose to add Google authentication to an application exposed via Traefik.

In this example, your OAuth2 application should be configured to redirect users to https://auth.example.com/oauth2/callback.

# docker-compose.yaml
version: '3'

services:
  traefik:
    image: traefik:v2.10
    command:
      - "--providers.docker=true"
      - "--entrypoints.websecure.address=:443"
    ports:
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

  traefik-forward-auth:
    image: ghcr.io/italypaleale/traefik-forward-auth:3
    environment:
      # Hostname where the application can be reached at externally
      - TFA_HOSTNAME=auth.example.com
      # Domain for setting cookies
      - TFA_COOKIEDOMAIN=example.com
      # Configure authentication with Google
      - TFA_AUTHPROVIDER=google
      - TFA_AUTHGOOGLE_CLIENTID=...
      - TFA_AUTHGOOGLE_CLIENTSECRET=...
    labels:
      - "traefik.http.middlewares.traefik-forward-auth.forwardauth.address=http://traefik-forward-auth:4181"
      - "traefik.http.middlewares.traefik-forward-auth.forwardauth.authResponseHeaders=X-Forwarded-User"
      - "traefik.http.services.traefik-forward-auth.loadbalancer.server.port=4181"
      - "traefik.http.routers.traefik-forward-auth.rule=Host(`auth.example.com`)"
      - "traefik.http.routers.traefik-forward-auth.entrypoints=websecure"
      - "traefik.http.routers.traefik-forward-auth.tls=true"

  whoami:
    image: ghcr.io/traefik/whoami:latest
    environment:
      - WHOAMI_PORT_NUMBER=4545
    labels:
      - "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
      - "traefik.http.routers.whoami.middlewares=traefik-forward-auth"
      - "traefik.http.services.whoami.loadbalancer.server.port=4545"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls=true"
Authenticate with Tailscale

This example uses Docker Compose to expose an application via Traefik. Users who access the Traefik endpoint through Tailscale are automatically authenticated. This example assumes Tailscale is running on the container host, not inside a container.

# docker-compose.yaml
version: '3'

services:
  traefik:
    image: traefik:v2.10
    command:
      - "--providers.docker=true"
      - "--entrypoints.websecure.address=:443"
    ports:
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

  traefik-forward-auth:
    image: ghcr.io/italypaleale/traefik-forward-auth:3
    volumes:
      # Note the Tailscale socket must be mounted in the container
      - /var/run/tailscale/:/var/run/tailscale
    environment:
      # Hostname where the application can be reached at externally
      - TFA_HOSTNAME=auth.example.com
      # Domain for setting cookies
      - TFA_COOKIEDOMAIN=example.com
      # Configure authentication with Tailscale
      - TFA_AUTHPROVIDER=tailscalewhois
    labels:
      - "traefik.http.middlewares.traefik-forward-auth.forwardauth.address=http://traefik-forward-auth:4181"
      - "traefik.http.middlewares.traefik-forward-auth.forwardauth.authResponseHeaders=X-Forwarded-User"
      - "traefik.http.routers.traefik-forward-auth.rule=Host(`auth.example.com`)"
      - "traefik.http.routers.traefik-forward-auth.entrypoints=websecure"
      - "traefik.http.routers.traefik-forward-auth.tls=true"
      - "traefik.http.services.traefik-forward-auth.loadbalancer.server.port=4181"

  whoami:
    image: ghcr.io/traefik/whoami:latest
    environment:
      - WHOAMI_PORT_NUMBER=4545
    labels:
      - "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
      - "traefik.http.routers.whoami.middlewares=traefik-forward-auth"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls=true"
      - "traefik.http.services.whoami.loadbalancer.server.port=4545"

Configuration

Configuring Traefik Forward Auth

Traefik Forward Auth can be configured in two ways:

  1. Mount a YAML configuration file into the container at the path /etc/traefik-forward-auth/config.yaml. In your docker-compose.yaml you can mount the configuration file similar to this:

    services:
     traefik-forward-auth:
       image: ghcr.io/italypaleale/traefik-forward-auth:3
       volumes:
         - `/path/on/host/config.yaml:/etc/traefik-forward-auth/config.yaml:ro`
    
  2. Using environmental variables. In your docker-compose.yaml, this is done listing each variable in the environment section:

    services:
     traefik-forward-auth:
       image: ghcr.io/italypaleale/traefik-forward-auth:3
       environment:
         - `TFA_HOSTNAME=auth.example.com`
    

You can find the list of all configuration options in the section below.

Environmental variables take precedence over values set in the configuration file.

Exposing Traefik Forward Auth

In order to use Traefik Forward Auth, it needs to be reachable through a Traefik router. You can configure it in 2 ways:

  1. Using a dedicated sub-domain
    This is most commonly used when all the apps you want to protect are served under the same domain (e.g. example.com). Traefik Forward Auth is exposed through its own sub-domain (for example, https://auth.example.com), while your apps are served through the parent domain (https://example.com) or other sub-domains (https://myapp.example.com).
    This scenario is the most convenient one when you need to protect multiple applications at once using the same Traefik Forward Auth instance.
  2. Using a sub-path
    In this scenario you do not need a dedicated sub-domain for Traefik Forward Auth, which is instead exposed in a sub-path. For example, if your app is reachable at https://example.com, Traefik is configured to route requests to Traefik Forward Auth at https://example.com/auth.

Although Traefik Forward Auth doesn't need to be reachable from the public Internet, your clients must be able to have a route to it (for example, within the LAN or using a VPN)
Additionally, many OAuth2 identity providers (including Google and Microsoft Entra ID) require the callback URL to be served via HTTPS/TLS (even if using a self-signed certificate).

Using a dedicated sub-domain

Using a dedicated sub-domain is the most convenient way to protect multiple apps, as long as they are all served under sub-domains of the same domain name (e.g. example.com).

In this example:

  • Applications are hosted on https://example.com and/or subdomains such as https://myapp.example.com.
  • Traefik Forward Auth is served on https://auth.example.com.

To configure Traefik and Traefik Forward Auth in this scenario:

  1. If using a provider based on OAuth2 (including Google, Microsoft Entra ID, GitHub, and OpenID Connect providers), configure your authentication callback to: https://auth.example.com/oauth2/callback

  2. Configure Traefik Forward Auth with:

  3. Create a Traefik middleware of type forwardauth with:

    • address: http://traefik-forward-auth:4181
      This is the address of the traefik-forward-auth container within your Docker network. In this example, we are assuming the container/service is named traefik-forward-auth. Also note that the internal communication happens over HTTP by default.
    • authResponseHeaders: X-Forwarded-User
      This is optional, but allows your application to read the ID of the authenticated user through the request header X-Forwarded-User.
  4. Configure Traefik to expose your applications, including:

    • Traefik Forward Auth at auth.example.com, using the "websecure" entry point (which is enabled for HTTPS/TLS).
    • Your applications at example.com or other sub-domains such as myapp.example.com

Full example using Docker Compose:

# docker-compose.yaml
version: '3'

services:
  traefik:
    image: traefik:v2.10
    command:
      - "--providers.docker=true"
      - "--entrypoints.websecure.address=:443"
    ports:
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

  traefik-forward-auth:
    image: ghcr.io/italypaleale/traefik-forward-auth:3
    environment:
      # Hostname where the application can be reached at externally
      - TFA_HOSTNAME=auth.example.com
      # Domain for setting cookies
      - TFA_COOKIEDOMAIN=example.com
      # Add other options
      - ...
    labels:
      - "traefik.http.middlewares.traefik-forward-auth.forwardauth.address=http://traefik-forward-auth:4181"
      - "traefik.http.middlewares.traefik-forward-auth.forwardauth.authResponseHeaders=X-Forwarded-User"
      - "traefik.http.services.traefik-forward-auth.loadbalancer.server.port=4181"
      - "traefik.http.routers.traefik-forward-auth.rule=Host(`auth.example.com`)"
      - "traefik.http.routers.traefik-forward-auth.entrypoints=websecure"
      - "traefik.http.routers.traefik-forward-auth.tls=true"

  whoami:
    image: ghcr.io/traefik/whoami:latest
    environment:
      - WHOAMI_PORT_NUMBER=4545
    labels:
      - "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
      - "traefik.http.routers.whoami.middlewares=traefik-forward-auth"
      - "traefik.http.services.whoami.loadbalancer.server.port=4545"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls=true"
Using a sub-path

Using a sub-path does not require the use of sub-domains, but it is generally harder to implement when you want to protect more than one application.

In this example:

  • Your application is hosted at https://example.com.
  • Traefik Forward Auth is served on https://example.com/auth.

To configure Traefik and Traefik Forward Auth in this scenario:

  1. If using a provider based on OAuth2 (including GitHub, Google, Microsoft Entra ID, and OpenID Connect providers), configure your authentication callback to: https://example.com/auth/oauth2/callback

  2. Configure Traefik Forward Auth with:

  3. Create a Traefik middleware of type forwardauth with:

    • address: http://traefik-forward-auth:4181/auth
      This is the address of the traefik-forward-auth container within your Docker network. In this example, we are assuming the container/service is named traefik-forward-auth. Also note that the internal communication happens over HTTP by default.
    • authResponseHeaders: X-Forwarded-User
      This is optional, but allows your application to read the ID of the authenticated user through the request header X-Forwarded-User.
  4. Configure Traefik to expose your applications, including:

    • Traefik Forward Auth at example.com/auth, using the rule PathPrefix(`/auth`) the "websecure" entry point (which is enabled for HTTPS/TLS).
    • Your application at example.com.

Full example using Docker Compose:

# docker-compose.yaml
version: '3'

services:
  traefik:
    image: traefik:v2.10
    command:
      - "--providers.docker=true"
      - "--entrypoints.websecure.address=:443"
    ports:
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

  traefik-forward-auth:
    image: ghcr.io/italypaleale/traefik-forward-auth:3
    environment:
      # Hostname where the application can be reached at externally
      - TFA_HOSTNAME=example.com
      # Base path
      - TFA_BASEPATH=/auth
      # Add other options
      - ...
    labels:
      - "traefik.http.middlewares.traefik-forward-auth.forwardauth.address=http://traefik-forward-auth:4181/auth"
      - "traefik.http.middlewares.traefik-forward-auth.forwardauth.authResponseHeaders=X-Forwarded-User"
      - "traefik.http.services.traefik-forward-auth.loadbalancer.server.port=4181"
      - "traefik.http.routers.traefik-forward-auth.rule=Host(`example.com`) && PathPrefix(`/auth`)"
      - "traefik.http.routers.traefik-forward-auth.entrypoints=websecure"
      - "traefik.http.routers.traefik-forward-auth.tls=true"

  whoami:
    image: ghcr.io/traefik/whoami:latest
    environment:
      - WHOAMI_PORT_NUMBER=4545
    labels:
      - "traefik.http.routers.whoami.rule=Host(`example.com`)"
      - "traefik.http.routers.whoami.middlewares=traefik-forward-auth"
      - "traefik.http.services.whoami.loadbalancer.server.port=4545"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls=true"
Authentication providers
GitHub

To use GitHub for user authentication, create an OAuth2 application and configure the callback to https://<endpoint>/oauth2/callback (see examples depending on how Traefik Forward Auth is exposed).

Set the following options for Traefik Forward Auth:

You can restrict the users that can authenticate with your service using this option:

  • authGitHub_allowedUsers (env: TFA_AUTHGITHUB_ALLOWEDUSERS): List of allowed users, matching the GitHub user handle.
Google

To use Google for user authentication, create an OAuth2 application and configure the callback to https://<endpoint>/oauth2/callback (see examples depending on how Traefik Forward Auth is exposed).

Set the following options for Traefik Forward Auth:

You can restrict the users that can authenticate with your service using one (or more) of these options:

  • authGoogle_allowedEmails (env: TFA_AUTHGOOGLE_ALLOWEDEMAILS): List of allowed users, matching their email address (e.g. example@gmail.com)
  • authGoogle_allowedDomains (env: TFA_AUTHGOOGLE_ALLOWEDDOMAINS): List of allowed domain names of users' email addresses (e.g. mydomain.com)
  • authGoogle_allowedUsers (env: TFA_AUTHGOOGLE_ALLOWEDUSERS): List of allowed users, matching the internal user ID.
Microsoft Entra ID

To use Microsoft Entra ID (formerly Azure AD) for user authentication, create an OAuth2 application and configure the callback to https://<endpoint>/oauth2/callback (see examples depending on how Traefik Forward Auth is exposed).

Set the following options for Traefik Forward Auth:

You can restrict the users that can authenticate with your service using one (or more) of these options:

Other OpenID Connect providers

Traefik Forward Auth support generic OpenID Connect providers. This includes Auth0, Okta, etc.

To use an OpenID Connect provider for user authentication, create an application and configure the callback to https://<endpoint>/oauth2/callback (see examples depending on how Traefik Forward Auth is exposed).

Set the following options for Traefik Forward Auth:

  • authProvider (env: TFA_AUTHPROVIDER): openidconnect
  • authOpenIDConnect_tokenIssuer (env: TFA_AUTHOPENIDCONNECT_TOKENISSUER): Token issuer
    This is generally a URL like https://tenant.identityprovider.com/.
    Traefik Forward Auth will try to fetch the OpenID Configuration document at <tokenIssuer>/.well-known/openid-configuration; in this example, https://tenant.identityprovider.com/.well-known/openid-configuration.
  • authOpenIDConnect_clientID (env: TFA_AUTHOPENIDCONNECT_CLIENTID): Client ID of your application
  • authOpenIDConnect_clientSecret (env: TFA_AUTHOPENIDCONNECT_CLIENTSECRET): Client secret of your application

You can restrict the users that can authenticate with your service using one (or more) of these options:

Tailscale Whois

You can configure Single Sign-On (SSO) for clients that access your Traefik server through Tailscale. Users will be automatically authenticated when the request comes through the Tailscale network.

This offers a similar behavior to the Tailscale nginx-auth component.

  1. Your container host must be joined to a Tailnet, and you must have the Tailscale service running on the host.

  2. Make sure that the socket /var/run/tailscale/ is mounted into the traefik-forward-auth container.

  3. Configure Traefik Forward Auth with:

Example using Docker Compose (unrelated configuration options and labels omitted):

services:
  traefik-forward-auth:
    image: ghcr.io/italypaleale/traefik-forward-auth:3
    volumes:
      - /var/run/tailscale/:/var/run/tailscale
    environment:
      - TFA_AUTHPROVIDER=tailscalewhois

You can restrict the users or tailnets that can authenticate with your service using one (or more) of these options:

  • authTailscaleWhois_allowedTailnet (env: TFA_AUTHTAILSCALEWHOIS_ALLOWEDTAILNET): If set, restricts users who are part of this specific Tailnet. Note that due to how Tailscale works, Tailnet names are only returned for nodes that are part of the current Tailnet, and not nodes that are being added as "guests".
  • authTailscaleConnect_allowedUsers (env: TFA_AUTHTAILSCALECONNECT_ALLOWEDUSERS): List of allowed users, matching the user ID.
All configuration options
Name Type Description
YAML: hostname
Env: TFA_HOSTNAME
string The hostname the application is reached at.
This is used for setting the "redirect_uri" field for OAuth2 callbacks.
Required
YAML: cookieDomain
Env: TFA_COOKIEDOMAIN
string Domain name for setting cookies.
If empty, this is set to the value of the hostname property.
This value must either be the same as the hostname property, or the hostname must be a sub-domain of the cookie domain name.
Recommended
YAML: cookieName
Env: TFA_COOKIENAME
string Name of the cookie used to store the session. Default: "tf_sess"
YAML: cookieInsecure
Env: TFA_COOKIEINSECURE
boolean If true, sets cookies as "insecure", which are served on HTTP endpoints too.
By default, this is false and cookies are sent on HTTPS endpoints only.
Default: false
YAML: sessionLifetime
Env: TFA_SESSIONLIFETIME
duration Lifetime for sessions after a successful authentication. Default: 2h
YAML: port
Env: TFA_PORT
number Port to bind to. Default: 4181
YAML: bind
Env: TFA_BIND
string Address/interface to bind to. Default: "0.0.0.0"
YAML: basePath
Env: TFA_BASEPATH
string Base path for all routes.
Set this if Traefik is forwarding requests to traefik-forward-auth for specific paths only.
Note: this does not apply to /api and /healthz routes
YAML: logLevel
Env: TFA_LOGLEVEL
string Controls log level and verbosity. Supported values: debug, info (default), warn, error. Default: info
YAML: enableMetrics
Env: TFA_ENABLEMETRICS
boolean Enable the metrics server, which exposes a Prometheus-compatible endpoint /metrics. Default: false
YAML: metricsPort
Env: TFA_METRICSPORT
number Port for the metrics server to bind to. Default: 2112
YAML: metricsBind
Env: TFA_METRICSBIND
string Address/interface for the metrics server to bind to. Default: "0.0.0.0"
YAML: omitHealthCheckLogs
Env: TFA_OMITHEALTHCHECKLOGS
boolean If true, calls to the healthcheck endpoint (/healthz) are not included in the logs. Default: true
YAML: tokenSigningKey
Env: TFA_TOKENSIGNINGKEY
string String used as key to sign state tokens.
Can be generated for example with openssl rand -base64 32
If left empty, it will be randomly generated every time the app starts (recommended, unless you need user sessions to persist after the application is restarted).
YAML: authProvider
Env: TFA_AUTHPROVIDER
string Authentication provider to use
Currently supported providers:

- github
- google
- microsoftentraid
- openidconnect
- tailscalewhois
Required
YAML: authGoogle_clientID
Env: TFA_AUTHGOOGLE_CLIENTID
string Client ID for the Google auth application
Ignored if authMethod is not google
YAML: authGoogle_clientSecret
Env: TFA_AUTHGOOGLE_CLIENTSECRET
string Client secret for the Google auth application
Ignored if authMethod is not google
YAML: authGoogle_allowedUsers
Env: TFA_AUTHGOOGLE_ALLOWEDUSERS
list of strings List of allowed users for Google auth
This is a list of user IDs
Ignored if authMethod is not google
YAML: authGoogle_allowedEmails
Env: TFA_AUTHGOOGLE_ALLOWEDEMAILS
list of strings List of allowed email addresses of users for Google auth
This is a list of email addresses
Ignored if authMethod is not google
YAML: authGoogle_allowedDomains
Env: TFA_AUTHGOOGLE_ALLOWEDDOMAINS
list of strings List of allowed domains for Google auth
This is a list of domains for email addresses
Ignored if authMethod is not google
YAML: authGoogle_requestTimeout
Env: TFA_AUTHGOOGLE_REQUESTTIMEOUT
duration Timeout for network requests for Google auth
Ignored if authMethod is not google
Default: 10s
YAML: authGitHub_clientID
Env: TFA_AUTHGITHUB_CLIENTID
string Client ID for the GitHub auth application
Ignored if authMethod is not github
YAML: authGitHub_clientSecret
Env: TFA_AUTHGITHUB_CLIENTSECRET
string Client secret for the GitHub auth application
Ignored if authMethod is not github
YAML: authGitHub_allowedUsers
Env: TFA_AUTHGITHUB_ALLOWEDUSERS
list of strings List of allowed users for GitHub auth
This is a list of usernames
Ignored if authMethod is not github
YAML: authGitHub_requestTimeout
Env: TFA_AUTHGITHUB_REQUESTTIMEOUT
duration Timeout for network requests for GitHub auth
Ignored if authMethod is not github
Default: 10s
YAML: authMicrosoftEntraID_tenantID
Env: TFA_AUTHMICROSOFTENTRAID_TENANTID
string Tenant ID for the Microsoft Entra ID auth application
Ignored if authMethod is not microsoftentraid
YAML: authMicrosoftEntraID_clientID
Env: TFA_AUTHMICROSOFTENTRAID_CLIENTID
string Client ID for the Microsoft Entra ID auth application
Ignored if authMethod is not microsoftentraid
YAML: authMicrosoftEntraID_clientSecret
Env: TFA_AUTHMICROSOFTENTRAID_CLIENTSECRET
string Client secret for the Microsoft Entra ID auth application
Ignored if authMethod is not microsoftentraid
YAML: authMicrosoftEntraID_allowedUsers
Env: TFA_AUTHMICROSOFTENTRAID_ALLOWEDUSERS
list of strings List of allowed users for Microsoft Entra ID auth
This is a list of user IDs
Ignored if authMethod is not microsoftentraid
YAML: authMicrosoftEntraID_allowedEmails
Env: TFA_AUTHMICROSOFTENTRAID_ALLOWEDEMAILS
list of strings List of allowed email addresses of users for Microsoft Entra ID auth
This is a list of email addresses
Ignored if authMethod is not microsoftentraid
YAML: authMicrosoftEntraID_requestTimeout
Env: TFA_AUTHMICROSOFTENTRAID_REQUESTTIMEOUT
duration Timeout for network requests for Microsoft Entra ID auth
Ignored if authMethod is not microsoftentraid
Default: 10s
YAML: authOpenIDConnect_clientID
Env: TFA_AUTHOPENIDCONNECT_CLIENTID
string Client ID for the OpenID Connect auth application
Ignored if authMethod is not openidconnect
YAML: authOpenIDConnect_clientSecret
Env: TFA_AUTHOPENIDCONNECT_CLIENTSECRET
string Client secret for the OpenID Connect auth application
Ignored if authMethod is not openidconnect
YAML: authOpenIDConnect_tokenIssuer
Env: TFA_AUTHOPENIDCONNECT_TOKENISSUER
string OpenID Connect token issuer
The OpenID Connect configuration document will be fetched at <token-issuer>/.well-known/openid-configuration
Ignored if authMethod is not openidconnect
YAML: authOpenIDConnect_allowedUsers
Env: TFA_AUTHOPENIDCONNECT_ALLOWEDUSERS
list of strings List of allowed users for OpenID Connect auth
This is a list of user IDs, as returned by the ID provider in the "sub" claim
Ignored if authMethod is not openidconnect
YAML: authOpenIDConnect_allowedEmails
Env: TFA_AUTHOPENIDCONNECT_ALLOWEDEMAILS
list of strings List of allowed email addresses for users for OpenID Connect auth
This is a list of email addresses, as returned by the ID provider in the "email" claim
Ignored if authMethod is not openidconnect
YAML: authOpenIDConnect_requestTimeout
Env: TFA_AUTHOPENIDCONNECT_REQUESTTIMEOUT
duration Timeout for network requests for OpenID Connect auth
Ignored if authMethod is not openidconnect
Default: 10s
YAML: authTailscaleWhois_allowedTailnet
Env: TFA_AUTHTAILSCALEWHOIS_ALLOWEDTAILNET
string If non-empty, requires the Tailnet of the user to match this value
Ignored if authMethod is not tailscalewhois
YAML: authTailscaleConnect_allowedUsers
Env: TFA_AUTHTAILSCALECONNECT_ALLOWEDUSERS
list of strings List of allowed users for Tailscale Whois auth
This is a list of user IDs as returned by the ID provider
Ignored if authMethod is not tailscalewhois
YAML: authTailscaleWhois_requestTimeout
Env: TFA_AUTHTAILSCALEWHOIS_REQUESTTIMEOUT
duration Timeout for network requests for Tailscale Whois auth
Ignored if authMethod is not tailscalewhois
Default: 10s
YAML: authenticationTimeout
Env: TFA_AUTHENTICATIONTIMEOUT
duration Timeout for authenticating with the authentication provider. Default: 5m
YAML: tlsPath
Env: TFA_TLSPATH
string Path where to load TLS certificates from. Within the folder, the files must be named tls-cert.pem and tls-key.pem (and optionally tls-ca.pem).
Vault watches for changes in this folder and automatically reloads the TLS certificates when they're updated.
If empty, certificates are loaded from the same folder where the loaded config.yaml is located.
Default: Folder where the config.yaml file is located
YAML: tlsCertPEM
Env: TFA_TLSCERTPEM
string Full, PEM-encoded TLS certificate.
Using tlsCertPEM and tlsKeyPEM is an alternative method of passing TLS certificates than using tlsPath.
YAML: tlsKeyPEM
Env: TFA_TLSKEYPEM
string Full, PEM-encoded TLS key.
Using tlsCertPEM and tlsKeyPEM is an alternative method of passing TLS certificates than using tlsPath.
YAML: tlsCAPEM
Env: TFA_TLSCAPEM
string Full, PEM-encoded TLS CA certificate, used for TLS client authentication (mTLS).
This is an alternative method of passing the CA certificate than using tlsPath.
Note that this is ignored unless tlsClientAuth is set to true.
YAML: tlsClientAuth
Env: TFA_TLSCLIENTAUTH
boolean If true, enables mTLS for client authentication.
Requests to the root endpoint (normally used by Traefik) must have a valid client certificate signed by the CA.
Default: false
YAML: trustedRequestIdHeader
Env: TFA_TRUSTEDREQUESTIDHEADER
string String with the name of a header to trust as ID of each request. The ID is included in logs and in responses as X-Request-ID header.
Common values include:

- X-Request-ID: a de-facto standard that's vendor agnostic
- CF-Ray: when the application is served by a Cloudflare CDN

If this option is empty, or if it contains the name of a header that is not found in an incoming request, a random UUID is generated as request ID.

Advanced

Configure health checks

Traefik Forward Auth supports health checks on the /healthz endpoint, which can be used to configure health checks in your platform. This endpoint returns a response with a 200 status code to indicate the application is healthy.

Calls to the /healthz endpoint do not appear in access logs unless the configuration option omitHealthCheckLogs is set to false (default is true).

The /healthz endpoint is unchanged regardless of the value of the basePath configuration.

Metrics

Traefik Forward Auth can expose metrics in a Prometheus-compatible format on a separate endpoint.

The metrics server is disabled by default. To enable it, set enableMetrics (env: TFA_ENABLEMETRICS) to true.

The metrics server listens on port 2112 by default, which can be configured with metricsPort (env: TFA_METRICSPORT). Metrics are exposed on the /metrics path. For example: http://<endpoint>:2112/metrics.

Token signing keys

Traefik Forward Auth issues JWT tokens which are signed with HMAC-SHA256 (HS256), an operation which requires a "signing key".

The signing key is randomly generated when Traefik Forward Auth starts. For most users, relaying on the default behavior is sufficient—and recommended.

However, when a JWT is signed with a randomly-generated token, they are invalidated when the Traefik Forward Auth process that issued them is restarted, or if the request hits a separate replica.

In certain situations, for example when:

  • You have multiple replicas of Traefik Forward Auth, and/or
  • You auto-scale Traefik Forward Auth, and/or
  • You want tokens to remain valid even after a restart of Traefik Forward Auth

You can set an explicit value for the tokenSigningKey (env: TFA_TOKENSIGNINGKEY) option. For example, you can generate a random string with openssl rand -base64 32.

Note that Traefik Forward Auth does not use the value provided in tokenSigningKey as-is to sign JWTs. Instead, the actual token signing key is derived using a key derivation function on the value provided in the configuration option.

Configure session lifetime

When Traefik Forward Auth authenticates a user, it issues a JWT, saved in a cookie on the user's browser, to maintain the session.

By default, sessions are valid for 2 hours.

You can configure the lifetime of a session using the option sessionLifetime (env: TFA_SESSIONLIFETIME), which accepts a Go duration (such as 2h for 2 hours, or 30m for 30 minutes).

Security hardening

This section contains some advanced options to harden the security of Traefik Forward Auth.

Container security options

Traefik Forward Auth's containers run as non-root users and do not require write access to the root file system of the container. As such, you can configure the container with certain security options.

For Docker Compose (unrelated fields are omitted):

# docker-compose.yaml
services:
  traefik-forward-auth:
    # Read-only root file system
    read_only: true
    # Run as UID/GID 65532/65532
    user: 65532:65532

For Kubernetes, set these options in the Pod's container definition (unrelated fields are omitted):

apiVersion: v1
kind: Pod
spec:
  containers:
    - name: "traefik-forward-auth"
      securityContext:
        readOnlyRootFilesystem: true
        runAsUser: 65532
        runAsGroup: 65532
mTLS between Traefik and Traefik Forward Auth

Traefik Forward Auth's root endpoint (/) is meant to be invoked by Traefik only. Aside from network-level access control rules, you can configure TLS with mutual authentication to encrypt the traffic between Traefik and Traefik Forward Auth, and ensure that only Traefik can invoke the root endpoint of the forward auth service.

  1. Generate a root CA certificate, then generate a certificate for the server (Traefik Forward Auth) and the client (Traefik).

    You can see an example of generating the various certificates and keys using CFSSL in mradile/cfssl-mtls-demo.

  2. Make sure that files are named according to these conventions:

    • For Traefik Forward Auth, files must be mounted in the container in the path /etc/traefik-forward-auth (the same folder where the config.yaml file is mounted):

      • tls-ca.pem: CA certificate
      • tls-cert.pem: Server certificate for Traefik Forward Auth
      • tls-key.pem: Server key for Traefik Forward Auth
    • For Traefik, mount the files in the container at the path you prefer. You need to provide the CA certificate, as well as the client certificate and key for Traefik.
      In this example, we'll mount the certificates in /mnt/tls in the container, with files named:

      • tls-ca.pem: CA certificate
      • tls-cert.pem: Client certificate for Traefik
      • tls-key.pem: Client key for Traefik
  3. Configure Traefik Forward Auth to use mTLS by setting these options:

    • tlsPath (env: TFA_TLSPATH): /etc/traefik-forward-auth
    • tlsClientAuth (env: TFA_TLSCLIENTAUTH): true
  4. Configure Traefik to present a client certificate when connecting to Traefik Forward Auth. For example, using this Docker Compose (unrelated properties are omitted):

    # docker-compose.yaml
    version: '3'
      traefik:
        volumes:
          - "/path/on/host:/mnt/tls"
    
      traefik-forward-auth:
        environment:
          - TFA_TLSPATH=/etc/traefik-forward-auth
          - TFA_TLSCLIENTAUTH=true
        labels:
          # Note the use of "https"
          - "traefik.http.middlewares.traefik-forward-auth.forwardauth.address=https://traefik-forward-auth:4181"
          # Set the client certificates
          - "traefik.http.middlewares.traefik-forward-auth.forwardauth.tls.ca=/mnt/tls/tls-ca.pem"
          - "traefik.http.middlewares.traefik-forward-auth.forwardauth.tls.cert=/mnt/tls/tls-cert.pem"
          - "traefik.http.middlewares.traefik-forward-auth.forwardauth.tls.key=/mnt/tls/tls-key.pem"
          - "traefik.http.middlewares.traefik-forward-auth.forwardauth.authResponseHeaders=X-Forwarded-User"
          - "traefik.http.services.traefik-forward-auth.loadbalancer.server.port=4181"
          - "traefik.http.services.traefik-forward-auth.loadbalancer.serversTransport=forwardAuthCA@file"
          - "traefik.http.routers.traefik-forward-auth.rule=Host(`auth.example.com`)"
          - "traefik.http.routers.traefik-forward-auth.entrypoints=websecure"
          - "traefik.http.routers.traefik-forward-auth.tls=true"
    
  5. Set the server transport in the Traefik configuration using a File provider:

    http:
      serversTransports:
        forwardAuthCA:
          rootCAs:
            - "/mnt/tls/tls-ca.pem"
    

If the certificates are updated on disk, Traefik Forward Auth automatically reloads them.

When mTLS is used, only the root endpoint (/) authenticates the client certificate. Other endpoints will be served over TLS, but will not require the callers to present a valid client certificate.

Note: you can enable TLS in Traefik Forward Auth without configuring mTLS for authenticating Traefik. In this case, set tlsClientAuth to false, but nonetheless mount the server certificates in the Traefik Forward Auth containers. When configuring Traefik, do not include client certificates.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL