Add Authentik SSO integration for Jellyfin (#239)

## Summary
- Add Authentik OIDC provider + application for Jellyfin via blueprint (all authenticated users allowed, no policy binding)
- Wire `jellyfin-client-secret` through ExternalSecret and Authentik worker deployment
- Install [jellyfin-plugin-sso](https://github.com/9p4/jellyfin-plugin-sso) v4.0.0.3 via Ansible, with OIDC config template
- Authentik `admins` group maps to Jellyfin administrator role
- Local login left enabled; SSO is additive

## Deployment and Testing
- [ ] Sync ArgoCD `authentik` app on branch — verify provider + application appear in Authentik admin
- [ ] `mise run provision-indri -- --tags jellyfin --check --diff` (dry run)
- [ ] `mise run provision-indri -- --tags jellyfin` (deploy plugin + config)
- [ ] Test SSO flow: `https://jellyfin.ops.eblu.me/sso/OID/start/authentik`
- [ ] Verify `eblume` account auto-links via `preferred_username` match
- [ ] Verify admins group → Jellyfin admin
- [ ] Reset ArgoCD app revision to main after merge

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/239
This commit is contained in:
Erich Blume 2026-02-21 20:05:44 -08:00
commit 07fb48626d
8 changed files with 142 additions and 0 deletions

View file

@ -21,3 +21,10 @@ jellyfin_webdir: "{{ jellyfin_cask_app_path }}/Contents/Resources/jellyfin-web"
# Log directory
jellyfin_log_dir: "{{ ansible_env.HOME }}/Library/Logs"
# SSO plugin configuration
jellyfin_sso_plugin_version: "4.0.0.3"
jellyfin_sso_client_id: jellyfin
jellyfin_sso_client_secret: ""
jellyfin_sso_provider_name: authentik
jellyfin_plugins_dir: "{{ jellyfin_data_dir }}/plugins"

View file

@ -28,3 +28,36 @@
when: jellyfin_launchctl_check.rc != 0
changed_when: true
failed_when: false
# SSO plugin installation
- name: Ensure SSO-Auth plugin directory exists
ansible.builtin.file:
path: "{{ jellyfin_plugins_dir }}/SSO-Auth_{{ jellyfin_sso_plugin_version }}"
state: directory
mode: '0755'
- name: Download SSO-Auth plugin archive
ansible.builtin.get_url:
url: "https://github.com/9p4/jellyfin-plugin-sso/releases/download/v{{ jellyfin_sso_plugin_version }}/sso-authentication_{{ jellyfin_sso_plugin_version }}.zip"
dest: "/tmp/sso-authentication_{{ jellyfin_sso_plugin_version }}.zip"
mode: '0644'
- name: Extract SSO-Auth plugin
ansible.builtin.unarchive:
src: "/tmp/sso-authentication_{{ jellyfin_sso_plugin_version }}.zip"
dest: "{{ jellyfin_plugins_dir }}/SSO-Auth_{{ jellyfin_sso_plugin_version }}"
remote_src: true
notify: Reload jellyfin
- name: Ensure plugin configurations directory exists
ansible.builtin.file:
path: "{{ jellyfin_plugins_dir }}/configurations"
state: directory
mode: '0755'
- name: Deploy SSO-Auth plugin configuration
ansible.builtin.template:
src: sso-auth.xml.j2
dest: "{{ jellyfin_plugins_dir }}/configurations/SSO-Auth.xml"
mode: '0644'
notify: Reload jellyfin

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- {{ ansible_managed }} -->
<PluginConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SamlConfigs />
<OidConfigs>
<item>
<key><string>{{ jellyfin_sso_provider_name }}</string></key>
<value>
<PluginConfiguration>
<OidEndpoint>https://authentik.ops.eblu.me/application/o/jellyfin</OidEndpoint>
<OidClientId>{{ jellyfin_sso_client_id }}</OidClientId>
<OidSecret>{{ jellyfin_sso_client_secret }}</OidSecret>
<Enabled>true</Enabled>
<EnableAuthorization>true</EnableAuthorization>
<EnableAllFolders>true</EnableAllFolders>
<EnabledFolders />
<AdminRoles><string>admins</string></AdminRoles>
<Roles />
<EnableFolderRoles>false</EnableFolderRoles>
<FolderRoleMappings />
<RoleClaim>groups</RoleClaim>
<OidScopes>
<string>openid</string>
<string>email</string>
<string>profile</string>
</OidScopes>
<SchemeOverride>https</SchemeOverride>
<CanonicalLinks />
</PluginConfiguration>
</value>
</item>
</OidConfigs>
</PluginConfiguration>