Reverse Proxy Authentication
New as of 1.4.0
Dokku Pro can trust an identity-aware reverse proxy to authenticate users. When the proxy in front of Dokku Pro sets a configured HTTP header naming the logged-in user, Dokku Pro reads that header, resolves the matching user, and issues a normal session with no login form. This is the same mechanism used by Tailscale Serve's identity headers and Gitea's reverse-proxy authentication.
Direct (non-proxy) access continues to fall back to the usual username and password login, and the header is never trusted from an untrusted source.
Security model
Read this before enabling the feature
A trusted identity header is only as trustworthy as the network path in front of it. Any client that can reach Dokku Pro directly can forge the header and sign in as anyone. Only enable this feature when all of the following hold.
- Dokku Pro must be reachable only through the proxy. Bind it to localhost or a private network, or firewall it so no request can bypass the authenticating proxy.
- Restrict the trusted proxies. Set
REVERSE_PROXY_AUTH_TRUSTED_PROXIESto the proxy's IP or CIDR. When it is empty the feature is inert (it fails closed), and the header is never trusted even if the feature is enabled. - The proxy must strip any inbound copy of the header and re-set it from the authenticated session, so a client-supplied value never survives.
- Mind header-name normalization. In some stacks
-and_collapse to the same key, soX-Auth_Usercan impersonateX-Auth-Userif the proxy does not normalize.
The trust check uses the immediate TCP peer's address, not X-Forwarded-For (which a
client can spoof). If Dokku Pro sits behind additional proxies, list the address it
actually sees.
Configuration
Reverse proxy authentication is configured through the environment. See the configuration documentation for the full reference.
| variable | default | description |
|---|---|---|
REVERSE_PROXY_AUTH_ENABLED |
false |
Master switch for the feature. |
REVERSE_PROXY_AUTH_HEADER |
X-WEBAUTH-USER |
The header to read the identity from. |
REVERSE_PROXY_AUTH_TRUSTED_PROXIES |
empty | Comma-separated IPs/CIDRs allowed to set the header. * trusts any source. Empty disables the feature. |
REVERSE_PROXY_AUTH_AUTO_REGISTRATION |
false |
Auto-create an unknown user on first proxy login. |
REVERSE_PROXY_AUTH_REGISTRATION_TEAM |
empty | Team to add an auto-registered user to at creation. Must already exist. |
REVERSE_PROXY_AUTH_STRIP_EMAIL_DOMAIN |
false |
Map an email-style header value such as alice@example.com to alice. |
A minimal configuration that trusts a proxy running on the same host:
REVERSE_PROXY_AUTH_ENABLED=true
REVERSE_PROXY_AUTH_HEADER=X-WEBAUTH-USER
REVERSE_PROXY_AUTH_TRUSTED_PROXIES=127.0.0.1/32,::1/128
Username matching
The header value maps to a Dokku Pro username with its case preserved, so the proxy
must send the exact stored username. Usernames are compared case-sensitively but are
unique case-insensitively: if bob exists, a header of Bob will not match, and with
auto-registration enabled it is rejected rather than created. Keep the casing your proxy
sends consistent with the casing you create users with.
Since usernames may contain uppercase letters, underscores, dots, and @,
an email-style value such as alice@example.com is itself a valid username. To instead
map it to the local part (alice), enable REVERSE_PROXY_AUTH_STRIP_EMAIL_DOMAIN.
Unknown users
By default only pre-existing users can sign in through the proxy; an unknown user is
rejected. Set REVERSE_PROXY_AUTH_AUTO_REGISTRATION=true to instead create a passwordless
user on first login. Such a user starts with no team access and can later be given a
password via users:refresh-reset-token.
When REVERSE_PROXY_AUTH_REGISTRATION_TEAM is set, an auto-registered user is added to
that team as a member at creation time only (they are not re-added on later logins, so an
administrator removing them stays authoritative). The team must already exist; a missing
team fails the registration and the login.
Integrating with identity-aware proxies
Set REVERSE_PROXY_AUTH_HEADER to the header your proxy injects. The values below were
verified against current provider documentation.
| Proxy | Header to configure | Notes |
|---|---|---|
| Tailscale Serve | Tailscale-User-Login |
Serve only; Funnel traffic is public and carries no identity. Bind Dokku Pro to localhost. |
| Cloudflare Access | Cf-Access-Authenticated-User-Email |
Opt-in convenience header; the signed Cf-Access-Jwt-Assertion is authoritative. |
| oauth2-proxy (upstream) | X-Forwarded-Email or X-Forwarded-User |
Sent with --pass-user-headers (on by default). |
| oauth2-proxy (auth_request) | X-Auth-Request-Email or X-Auth-Request-User |
Set with --set-xauthrequest. |
| Authelia | Remote-User (or Remote-Email) |
Copy it through with authResponseHeaders / copy_headers. |
| Authentik | X-authentik-username (or X-authentik-email) |
Note the lowercase authentik; include it in the proxy's authResponseHeaders. |
| Pomerium | X-Pomerium-Claim-Email |
Requires pass_identity_headers and jwt_claims_headers. |
| Vouch Proxy | X-Vouch-User |
Copy via nginx auth_request_set. |
| Google Cloud IAP | X-Goog-Authenticated-User-Email |
The value is prefixed with accounts.google.com:, which contains a : (invalid in usernames). Strip the prefix at the proxy before it reaches Dokku Pro. |
| AWS ALB (OIDC) | x-amzn-oidc-identity |
Carries the sub; x-amzn-oidc-data is the signed JWT. |
| Azure App Service Easy Auth | X-MS-CLIENT-PRINCIPAL-NAME |
This is App Service Easy Auth, not Entra Application Proxy (a different contract). |
nginx auth_request / Traefik forwardAuth |
operator-chosen | These relay whatever header the auth backend returns; match the backend's contract above. |
Dokku Pro joins a well-established pattern also used by header-consuming applications such
as Gitea/Forgejo, Grafana, Jenkins, and Miniflux; the default header name
(X-WEBAUTH-USER) matches Gitea's.
Signing in
When the feature is active, the sign-in screen attempts a transparent login on load. If the trusted proxy header is present the browser is signed in and redirected to the dashboard automatically. If it is not, the usual username and password form is shown, so password login remains available for direct access.