Reverse proxy
Use this page when authentik is exposed through a reverse proxy or load balancer.
authentik uses WebSockets for communication with Outposts. Your reverse proxy must support HTTP/1.1 or newer. HTTP/1.0 reverse proxies are not supported.
Required proxy headers
When authentik is behind a reverse proxy, configure the proxy to set the following headers from the original request. The proxy should overwrite any corresponding headers supplied by the client. These headers tell authentik which host the client requested, whether the original connection used HTTP or HTTPS, what the client IP address was, and whether the request is attempting to upgrade to a WebSocket connection.
At a minimum, configure these headers in your reverse proxy:
-
X-Forwarded-HostorHostPreserves the original host requested by the client. Required for security checks, correct URL handling, WebSocket handshakes, and communication with outposts and proxy providers.
-
X-Forwarded-ProtoTells authentik whether the original client connection used HTTP or HTTPS.
-
X-Forwarded-ForPreserves the original client IP address so authentik can determine where the request came from.
-
Connection: UpgradeandUpgrade: WebSocketRequired to upgrade WebSocket requests when using HTTP/1.1.
It is also recommended to use a modern TLS configuration.
Trusted proxy networks
authentik only accepts the headers listed above, excluding Connection and Upgrade, when the request comes from a trusted proxy network. authentik does not use forwarded headers from other sources to determine the original host, scheme, or client address.
The trusted address is the source address from which the reverse proxy connects directly to authentik. In containerized deployments, this is typically the reverse proxy container or cluster network, not the client IP address.
By default, authentik trusts these proxy networks, but you can change the list of trusted proxy networks with AUTHENTIK_LISTEN__TRUSTED_PROXY_CIDRS:
127.0.0.0/810.0.0.0/8172.16.0.0/12192.168.0.0/16fe80::/10::1/128
Setting AUTHENTIK_LISTEN__TRUSTED_PROXY_CIDRS replaces the default list. If your reverse proxy or load balancer connects from an address outside the default networks, set this option to every address or network from which a trusted proxy connects directly to authentik. Do not include networks from which untrusted clients can connect directly to authentik.
For Docker Compose, set the value in your .env file:
AUTHENTIK_LISTEN__TRUSTED_PROXY_CIDRS=<trusted_proxy_networks>
For Kubernetes deployments using the authentik Helm chart, set:
authentik:
listen:
trusted_proxy_cidrs: "<trusted_proxy_networks>"
For more information, see Configuration.
If the proxy's source address is not trusted, authentik ignores its forwarded headers. This can cause authentik to:
- interpret an HTTPS request as HTTP and generate HTTP URLs
- display an endless loading indicator or an authentication error because the browser blocks mixed content
- log the reverse proxy address instead of the client address
Example: nginx
The following nginx configuration is a reasonable starting point. It proxies to authentik's HTTPS listener on port 9443.
If you proxy to authentik's HTTP listener instead, change the upstream port to 9000 and change proxy_pass https://authentik; to proxy_pass http://authentik;.
# Upstream where your authentik server is hosted.
upstream authentik {
server <hostname of your authentik server>:9443;
# Improve performance by keeping some connections alive.
keepalive 10;
}
# Upgrade WebSocket if requested, otherwise use keepalive
map $http_upgrade $connection_upgrade_keepalive {
default upgrade;
'' '';
}
server {
# HTTP server config
listen 80;
listen [::]:80;
server_name sso.domain.tld;
# 301 redirect to HTTPS
return 301 https://$host$request_uri;
}
server {
# HTTPS server config
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name sso.domain.tld;
# TLS certificates
ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem;
add_header Strict-Transport-Security "max-age=63072000" always;
# Proxy authentik
# If authentik is served under a subpath, also review:
# https://docs.goauthentik.io/install-config/configuration/#authentik_web__path
location / {
proxy_pass https://authentik;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade_keepalive;
}
}
Example: Traefik
This example uses Traefik's Docker provider with Docker Compose labels. It assumes that Traefik already has a websecure entry point with TLS enabled and a valid certificate for your public hostname, and that Traefik and authentik share a Docker network.
Add these labels to the server service in authentik's Compose file, and replace sso.domain.tld with your public hostname:
services:
server:
labels:
traefik.enable: "true"
traefik.http.routers.authentik.rule: "Host(`sso.domain.tld`)"
traefik.http.routers.authentik.entrypoints: websecure
traefik.http.routers.authentik.service: authentik
traefik.http.services.authentik.loadbalancer.server.port: "9000"
Traefik terminates TLS for clients and forwards requests to authentik over HTTP on port 9000. It sets the forwarded headers and passes WebSocket upgrades through without extra configuration.
Traffic between Traefik and authentik on port 9000 is unencrypted, so only attach trusted containers to the shared network. If Traefik should be the only way to reach authentik, remove the 9000 and 9443 port mappings from the server service.
If the authentik container is attached to more than one network, set the network Traefik should use with the traefik.docker.network label or the providers.docker.network option.
authentik sees requests coming from Traefik's address on the shared network. Docker's default address pools are within 172.16.0.0/12 and 192.168.0.0/16, which authentik trusts by default. If you use a custom address pool or have changed AUTHENTIK_LISTEN__TRUSTED_PROXY_CIDRS, make sure the list includes that network. See Trusted proxy networks.
If another proxy or load balancer sits in front of Traefik, add its address to the entry point's forwarded headers trusted IPs. Otherwise, Traefik replaces the forwarded headers that proxy sets.
If Traefik also protects other applications with authentik forward auth, do not apply that middleware to authentik's router, either directly or through the entry point. Doing so causes a redirect loop.
Connect to authentik over HTTPS
To encrypt the connection between Traefik and authentik, route to port 9443 instead. Traefik verifies the upstream certificate, so authentik's default self-signed certificate does not work. Assign a Web Certificate that covers sso.domain.tld to the brand for that domain.
Change the port label to "9443" and add these labels:
traefik.http.services.authentik.loadbalancer.server.scheme: https
traefik.http.services.authentik.loadbalancer.serverstransport: authentik-tls@file
Traefik connects to the container IP address, so it needs a ServersTransport that tells it which hostname to verify. Define it in a file provider directory:
http:
serversTransports:
authentik-tls:
serverName: sso.domain.tld
If Traefik does not have a file provider yet, start it with --providers.file.directory=/etc/traefik/dynamic and mount the directory that contains traefik-dynamic.yml at /etc/traefik/dynamic.
If a private CA issued the Web Certificate, mount the CA certificate into the Traefik container and add it to rootCAs:
http:
serversTransports:
authentik-tls:
serverName: sso.domain.tld
rootCAs:
- /etc/traefik/authentik-ca.pem
Troubleshooting
- An endless loading indicator, a generic authentication error, or a browser error about blocked mixed content usually means that authentik is interpreting an HTTPS request as HTTP.
- Use the browser's developer tools to check whether the page is attempting to load an
http://authentik URL from anhttps://page. - Verify that the reverse proxy sets
X-Forwarded-Prototo the original client scheme. For an HTTPS request, the proxy must sendX-Forwarded-Proto: https, even if the proxy connects to authentik over HTTP on port9000. - Verify that the address from which the proxy connects to authentik is included in
AUTHENTIK_LISTEN__TRUSTED_PROXY_CIDRS. authentik ignores forwarded headers from untrusted addresses.
- Use the browser's developer tools to check whether the page is attempting to load an
- If Traefik returns
502 Bad Gateway, check that Traefik can reach authentik on the shared network and that the port and scheme match:9000with HTTP or9443with HTTPS. On port9443, also check that the Web Certificate covers theserverNamein the ServersTransport and that Traefik trusts the certificate issuer. - CSRF errors when saving objects are usually caused by incorrect
HostorOriginhandling. See Troubleshooting CSRF Errors. - Incorrect client IP addresses usually mean the proxy IP is not covered by
AUTHENTIK_LISTEN__TRUSTED_PROXY_CIDRS. - Broken outpost or proxy provider communication often means the WebSocket upgrade headers are missing or the proxy is not using HTTP/1.1 or newer.