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
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 (not yet implemented)

1. Outpost container

Deploy goauthentik/proxy (or current Authentik outpost image) on infra-services:

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

2. Authentik admin

For each protected *.infra.realemail.app hostname (or one domain-level provider for the whole zone):

  1. Applications → create app (Grafana, Komodo, …)
  2. Providers → Proxy Provider → Forward auth (single application) or domain level
  3. Outposts → assign provider to the infra outpost instance
  4. External host = https://<app>.infra.realemail.app

3. Infra Traefik

File provider or labels on outpost service:

# Pattern — see Authentik docs for full header list
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:
    grafana:
      rule: Host(`grafana.infra.realemail.app`)
      middlewares: [authentik]
    grafana-outpost:
      rule: Host(`grafana.infra.realemail.app`) && PathPrefix(`/outpost.goauthentik.io/`)
      priority: 15
      service: authentik-outpost

Apply middlewares: [authentik] to every infra router except break-glass docs (if any). 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
  • [ ] Outpost on same host as Traefik includes this provider
  • [ ] Traefik router uses forward-auth middleware (or app uses OIDC)
  • [ ] 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.