Skip to content

ADR-002: Authentik protects all user-facing services (cross-host)

Status: Accepted Date: 2026-06-25 Phase: 4+ (infra Traefik), ongoing for every new service Supersedes: Informal “Saltbox Authentik middleware only on saltierpoop” assumption

Context

Authentik runs on saltierpoop as a Saltbox role (auth.realemail.app). Saltbox Traefik applies authentik@docker forward-auth to many *.realemail.app services — a same-host convenience, not a platform-wide architecture.

ADR-001 places homelab ops services on infra-services with a second Traefik (*.infra.realemail.app). Monitoring consolidation (saltbox-monitoring-migration.md) moves user UI to infra URLs. Those endpoints must not fall back to Grafana admin passwords or open dashboards.

Owner requirement: Authentik must protect all user-facing HTTP(S) services on every host, except for the explicitly registered exceptions below.

Decision drivers

  • Single identity plane — Authentik is the strategic auth provider (PLAN.md)
  • Multi-host lab is permanent (saltierpoop, infra-services, prox guests, Whrrr VMM)
  • Saltbox Traefik middleware does not extend to other hosts
  • Authentik supports cross-host protection via outposts + forward auth (or app-native OIDC)

Decision

Requirement

Scope Rule
Default Every user-facing HTTPS route (browser or human API) is behind Authentik
Hosts saltierpoop, infra-services, and any future Traefik- or web-fronted host
Exceptions Plex on saltierpoop and the temporary Reddit Explorer trusted-network route; see the exception register
Identity server Authentik server stays on saltierpoop (Saltbox-managed, tier-1 backup)

Architecture

                    auth.realemail.app
                    Authentik server (saltierpoop, Saltbox)
                              │
         ┌────────────────────┼────────────────────┐
         │                    │                    │
   Saltbox Traefik      Outpost on            Outpost on
   *.realemail.app      infra-services        other hosts
   (authentik@docker)   *.infra.realemail.app  (as needed)
         │                    │
   *arr, Grafana, …     Grafana, Komodo, …
   Plex — EXCLUDED      all infra UIs — REQUIRED

Enforcement patterns (pick per service; all must satisfy the requirement):

  1. Forward auth (preferred for Traefik-fronted apps) — Traefik forwardAuth to a local outpost on the same host as that Traefik instance. See Authentik Traefik docs.
  2. Dedicated outpost container — Same pattern as existing ak-outpost-home-assistant on saltierpoop for apps off the default embedded outpost.
  3. Native OIDC/OAuth — Application configured in Authentik; app talks to auth.realemail.app directly (acceptable when forward-auth is awkward).

Do not rely on pointing infra Traefik at https://auth.realemail.app/... alone without a local outpost on infra-services — community reports show routing pain; local outpost is the supported model.

  • Saltbox zone: *.realemail.app
  • Infra zone: *.infra.realemail.app

Prefer Authentik forward auth (domain level) per zone where policy allows shared login, or per-application providers where apps need different groups. Expect separate login prompts across zones unless cookie domain is explicitly configured to .realemail.app and verified end-to-end.

Explicit non-requirements (not “exceptions” — different layer)

Traffic Auth model
Prometheus scrape, node_exporter, Alertmanager webhooks Network placement + firewall; not browser SSO
auth.realemail.app itself Authentik login UI (self)
Machine / API tokens (Komodo agents, CI) Authentik M2M or service tokens where applicable — not forward-auth

Phoenix's prepared Companion deployment API route uses this machine-token boundary: exact host/method/path matching plus native Phoenix bearer-key validation, not a browser-wide exemption. The existing UI router retains Authentik. Header presence is not authentication; live native-auth acceptance is required before activation. The global annotation-config collection is explicitly not a project-scoped permission. Source preparation does not imply that this route is deployed or that existing keys have the required permissions.

Options considered

  1. Extend Saltbox middleware to infra via remote forwardAuth URL — rejected (fragile)
  2. Move Authentik server to infra-services — rejected (breaks Saltbox model; server stays on saltierpoop)
  3. Per-app passwords on infra only — rejected (violates owner requirement)
  4. Central server + per-host outposts + Traefik forward auth — accepted

Consequences

  • New homelab service checklist: Traefik labels or file middleware must include Authentik forward-auth (or documented OIDC) before the service is “done”
  • infra-services: deploy Authentik outpost compose (homelab-owned, not Saltbox); wire infra Traefik dynamic middleware; register each *.infra.realemail.app app in Authentik admin
  • Monitoring migration: Grafana/Prometheus/Uptime at *.infra.realemail.app are in scope for Authentik before cutover sign-off (not admin-password-only)
  • Plex: inventory/docs must note intentionally unauthenticated at reverse proxy (perimeter + Plex’s own auth only)
  • Reddit Explorer: no Authentik for the initial single-user deployment. Keep reddit-explorer.infra.realemail.app LAN/Tailscale-only through infra-services Traefik, with no host port or public DNS record.
  • Authelia: legacy; do not add new apps behind Authelia (PLAN.md); migrate opportunistically

Exception register

Service Scope Reason Review trigger
Plex (plex.realemail.app) Saltbox route Native client, LAN/TV, and remote playback UX Plex access architecture changes
Reddit Explorer (reddit-explorer.infra.realemail.app) LAN/Tailscale through infra Traefik only Deliberate initial single-user deployment; application management routes are otherwise unauthenticated Any public DNS/exposure, additional users, or 2026-11-22

The Reddit Explorer exception does not permit a host port, public Cloudflare record, or access outside trusted LAN/Tailscale clients. Its service README documents the compensating controls and operator checks.

Implementation

Operational steps: authentik-cross-host-sso.md Owner Authentik admin walkthrough: authentik-infra-admin-setup.md

Changelog

Date Change
2026-06-25 Accepted — owner requirement: universal Authentik except Plex
2026-08-22 Registered temporary trusted-network Reddit Explorer exception