Add Authentik SSO integration for Jellyfin #239
8 changed files with 142 additions and 0 deletions
Add Authentik SSO integration for Jellyfin
Wire up OIDC authentication via jellyfin-plugin-sso so all Authentik users can access Jellyfin, with admins group mapped to Jellyfin admin. - Authentik blueprint: OAuth2 provider + application (no policy binding) - ExternalSecret + worker env var for client secret - Ansible: fetch client secret, install SSO-Auth plugin, deploy config - Local login left enabled (no branding override) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
commit
625af2a1ec
|
|
@ -161,6 +161,23 @@
|
|||
no_log: true
|
||||
tags: [caddy]
|
||||
|
||||
# Jellyfin SSO client secret
|
||||
- name: Fetch Jellyfin OIDC client secret
|
||||
ansible.builtin.command:
|
||||
cmd: op read "op://vg6xf6vvfmoh5hqjjhlhbeoaie/oor7os5kapczgpbwv7obkca4y4/jellyfin-client-secret"
|
||||
delegate_to: localhost
|
||||
register: _jellyfin_oidc_secret
|
||||
changed_when: false
|
||||
no_log: true
|
||||
check_mode: false
|
||||
tags: [jellyfin]
|
||||
|
||||
- name: Set Jellyfin OIDC client secret fact
|
||||
ansible.builtin.set_fact:
|
||||
jellyfin_sso_client_secret: "{{ _jellyfin_oidc_secret.stdout }}"
|
||||
no_log: true
|
||||
tags: [jellyfin]
|
||||
|
||||
# Jellyfin API key for metrics collection
|
||||
- name: Fetch Jellyfin API key
|
||||
ansible.builtin.command:
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
33
ansible/roles/jellyfin/templates/sso-auth.xml.j2
Normal file
33
ansible/roles/jellyfin/templates/sso-auth.xml.j2
Normal 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>
|
||||
|
|
@ -245,3 +245,45 @@ data:
|
|||
enabled: true
|
||||
negate: false
|
||||
timeout: 30
|
||||
|
||||
jellyfin.yaml: |
|
||||
version: 1
|
||||
metadata:
|
||||
name: BlumeOps Jellyfin SSO
|
||||
labels:
|
||||
blueprints.goauthentik.io/description: "Jellyfin OIDC provider and application"
|
||||
entries:
|
||||
# OAuth2 provider for Jellyfin
|
||||
- model: authentik_providers_oauth2.oauth2provider
|
||||
id: jellyfin-provider
|
||||
identifiers:
|
||||
name: Jellyfin
|
||||
attrs:
|
||||
name: Jellyfin
|
||||
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
||||
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
||||
client_type: confidential
|
||||
client_id: jellyfin
|
||||
client_secret: !Env AUTHENTIK_JELLYFIN_CLIENT_SECRET
|
||||
redirect_uris:
|
||||
- matching_mode: strict
|
||||
url: https://jellyfin.ops.eblu.me/sso/OID/redirect/authentik
|
||||
signing_key: !Find [authentik_crypto.certificatekeypair, [name, authentik Self-signed Certificate]]
|
||||
property_mappings:
|
||||
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]]
|
||||
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, email]]
|
||||
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]]
|
||||
sub_mode: hashed_user_id
|
||||
include_claims_in_id_token: true
|
||||
|
||||
# Jellyfin application — all authenticated users allowed (no policy binding)
|
||||
- model: authentik_core.application
|
||||
id: jellyfin-app
|
||||
identifiers:
|
||||
slug: jellyfin
|
||||
attrs:
|
||||
name: Jellyfin
|
||||
slug: jellyfin
|
||||
provider: !KeyOf jellyfin-provider
|
||||
meta_launch_url: https://jellyfin.ops.eblu.me
|
||||
policy_engine_mode: all
|
||||
|
|
|
|||
|
|
@ -68,6 +68,11 @@ spec:
|
|||
secretKeyRef:
|
||||
name: authentik-config
|
||||
key: zot-client-secret
|
||||
- name: AUTHENTIK_JELLYFIN_CLIENT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: authentik-config
|
||||
key: jellyfin-client-secret
|
||||
volumeMounts:
|
||||
- name: blueprints
|
||||
mountPath: /blueprints/custom
|
||||
|
|
|
|||
|
|
@ -49,3 +49,7 @@ spec:
|
|||
remoteRef:
|
||||
key: "Authentik (blumeops)"
|
||||
property: zot-client-secret
|
||||
- secretKey: jellyfin-client-secret
|
||||
remoteRef:
|
||||
key: "Authentik (blumeops)"
|
||||
property: jellyfin-client-secret
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
Add Authentik SSO to Jellyfin with admin group mapping
|
||||
Loading…
Add table
Add a link
Reference in a new issue
please check this is the most recent version