From 95272ca4c5179bd935b4d57662e3ba1702056915 Mon Sep 17 00:00:00 2001 From: prosolis <5590409+prosolis@users.noreply.github.com> Date: Sat, 20 Jun 2026 16:03:06 -0700 Subject: [PATCH] docs: document outpost router + priority gotcha for forward-auth The Traefik example was missing the veola-outpost router (PathPrefix /outpost.goauthentik.io/ -> authentik service) and the header-strip middleware, so a fresh deploy following it would 404 on Sign out. Add both, plus a prominent note: the outpost router must outrank the catch-all Host(...) router. Traefik's default priority is rule length, so Authentik's docs value of priority:15 silently loses once the hostname rule exceeds 15 chars (e.g. veola.parodia.dev = 25), letting the catch-all swallow /outpost.goauthentik.io/sign_out into Veola's 404. Use a high explicit priority (100). --- deploy/authentik-forward-auth.md | 43 ++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/deploy/authentik-forward-auth.md b/deploy/authentik-forward-auth.md index 041b290..008eed8 100644 --- a/deploy/authentik-forward-auth.md +++ b/deploy/authentik-forward-auth.md @@ -47,19 +47,58 @@ http: - X-authentik-email - X-authentik-name - X-authentik-groups + # Strip client-supplied identity headers on ingress so only the outpost + # can set them (runs before `authentik` on the protected router). + authentik-strip: + headers: + customRequestHeaders: + X-authentik-username: "" + X-authentik-email: "" + X-authentik-name: "" + X-authentik-groups: "" + X-authentik-uid: "" routers: veola: rule: "Host(`veola.example.com`)" service: veola middlewares: + - authentik-strip - authentik tls: certResolver: letsencrypt + + # The outpost's own endpoints (callback, start, sign_out) must go straight + # to Authentik, NOT through the forwardAuth-protected `veola` router. This + # router has NO auth middleware and points at the authentik service. + veola-outpost: + rule: "Host(`veola.example.com`) && PathPrefix(`/outpost.goauthentik.io/`)" + priority: 100 + service: authentik + tls: + certResolver: letsencrypt + + services: + authentik: + loadBalancer: + servers: + - url: "http://authentik-server:9000/" ``` -Traefik must strip any client-supplied `X-Authentik-*` and `X-Forwarded-*` -headers on ingress so only the outpost can set them. +**Router priority — important.** Both routers match the Veola host, so the more +specific `veola-outpost` must win. Traefik's *default* priority is the rule +length, so the catch-all `veola` router (`Host(...)`) gets a priority equal to +its length (e.g. `Host(`veola.parodia.dev`)` = 25). Authentik's docs example +sets the outpost router to `priority: 15`, which **silently loses** whenever the +hostname rule is longer than 15 chars — the catch-all then swallows +`/outpost.goauthentik.io/*` and hands it to Veola, which 404s. Symptom: clicking +**Sign out** lands on `/outpost.goauthentik.io/sign_out` with a plain +`404 page not found`. Fix: give `veola-outpost` a high explicit priority (e.g. +`100`) so it always beats the catch-all. + +(Login still works even when the outpost router loses, because the outpost +intercepts `callback`/`start` during the forwardAuth `/auth/traefik` round-trip; +`sign_out` is the one path that genuinely needs the dedicated router.) ## Break-glass