Provisioning Authentik Middleware with Traefik Reverse Proxy Using Internal Samba AD CA
Introduction
Protecting internal services behind a reverse proxy is one thing -- adding single sign-on backed by your own Active Directory and internal CA is where it starts to feel like a real enterprise stack. In this post, I walk through how I integrated Authentik as a forwardAuth middleware with Traefik, using TLS certificates issued by my Samba AD CA and LDAPS for directory lookups.
This setup delivers:
- Trusted HTTPS access to services proxied through Traefik
- SSO enforcement using Authentik via the forwardAuth middleware
- Certificate-based trust rooted in my Samba 4 AD CA
- Authentik outpost (proxy) deployed as a sidecar container to manage authentication flows
Prerequisites
- Working Traefik reverse proxy deployed via Docker Compose
- Authentik server accessible at
https://authentik.example.lan - Valid internal CA-signed certificates for both Traefik and Authentik
- Samba 4 running as internal CA with LDAPS enabled
- Docker and Docker Compose installed
- DNS records pointing to correct internal service IPs (e.g.,
traefik.example.lan)
Authentik Setup Notes
- Authentik was configured to use LDAPS for user directory integration against Samba AD.
- Users from a specific group (e.g.,
AuthorizedSSOUsers) were assigned access to the Traefik application. - An embedded outpost was initially tested, but the dedicated container provided cleaner integration.
Directory Layout
/home/username/traefik-authentik/
├── docker-compose.yml # Main Docker Compose file
├── Dockerfile # Custom Dockerfile for the Authentik outpost
├── .env # (Optional) Environment variables file
├── certs/ # Internal CA and TLS certs
│ ├── ca.crt # Internal Samba AD CA certificate (PEM format)
│ ├── authentik.example.lan.crt # Authentik SSL certificate
│ ├── authentik.example.lan.key # Authentik SSL key
│ ├── traefik.example.lan.crt # Traefik dashboard SSL certificate
│ └── traefik.example.lan.key # Traefik dashboard SSL key
├── traefik/
│ ├── traefik.yml # Static Traefik configuration
│ ├── middleware.yml # Middleware definition for Authentik SSO
│ └── tls.yml # TLS options and certificate stores
Notes:
- The
certs/folder is mounted into containers to provide all necessary trusted CA and TLS materials. - All certificates must be in PEM format.
- The
Dockerfileshould use a multi-stage approach or add the CA and callupdate-ca-certificatesasroot. - The
traefik/folder holds Traefik's dynamic configuration files. - You can substitute
/home/username/traefik-authentik/with any appropriate directory, but all relative volume mounts indocker-compose.ymlshould align.
1. Traefik Configuration Overview
traefik.yml
global:
checkNewVersion: false
sendAnonymousUsage: false
accessLog: {}
log:
level: TRACE
api:
dashboard: true
insecure: false
debug: false
entryPoints:
web:
address: :80
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: :443
serversTransport:
insecureSkipVerify: true # Useful during internal CA testing phase
providers:
docker:
exposedByDefault: false
endpoint: 'unix:///var/run/docker.sock'
watch: true
file:
directory: /etc/traefik/conf/
watch: true
Global Settings
global: Root-level settings for global Traefik behaviorcheckNewVersion: false: Disables automatic checking for new Traefik versions (I prefer to update manually)sendAnonymousUsage: false: Prevents sending anonymous usage statistics to Traefik developers
Access Log Configuration
accessLog: {}: Enables access logging with default settings (empty config block)
General Logging Configuration
log.level: TRACE: Sets the logging level to the most verbose (TRACE), useful for debugging and troubleshooting
API and Dashboard
api.dashboard: true: Enables the Traefik web dashboardapi.insecure: false: Dashboard is only accessible via a secure entry point (not exposed on HTTP)api.debug: false: Disables the debug endpoint, which can expose sensitive info
Entry Points (Ports)
entryPoints: Defines how Traefik listens for incoming trafficweb.address: :80: Listens on port 80 (HTTP)http.redirections.entryPoint.to: websecure: Redirects all HTTP traffic to HTTPSscheme: https: Specifies the protocol for redirectionwebsecure.address: :443: Listens on port 443 (HTTPS)
TLS Transport Options
serversTransport.insecureSkipVerify: true: Disables certificate verification when Traefik communicates with backend services. Use only for internal services or testing, as it bypasses TLS validation.
Providers
providers.docker: Enables Docker as a dynamic configuration provider.exposedByDefault: false: Services are not automatically exposed to Traefik unless explicitly enabled via labels.endpoint: Communicates with Docker through the local Unix socket.watch: true: Automatically reloads config when Docker changes (e.g., containers start/stop).
providers.file: Enables static/dynamic config from a file directory.directory: /etc/traefik/conf/: Path to directory containing additional dynamic configuration files (like routers, middlewares, TLS certs).watch: true: Traefik watches this directory for live changes and reloads as needed.
conf/middleware.yml
http:
middlewares:
authentik:
forwardAuth:
address: http://NAME-OF-AUTHENTIK-OUTPOST:9000/outpost.goauthentik.io/auth/traefik
trustForwardHeader: true
authResponseHeaders:
- X-authentik-username
- X-authentik-groups
- X-authentik-entitlements
- X-authentik-email
- X-authentik-name
- X-authentik-uid
- X-authentik-jwt
- X-authentik-meta-jwks
- X-authentik-meta-outpost
- X-authentik-meta-provider
- X-authentik-meta-app
- X-authentik-meta-version
This middleware configuration tells Traefik to forward every incoming request to the Authentik outpost for authentication before passing it to the backend service.
middlewares: Defines one or more middleware objects that routers can reference.authentik: The name assigned to this middleware. Attach it to a router with the labeltraefik.http.routers.<name>.middlewares=authentik@file.forwardAuth: Specifies the forward authentication model -- Traefik sends each incoming request to an external authentication server (Authentik) before routing it to the backend.address: The URL Traefik forwards incoming requests to for authentication. This must point to the Authentik Outpost's Traefik-specific forwardAuth endpoint.trustForwardHeader: true: Tells Traefik to forwardX-Forwarded-*headers from the client (e.g., real client IP, host info). Authentik needs these headers to make access decisions.authResponseHeaders: Headers returned from Authentik that Traefik passes through to the backend service. These typically contain user metadata, group memberships, entitlements, and JWT tokens -- essential for the application to know who is logged in and what they're authorized to do.
conf/tls.yml
tls:
certificates:
- certFile: /var/traefik/certs/traefik.example.lan.crt
keyFile: /var/traefik/certs/traefik.example.lan.key
- certFile: /var/traefik/certs/authentik.example.lan.crt
keyFile: /var/traefik/certs/authentik.example.lan.key
stores:
default:
defaultCertificate:
certFile: /var/traefik/certs/traefik.example.lan.crt
keyFile: /var/traefik/certs/traefik.example.lan.key
options:
default:
minVersion: VersionTLS12
sniStrict: true
curvePreferences:
- CurveP256
- CurveP384
- CurveP521
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
The tls.yml file specifies TLS certificates and key files signed by the internal Samba CA.
Summary
This configuration:
- Defines and serves multiple domain-specific certificates
- Uses strong security defaults (TLS 1.2+, strict SNI, PFS ciphers)
- Ensures fallback TLS service via the default certificate store
Root Key
tls: Root section for configuring TLS certificates, stores, and security options.
TLS Certificates
certificates: List of TLS certificates that Traefik will serve.certFile: Path to the public certificate file (PEM format).keyFile: Path to the associated private key.
- Each certificate is matched against incoming requests by their SNI (Server Name Indication) hostname (e.g.,
traefik.example.lan,authentik.example.lan).
Default Certificate Store
stores: Defines named TLS stores. The default store is used when no matching SNI is found.defaultCertificate: A fallback certificate that Traefik uses if no specific certificate matches the request's hostname.
TLS Security Options
options: Defines reusable TLS options (like security policies).default: The default TLS policy applied if not overridden.minVersion: VersionTLS12: Only allows TLS 1.2 or higher (disables older, insecure TLS versions).sniStrict: true: Requires a matching certificate for the SNI; otherwise Traefik rejects the connection.
Curve Preferences
curvePreferences: Preferred elliptic curves for ECDHE (Elliptic Curve Diffie-Hellman Ephemeral) key exchange. This list defines the order of preference for stronger cryptographic curves.
Cipher Suites
cipherSuites: Explicitly defines the allowed cipher suites for TLS 1.2 connections (TLS 1.3 has its own fixed ciphers). All suites listed here support strong AEAD encryption and PFS (Perfect Forward Secrecy) via ECDHE.
2. Docker Compose Configuration
docker-compose.yml
Create a unified docker-compose.yml that includes both traefik and the authentik-outpost:
services:
traefik:
container_name: traefik
image: traefik:latest
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- filepathto/traefik.yml:/etc/traefik/traefik.yml:ro
- filepathto/traefik/config/:/etc/traefik/conf:ro
- filepathto/traefik/certs/:/var/traefik/certs/:rw
networks:
- frontend
- backend
labels:
- traefik.enable=true #enables Traefik reverse proxy for this container
- traefik.http.routers.traefik.rule=Host(`traefik.example.lan`) #defines a router that activates when requests match the domain specified
- traefik.http.routers.traefik.entrypoints=websecure #binds the router to HTTPS (websecure) entry point
- traefik.http.routers.traefik.tls=true #enables TLS for this router
- traefik.http.routers.traefik.middlewares=authentik@file #applies the middleware named authentik from the file provider (in my case middleware.yml) for auth
- traefik.http.routers.traefik.service=api@internal #tells Traefik to serve its internal API/dashboard when this route is hit
restart: unless-stopped
authentik-outpost:
container_name: traefik-authentik-outpost
image: custom-authentik-outpost #use custom image to load trusted internal CA cert into container
volumes:
- filepathto/certs:/certs:ro
restart: unless-stopped
networks:
- frontend
- backend
environment:
- AUTHENTIK_HOST=https://authentik.example.lan
- AUTHENTIK_INSECURE=false #requires valid HTTPS connection (doesn't skip tls checks)
- REQUESTS_CA_BUNDLE=/certs/ca.crt #instructs Python-based tools (used by Authentik Proxy) to trust internal CA for TLS
- LOG_LEVEL=debug
- AUTHENTIK_HOST_BROWSER=https://authentik.example.lan #used when public and internal addresses differ
- AUTHENTIK_TOKEN=xxxxxxxxxxxxxxx # Replace with Authentik outpost token. Token is necessary to authenticate the outpost with the Authentik server. DO NOT EXPOSE
networks:
frontend:
external: true
backend:
external: true
Highlights:
- Traefik loads configuration from mounted YAML files.
- The Authentik outpost uses the internal CA to validate Authentik's certificate.
- If
AUTHENTIK_INSECURE=falsefails due to CA trust, temporarily flip it totruewhile you troubleshoot. - Replace
custom-authentik-outpostwith the name of your custom image (see next step).
3. Custom Dockerfile for Outpost (Trust Internal CA)
To trust my internal Samba CA, I built a custom image for the Authentik proxy outpost. This resolves certificate validation issues by appending the Samba AD CA to the container's trust store.
Dockerfile for Custom Outpost Image
Name the file exactly Dockerfile:
FROM ghcr.io/goauthentik/proxy:latest
COPY ./certs/ca.crt /usr/local/share/ca-certificates/ca.crt
RUN update-ca-certificates
Then build it with:
sudo docker build -t custom-authentik-outpost .
This ensures the Authentik outpost container trusts my internal certificate hierarchy.
4. Authentik Configuration
In the Authentik dashboard:
Application
- Name: traefik-dashboard
- Slug:
traefik-dashboard - Launch URL:
https://traefik.example.lan/dashboard/ - Provider: The proxy provider you created (in my case
traefik-forward-auth) - Policy engine mode: any
Provider (Proxy)
- Type: Proxy
- Name: traefik-forward-auth
- Authorization flow: default-provider-authorization-explicit-consent (Authorize Application)
- Use forward auth (single application)
- The external host address should be the FQDN you want to access the application at
- In my case:
https://traefik.tillynet.lansince I want to protect my Traefik dashboard with Authentik
- Token Validity: hours=24
Outpost
Create a new Authentik Outpost to deploy in the same Docker Compose config as Traefik (see the docker-compose.yml above for deploying the outpost as a Docker container):
- Name: traefik-authentik-outpost
- Type: Proxy
- Integration: Local Docker connection
- Applications: Link your
traefik-dashboardapplication - Token: After creating the outpost, copy your Authentik token and paste it in
docker-compose.yml - Health check: Ensure Authentik sees the outpost as healthy after the container has been deployed
5. Start the Stack
docker compose up -d
You should now be able to access:
https://traefik.example.lan/dashboard/-- protected by Authentik SSO
6. Troubleshooting Tips
- Ensure your internal CA is correctly mounted and trusted in the custom container.
- If you see
x509: certificate signed by unknown authority, the CA is likely missing from the container's trust store. - Use
docker logsfor both Traefik and the outpost to trace errors. - Check firewall/NAT between the Docker bridge network (172.x) and your internal CA if you get
connection reset by peer. Do not use the default Docker bridge network -- create dedicated networks as shown in the compose file.
7. Final Outcome
At this point you should be able to:
- Visit
https://traefik.example.lan/dashboard/ - Get redirected to Authentik SSO
- Log in via your authorized AD credentials using LDAPS
- Gain access to the secured dashboard with a valid TLS certificate
This project brought together reverse proxying, identity management, and internal PKI into a cohesive, reproducible stack. It serves as a solid foundation for any homelab aiming to mirror enterprise SSO and certificate trust patterns.