Skip to content

Identity and single sign-on

The homelab uses a small identity stack so a set of trusted users can log in to several apps with one account and TOTP two-factor, instead of a separate password per app.

Pieces

  • lldap - a lightweight directory that holds the user accounts. It is the single source of users. It is reachable only on the LAN.
  • Authelia - the login page, the TOTP MFA step, and the OpenID Connect (OIDC) provider that the apps trust. Served at auth.example.com through the Cloudflare tunnel.
  • redis - Authelia's session cache. Internal only.

What is protected

Authelia is the OIDC provider for Audiobookshelf, Kavita, and Actual. Each app keeps its own password login as a fallback, so a problem with Authelia never locks the app.

What is not

The media servers own their own identity and their apps cannot delegate it:

  • Plex authenticates against plex.tv.
  • Jellyseerr authenticates against Plex/Jellyfin accounts by design.

So there is no single login across the media servers and the supporting apps. Authelia unifies the supporting apps only. Users still have a separate Plex account.

Trust boundaries

  • Only Authelia is exposed to the internet (through the tunnel). lldap and redis are never published.
  • redis runs without a password because it sits on an isolated internal network that only Authelia can reach, and it holds nothing but short-lived sessions.
  • Every OIDC client requires two-factor, so internet-facing logins always need TOTP.

Login visibility

Authelia logs in JSON so the monitoring stack can parse each field. The Identity dashboard has a "Service login attempts by user" panel that reads Authelia's flow log to show which user signed in to which app. It is best-effort, not a complete ledger: a row means a password was submitted for a service, not that the two-factor step finished, and a login that rides a still-valid session (either the app's own session or Authelia's) makes no round-trip to Authelia and so does not appear. Completed-login detail is only available at Authelia's debug log level, which is deliberately not enabled to avoid flooding the logs.

Secrets

No secrets are committed. Authelia and lldap read every secret from files on the server, generated by identity/generate-secrets.sh and escrowed in the password manager. See identity/README.md for setup and per-app configuration.