Skip to content

Authentik cross-host SSO

Implements ADR-002: Authentik universal SSO.

Requirement: All user-facing HTTPS services on all hosts are Authentik-protected. Exception: Plex on saltierpoop (plex.realemail.app) only.

Authentik server stays on saltierpoop (auth.realemail.app, Saltbox). Other hosts use local outposts + Traefik forward auth (or native OIDC).


Reference architecture

Host Traefik Authentik enforcement
saltierpoop *.realemail.app Saltbox authentik@docker middleware (+ per-app outposts e.g. HA)
infra-services *.infra.realemail.app Homelab outpost + infra Traefik forwardAuth (Komodo: native OIDC instead)
Future hosts TBD Outpost co-located with that host’s reverse proxy

Precedent on saltierpoop: ak-outpost-home-assistant — dedicated outpost for a non-standard app host.


infra-services rollout

Repo artifacts:

Path Purpose
services/authentik-outpost/ Outpost container + SOPS token
services/traefik/config/dynamic/authentik.yml authentik@file middleware + callback router
services/*/compose.yml App routers use traefik.http.routers.<name>.middlewares=authentik@file (except Komodo — OIDC)

1. Outpost container

Deploy ghcr.io/goauthentik/proxy on infra-services:

  • Join traefik external network
  • Env: AUTHENTIK_HOST=https://auth.realemail.app, outpost token from Authentik admin
  • Homelab-managed — not Saltbox (services/authentik-outpost/compose.yml)

Owner admin walkthrough: authentik-infra-admin-setup.md (step-by-step Authentik UI, token → SOPS, verify).

See services/authentik-outpost/README.md for deploy order on infra-services.

2. Authentik admin (summary)

Full checklist: authentik-infra-admin-setup.md.

Short version:

  1. Create with provider → Proxy Provider → Forward auth (domain level)
  2. Authentication URL https://homepage.infra.realemail.app, Cookie domain infra.realemail.app
  3. Outposts → manual proxy outpost infra-services → assign application → copy token → SOPS

Komodo: separate OAuth2/OIDC provider — komodo-authentik-oidc.md (no forward-auth on Komodo router).

3. Infra Traefik

File provider (services/traefik/config/dynamic/authentik.yml):

http:
  middlewares:
    authentik:
      forwardAuth:
        address: http://authentik-outpost:9000/outpost.goauthentik.io/auth/traefik
        trustForwardHeader: true
        authResponseHeaders:
          - X-authentik-username
          - X-authentik-groups
          - X-authentik-email
  routers:
    authentik-outpost-callback:
      rule: HostRegexp(`^[a-z0-9-]+\.infra\.realemail\.app$`) && PathPrefix(`/outpost.goauthentik.io/`)
      priority: 100
      service: authentik-outpost-callback

Docker labels on each app router:

traefik.http.routers.grafana.middlewares=authentik@file

Apply to every infra Traefik router. Do not apply to Plex (lives on saltierpoop, excluded by ADR).

4. Verify

  • Unauthenticated browser → redirect to Authentik login
  • After login → app loads; headers present if app uses them
  • Plex at plex.realemail.appno Authentik redirect (still direct)

Adding a new service (checklist)

  • [ ] Hostname decided (*.infra.realemail.app vs *.realemail.app)
  • [ ] Authentik Application + Provider created (or covered by domain-level provider)
  • [ ] Outpost on same host as Traefik includes this provider
  • [ ] Traefik router label: traefik.http.routers.<name>.middlewares=authentik@file
  • [ ] Not Plex — if media on saltierpoop and hostname is Plex, skip Authentik per ADR-002
  • [ ] Scrape/webhook paths documented if exempt from browser SSO

Monitoring migration gate

Do not sign off saltbox-monitoring-migration.md until Grafana (and other migrated UIs) at *.infra.realemail.app pass the verify step above.


DR

Authentik server restore: dr-public-edge.md, restore.md § Authentik DB.

After server restore, outposts on infra-services reconnect automatically when auth.realemail.app is healthy; confirm outpost logs if SSO fails post-DR.