Repository navigation
Forward Auth
The image ghcr.io/govengers/forwardauth (binary cmd/forwardauth) runs one provider, PROVIDER=oidc (optionally with Keycloak enrichment) or PROVIDER=github, in front of any app behind Traefik. It needs no code in the app; a Go backend verifies the optional JWT with jwt.Verifier. Password login is not offered.
- Traefik's
forwardAuthmiddleware callsGET {prefix}/ui(browsers: 302 to the login when unauthenticated) orGET {prefix}/api(APIs: 401 JSON) for every request. - 200 lets the request through, with a signed JWT in
Authorization(JWT_ENABLED=true); 302, 401 and 403 go to the client. - Login, callback, logout and the JWKS are served under
{prefix}(default/auth) on the app's own host, through a separate Traefik router. - Optional static API keys (
API_KEYS_ENABLED) with permissions, no roles. - One instance serves one external origin; without Redis (
SESSION_REDIS_ENABLED) it is a single replica.
{prefix}/ui, {prefix}/api (checks), {prefix}/jwks, {prefix}/me (optional), {prefix}/health, {prefix}/ready, the provider routes ({prefix}/oidc/<OIDC_NAME>/... or {prefix}/github/...) and GET /metrics on METRICS_PORT. Table with answers: Forward-Auth-Configuration.
Environment variables only; the process lists every problem and exits before serving. Full table with defaults: Forward-Auth-Configuration. The minimum: PROVIDER, EXTERNAL_URL (origin without path), SESSION_ENCRYPTION_KEY, plus OIDC_ISSUER, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET or GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, GITHUB_ALLOWED_TEAMS. Callback URL to register: <EXTERNAL_URL><PATH_PREFIX>/oidc/<OIDC_NAME>/callback or <EXTERNAL_URL><PATH_PREFIX>/github/callback.
Copy from Forward-Auth-Configuration (docker labels, production with TLS, Kubernetes CRDs); the tested stack is test/e2e/compose. The rules that matter:
- A router for
PathPrefix(/auth)to forwardauth without the forwardAuth middleware, excluding/auth/ui,/auth/api,/auth/healthand/auth/ready(one!Patheach); the checks and probes stay internal. - forwardAuth middleware:
authResponseHeadersAuthorizationandX-API-Key(Traefik strips the client's copies; a forged token never reaches the app),trustForwardHeader: false,maxResponseBodySize. - Entrypoints:
http.aliasHeadersStrategy=delete. - Probes at
{prefix}/healthand{prefix}/readyon port 8080; keepMETRICS_PORToff Traefik.
-
EXTERNAL_URLon plainhttpoff loopback needsSESSION_INSECURE_COOKIE=true(local only);app.localhostis not loopback. -
JWT_PRIVATE_KEYandJWT_AUDIENCEare required withJWT_ENABLED; no generated key, so every replica signs with the same one. - With
API_KEYS_ENABLED, a bearer token that is not a configured key is 401 on both checks, even with a session cookie. - An inactive identity is 403 on both checks.
- Logout links (
{prefix}/oidc/<name>/logout,{prefix}/github/logout) must be on the app's own site.
Source: cmd/forwardauth/main.go, internal/forwardauth/, docs/infrastructure-notes.md (image, CI, e2e).
Mirror of docs/wiki at v1.4.0 (5734859). Edit the repository, not this wiki.