jellyfin-librarian¶
jellyfin-librarian is an internal webhook handler that automatically syncs Jellyfin user state from Authentik on every login.
Jellyfin has no concept of a default user profile — every new user starts with access to all libraries and no playback restrictions. Without automation, each new user would require manual configuration in the Jellyfin admin UI. jellyfin-librarian solves this by hooking into the login event and enforcing the correct policy automatically.
It also syncs the user's email from Authentik into Jellyseerr (if the user doesn't already have one set), and enables all email notification types so users get notified about their media requests.
How It Works¶
graph LR
User -->|1. logs in| Jellyfin
Jellyfin -->|2. AuthenticationSuccess webhook| Librarian[jellyfin-librarian]
Librarian -->|3. GET /core/users/| Authentik
Authentik -->|4. jellyfin_libraries + email| Librarian
Librarian -->|5. POST /Users/id/Policy| Jellyfin
Librarian -->|6. GET /user?q=username| Jellyseerr
Librarian -->|7. POST /user/id/settings| Jellyseerr
On every successful login:
- Jellyfin fires an
AuthenticationSuccesswebhook tojellyfin-librarian - Librarian looks up the user in Authentik and reads
jellyfin_librariesattribute andemail - Maps the attribute value to Jellyfin folder IDs via
LIBRARY_MAPPING - Compares against the user's current Jellyfin policy — if different, POSTs the updated policy
- Looks up the user in Jellyseerr — if they have no email set, syncs the Authentik email and enables all email notification types
Idempotent
If the policy already matches, no update is made. The handler fires on every login safely.
Deployment¶
-
Namespace
bots -
Source
gitea.hdhomelab.com/cicd/jellyfin-librarian -
Config
flux/apps/noah/bots/jellyfin-librarian/ -
Port
8080(cluster-internal only)
Library Attribute Values¶
The jellyfin_libraries attribute on the Authentik user record controls which libraries are enabled:
jellyfin_libraries |
Libraries |
|---|---|
cn |
Chinese libraries only |
en |
English libraries only |
all |
All libraries |
| (not set) | Defaults to en |
The attribute is set automatically during user registration via the Authentik enrollment flow. For existing users, set it manually:
Policy Applied on Login¶
In addition to library folder access, jellyfin-librarian enforces these policy settings for all managed users:
| Setting | Value | Reason |
|---|---|---|
EnableAllFolders |
false |
Restrict to EnabledFolders only |
EnabledFolders |
Per jellyfin_libraries attribute |
Library access control |
EnableVideoPlaybackTranscoding |
false |
Direct play only |
EnableAudioPlaybackTranscoding |
false |
Direct play only |
EnablePlaybackRemuxing |
false |
Direct play only |
Full policy update
Jellyfin requires the complete policy object on POST /Users/{id}/Policy. jellyfin-librarian reads the existing policy and merges in only the fields it manages, leaving all other settings untouched.
Jellyseerr Email Sync¶
After syncing library permissions, jellyfin-librarian checks if the user exists in Jellyseerr and whether they have a real email set (Jellyseerr defaults the email field to the username for Jellyfin users).
If no real email is set:
- Pulls the email from the user's Authentik account
- Sets it in Jellyseerr via the user settings API
- Enables all user-facing email notification types: Request Approved, Request Declined, Request Available
Best-effort
Jellyseerr sync failures are logged but do not block the library policy sync. If Jellyseerr is down, the user's library permissions still get updated.
Configuration¶
Environment Variables¶
| Env Var | Source | Value |
|---|---|---|
JELLYFIN_URL |
ConfigMap | http://jellyfin.media.svc:8096 |
JELLYFIN_API_KEY |
Vault secret | Jellyfin API key |
AUTHENTIK_URL |
ConfigMap | http://authentik-server.infra.svc |
AUTHENTIK_TOKEN |
Vault secret | Authentik API token (read-only) |
LIBRARY_MAPPING |
ConfigMap | JSON map of attribute value → folder IDs |
JELLYSEERR_URL |
ConfigMap | Jellyseerr base URL |
JELLYSEERR_API_KEY |
Vault secret | Jellyseerr API key |
LIBRARY_MAPPING is defined in the ConfigMap in deployment.yaml. Folder IDs are static — look them up once via GET /Library/VirtualFolders and update the ConfigMap.
Vault Secrets¶
Create at path jellyfin-librarian in Vault:
| Key | Description |
|---|---|
jellyfin-api-key |
Jellyfin API key — Dashboard → API Keys |
authentik-token |
Authentik API token — Admin → Directory → Tokens, intent: API Token |
jellyseerr-api-key |
Jellyseerr API key — Settings → General |
Jellyfin Webhook Plugin¶
The Webhook plugin must be installed from the Jellyfin plugin catalog and configured to point at jellyfin-librarian.
| Setting | Value |
|---|---|
| Destination URL | http://jellyfin-librarian.bots.svc:8080/webhook |
| Event type | Authentication Success |
| Content-Type header | application/json |
{
"NotificationType": "{{NotificationType}}",
"NotificationUsername": "{{NotificationUsername}}",
"UserId": "{{UserId}}"
}
Body template required
The plugin sends an empty body by default. The request body template and Content-Type: application/json header must both be set or the handler will fail to parse the payload.