Skip to content

Replace Authentik forward-auth with shared oauth2-proxy + per-route group gate

Date: 2026-07-03 Status: Accepted Decision: hl-1fia Deciders: sean

Authentik’s embedded outpost provided Traefik forwardAuth for 5 internal dashboards (agentgateway, temporal, hubble, traefik-dashboard, longhorn). Keycloak — the cluster IdP after the hl-5g05 migration — is OIDC-only and cannot forward-auth, so these dashboards need an oauth2-proxy shim before the Authentik pod can be removed (design hl-0ahs). The design had to choose an authorization granularity and infrastructure footprint for that shim.

Deploy one shared oauth2-proxy (keycloak-oidc provider) fronting all 5 dashboards. Each dashboard’s Traefik forwardAuth middleware appends a distinct ?allowed_groups=<app>-users query parameter to oauth2-proxy’s /oauth2/auth endpoint, enforcing per-app group membership at the proxy without per-app infrastructure. Groups are flat <app>-users (not nested) because the shared Keycloak groups mapper sets full_path=false.

  • oauth2-proxy’s /oauth2/auth endpoint has documented support for a per-request allowed_groups query parameter, so a single instance can still enforce per-app boundaries.
  • Per-app least-privilege authorization is a stated goal; a coarse single-group gate fails it outright.
  • Per-instance isolation multiplies Deployments, Keycloak clients, and CA-bundle configs 5x for a homelab trust model where the residual shared-blast-radius risk is acceptable.
  • The chosen design is reversible — split to per-app clients later without changing the authorization model.
  • Single shared oauth2-proxy with per-route ?allowed_groups= override (chosen): per-app least-privilege via one Deployment / one client / one CA bundle.
  • Coarse single-group gate, rev-1 (rejected): simplest, but any dashboard-authorized user reaches all 5 dashboards — no per-app authorization.
  • Per-app oauth2-proxy instances, rev-2 (rejected): full per-app isolation, but 5x the Deployments/clients/CA-bundle configs for homelab scale.
  • Positive: one Deployment / client / CA bundle to operate and patch; per-app group gating preserved; SSO across dashboards via the shared cookie.
  • Negative: shared session/cookie + single client secret means compromising the shared proxy or its credential affects all 5 dashboards; correctness depends on the pinned oauth2-proxy chart honoring the allowed_groups query override.
  • Neutral: future per-app credential isolation is possible later without redesigning the authorization model.