docs(jellyfin): document the authentik LDAP integration
Records the LDAP-Auth plugin wiring: the Jellyfin LDAP provider + outpost on Dankclaw, the svc-jellyfin-ldap service account, the jellyfin_users/jellyfin_admins access groups, and the key gotcha that the bind credential is a PASSWORD (set via Recovery), not an API/app token — the default auth flow's standard-password backend rejects tokens with 'flow error password: Invalid'. Verified end-to-end: alex (in jellyfin_users) logs in with their authentik password and the plugin creates the matching Jellyfin user.
This commit is contained in:
@@ -55,6 +55,47 @@ Client access paths and the public-exposure policy (auth wall required before
|
||||
any public vhost; Plex-style claim tokens do not exist here — Jellyfin uses its
|
||||
own users/API keys) follow the fleet [[Authentik]]/[[Anubis]] chain pattern.
|
||||
|
||||
## Authentik LDAP authentication (2026-09-25)
|
||||
|
||||
Jellyfin has no native external-auth, so it authenticates users through the
|
||||
**LDAP-Auth plugin** (`jellyfin-plugin-ldapauth`) against an [[Authentik]] LDAP
|
||||
provider. A user logs in with their **authentik username + password**; the
|
||||
plugin binds as a service account, searches the directory, and rebinds as the
|
||||
user to verify the password.
|
||||
|
||||
**authentik side** (on Dankclaw):
|
||||
- LDAP provider `Jellyfin LDAP` (Base DN `dc=franksdank,dc=cloud`, bind/search
|
||||
mode `direct`) + application `Jellyfin`.
|
||||
- LDAP outpost `Jellyfin LDAP Outpost` → container `authentik-outpost-ldap`
|
||||
(quadlet `dankclaw/authentik/quadlet/authentik-outpost-ldap.container`),
|
||||
publishing `389`/`636` on the Dankclaw host for cross-host binds.
|
||||
- Service account `svc-jellyfin-ldap` (DN
|
||||
`cn=svc-jellyfin-ldap,ou=users,dc=franksdank,dc=cloud`).
|
||||
- Access groups `jellyfin_users` (search filter
|
||||
`(memberOf=cn=jellyfin_users,ou=groups,dc=franksdank,dc=cloud)`) and
|
||||
`jellyfin_admins` (admin filter `(cn=jellyfin_admins)`). Add a user to
|
||||
`jellyfin_users` to grant them Jellyfin access; `jellyfin_admins` grants
|
||||
the Jellyfin admin role.
|
||||
|
||||
**Jellyfin side** (plugin config, set via admin → Plugins → LDAP-Auth):
|
||||
- Server `192.168.0.143:389` (plain LDAP over the trusted LAN), Base DN
|
||||
`dc=franksdank,dc=cloud`, bind user = the service-account DN, search
|
||||
attributes `uid,cn,mail,displayName`, uid attr `uid`, username attr `cn`,
|
||||
`CreateUsersFromLdap=true`, all folders enabled.
|
||||
|
||||
**Gotcha — the bind credential is a PASSWORD, not a token.** The LDAP bind is
|
||||
verified by authentik's default authentication flow (standard-password
|
||||
backend). The service account must have a password set (admin → user →
|
||||
Recovery → Set password); an API/app token is *not* accepted as the bind
|
||||
password and the bind fails with `flow error password: Invalid`. The
|
||||
service-account password is stored only in the Jellyfin plugin config (the
|
||||
`LdapBindPassword` field) — it is never committed to this repo.
|
||||
|
||||
**Verification (2026-09-25):** `ldapsearch` bind + the `jellyfin_users`
|
||||
search both succeed from Dankclaw; a real user (`alex`, in `jellyfin_users`)
|
||||
logged into the web UI with their authentik password and the plugin created
|
||||
the matching Jellyfin user.
|
||||
|
||||
## Configuration workflow
|
||||
|
||||
1. Create libraries pointing at `/data` folders (movies, shows, audio).
|
||||
|
||||
Reference in New Issue
Block a user