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.comthrough 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.