-
-
Notifications
You must be signed in to change notification settings - Fork 0
Provider Setup
This plugin has been tested to work against various providers, though not all providers provide support for all of this plugins' features.
This page holds the per-provider setup recipes and the general RBAC options. The operator-facing hardening and per-option reference (base-URL, SAML metadata/audience/binding/ request-signing/cert-rotation, provisioning, step-up/MFA, test-connection, config export/import, parental-rating) lives on Hardening & Options Reference; the security-control narratives (id_token requirements, secrets-at-rest, browser binding, in-flight capacity, SSO-only login) live on the Security Model. A one-line pointer is left below wherever a section moved.
❗ Before you proceed, make sure you have another admin account if you are going to link an SSO provider to the only admin account on the server — permissions might get overwritten.
❗ SAML signing algorithm: SAML responses must be signed with RSA or ECDSA using SHA-256 or stronger (SHA-384/SHA-512). Signatures using SHA-1 (rsa-sha1) or a SHA-1 digest are rejected, so if your identity provider still signs with SHA-1, reconfigure it to SHA-256 — otherwise every login through that provider fails with a "SAML response validation failed" error. The server log records the offending signature algorithm to help you diagnose this.
This section is broken into providers that support Role-Based Access Control (RBAC), and those that do not
- ✅ Google OIDC
- ❗ Usernames are numeric
- ❗ Requires disabling validating OpenID endpoints
For any provider that supports RBAC, we can configure it as we see fit:
Enabled: true
EnableAuthorization: true
EnableAllFolders: true
EnabledFolders: []
Roles: ["jellyfin_user"]
AdminRoles: ["jellyfin_admin"]
EnableFolderRoles: false
FolderRoleMapping: []Moved: see Hardening & Options Reference § Parental rating by role.
Moved: see Security Model § OpenID Connect id_token requirements (what your provider must be configured to satisfy, plus the account-adoption and upgrade/migration runbook).
Moved: see Hardening & Options Reference § Provision new users pending approval.
Moved: see Hardening & Options Reference § Step-up / MFA.
Moved: see Security Model § Secrets encrypted at rest (including the downgrade / rollback procedure).
Moved: see Hardening & Options Reference § Canonical base URL.
Moved: see Hardening & Options Reference § Import SAML config from IdP metadata.
Moved: see Hardening & Options Reference § SAML audience validation.
Moved: see Hardening & Options Reference § SAML response binding.
Moved: see Hardening & Options Reference § SAML request signing (including the SP signing-key rollover).
Moved: see Hardening & Options Reference § SAML identity-provider certificate rotation.
Moved: see Hardening & Options Reference § SAML service-provider metadata.
Moved: see Hardening & Options Reference § Test connection.
Moved: see Hardening & Options Reference § Configuration export / import.
Moved: see Security Model § Login browser binding.
Moved: see Security Model § Login browser binding.
Moved: see Hardening & Options Reference § Other OpenID options.
Moved: see Security Model § In-flight login capacity.
Moved: see Security Model § SSO-only login for the operator runbook and security properties; the threat model is in SSO-Only Login Design.
Authelia is simple to configure, and RBAC is straightforward.
Below is the identity_providers section of an Authelia config:
identity_providers:
oidc:
# hmac secret and private key given by env variables
clients:
- client_id: jellyfin
client_name: My media server
# Client secret should be randomly generated
client_secret: <redacted>
token_endpoint_auth_method: client_secret_post
authorization_policy: one_factor
redirect_uris:
- https://jellyfin.example.com/sso/OID/redirect/autheliaidentity_providers:
oidc:
# hmac secret and private key given by env variables
clients:
- id: jellyfin
description: My media server
# Client secret should be randomly generated
secret: <redacted>
authorization_policy: one_factor
redirect_uris:
- https://jellyfin.example.com/sso/OID/redirect/autheliaOn Jellyfin's end, we need to configure an Authelia provider as follows:
In order to test group membership, we need to request Authelia's groups OIDC scope, which we will use to check user roles.
authelia:
OidEndpoint: https://authelia.example.com
OidClientId: jellyfin
OidSecret: <redacted>
RoleClaim: groups
OidScopes: ["groups"]
DisablePushedAuthorization: trueTo begin with, we must set up an OIDC provider + application in authentik. Refer to the official documentation for detailed instruction.
authentik supports RBAC, but is slightly more complicated to configure than Authelia, as we need to configure a custom scope binding to include in the OIDC response.
To do this, we:
-
create a Custom Property Mapping

-
Create a Scope Mapping

-
Assign the following attributes:

# A nice, human readable name name: Group Membership # The name of the scope a client must request to get access to a user's groups Scope Name: groups # A description of what is being requested to show to a user Description: See Which Groups you belong to
-
For the Expression field, use the following code:
return [group.name for group in user.ak_groups.all()]
Now we can add this property mapping to authentik's Jellyfin OAuth provider:
-
Navigate to
Applications/providers
-
Edit / Update your Jellyfin OAuth provider
-
Verify your "Redirect URIs/Origins (RegEx)" follows the format:
https://domain.tld/sso/OID/redirect/Authentik. -
Under "Advanced Protocol Settings", add the Group Membership Scope

On Jellyfin's end, we need to configure an authentik provider as follows:
In order to test group membership, we need to request authentik's OIDC scope groups, which we will use to check user roles.
authentik:
OidEndpoint: https://authentik.example.com/application/o/jellyfin
OidClientId: <same-as-in-authentik>
OidSecret: <redacted>
RoleClaim: groups
OidScopes: ["groups"]If you receive the error Error processing request. from Jellyfin when attempting to login and the Jellyfin logs show Error loading discovery document: Endpoint belongs to different authority try setting Do not validate endpoints in the plugin settings.
Keycloak in general is a little more complicated than other providers. Ensure that you have a realm created and have some usable users.
Create a new Keycloak openid-connect application. Set the root URL to your Jellyfin URL (ie https://myjellyfin.example.com)
Ensure that the following configuration options are set:
- Access Type: Confidential
- Standard Flow Enabled
- Redirect URI: https://myjellyfin.example.com/sso/OID/redirect/PROVIDER_NAME
- Redirect URI (for Android app): org.jellyfin.mobile://login-callback
- Base URL: https://myjellyfin.example.com
Press the "Save" button at the bottom of the page and open the "Credentials" tab. Note down the secret.
For adding groups and RBAC, go to the "mappers" tab, press "Add Builtin", and select either "Groups", "Realm Roles", or "Client Roles", depending on the role system you are planning on using. Once the mapper is added, edit the mapper and ensure that you note down the Token Claim Name as well as enable all four toggles: "Multivalued", "Add to ID token", "Add to access token", and "Add to userinfo" are enabled.
Note that if you are using the template for the "Client Roles" mapper, the default token claim name has ${client_id} in it. When noting down this value, make sure you note down the actual Client ID (which should be written above).
On Jellyfin's side, we need to configure a Keycloak provider as follows:
keycloak:
OidEndpoint: https://keycloak.example.com/realms/<realm>
OidClientId: <same-as-in-keycloak>
OidSecret: <redacted>
RoleClaim: <same-as-token-claim-name>Keycloak with SAML is very similar to OpenID. Again, Keycloak in general is a little more complicated than other providers. Ensure that you have a realm created and have some usable users.
Create a new Keycloak saml application. Set the root URL to your Jellyfin URL (ie https://myjellyfin.example.com)
Ensure that the following configuration options are set:
- Sign Documents on
- Sign Assertions off
- Client Signature Required off
- Redirect URI: https://myjellyfin.example.com/sso/SAML/post/PROVIDER_NAME
- Base URL: https://myjellyfin.example.com
- Master SAML processing URL: https://myjellyfin.example.com/sso/SAML/post/PROVIDER_NAME
These two URLs are the assertion consumer service endpoint Keycloak POSTs the SAML response to. The plugin accepts both the sso/SAML/post/PROVIDER_NAME spelling and the legacy sso/SAML/p/PROVIDER_NAME spelling; use either, consistently. (The challenge route sso/SAML/start/PROVIDER_NAME is only the URL a login starts from — it cannot process assertions.)
Press the "Save" button at the bottom of the page.
For adding groups and RBAC, go to the "mappers" tab, press "Add Builtin", and select either "Groups", "Realm Roles", or "Client Roles", depending on the role system you are planning on using. Once the mapper is added, edit the mapper and ensure that you note down the Token Claim Name as well as enable all four toggles: "Multivalued", "Add to ID token", "Add to access token", and "Add to userinfo" are enabled.
Note that if you are using the template for the "Client Roles" mapper, the default token claim name has ${client_id} in it. When noting down this value, make sure you note down the actual Client ID (which should be written above).
Finally, download the certificate. Open the "Installation" tab, select "Mod Auth Mellon files", and download the zip. Extract the zip file, and open the idp-metadata.xml file. Note down the contents of the X509Certificate value.
keycloak:
SamlEndpoint: https://keycloak.example.com/realms/<realm>/protocol/saml
SamlClientId: <same-as-in-keycloak>
SamlCertificate: <copied-from-xml-file>A simple and easy-to-use OIDC provider that allows users to authenticate with their passkeys to your services.
- Login to you Pocket ID admin account
- Go to
Administration -> OCID Clients - Click
Add OCID Client - Give the client a name e.g.
Jellyfin - Set the
Clent Launch URLto your Jellyfin endpoint - Set the callbak url to
https://jellyfin.example.com/sso/OID/redirect/pocketid. Thepocketidpart must match theName of OpenID Providerin the Jellyfin SSO provider - (optional) Enable PKCE if Jellyfin is an https endpoint
- (optional) Set a logo
- (optional) Set
Allowed User Groups
pocketid:
OidEndpoint: https://pocketid.example.com/.well-known/openid-configuration
OidClientId: <pocket-id-client-id>
OidSecret: <pocket-id-secret>
EnableAuthorization: true # (optional) If you want Jellyfin to read group permissions from pocket id
RoleClaim: groups # (optional) If you want Jellyfin to be able to read group assignments from pocket id
AdminRoles: admin # (optional) The pocket id group which will give a user Jellyfin admin privilges
Roles: users # (optional) The pocket id group which will give a user Jellyfin access
AvatarUrlFormat: @{picture} # (optional) This will pull each users pocket id photo into JellyfinKanidm is a modern and simple identity management platform written in rust.
kanidm system oauth2 create jellyfin "Jellyfin" https://jellyfin.example.com/
# Set this to drop the trailing @idm.example.com in usernames
kanidm system oauth2 prefer-short-username jellyfin
kanidm system oauth2 add-redirect-url jellyfin https://jellyfin.example.com/sso/OID/redirect/kanidm
kanidm system oauth2 add-redirect-url jellyfin https://jellyfin.example.com/sso/OID/r/kanidm
# Optionally setup groups for Jellyfin
kanidm group create jellyfin_admins
kanidm group create jellyfin_users
kanidm system oauth2 update-scope-map jellyfin jellyfin_admins openid profile groups
kanidm system oauth2 update-scope-map jellyfin jellyfin_users openid profile groupsGet the secret used in the Jellyfin config with kanidm system oauth2 show-basic-secret jellyfin.
kanidm:
OidEndpoint: https://idm.example.com/oauth2/openid/jellyfin/
OidClientId: jellyfin
OidSecret: <kanidm-secret>
# (optional) If you want Jellyfin to read group permissions from kanidm
EnableAuthorization: true
OidScopes:
- groups
RoleClaim: groups
AdminRoles:
- jellyfin_admins@idm.example.com
Roles:
- jellyfin_users@idm.example.com
# If in your setup admin accounts aren't members of the users group you need to add the admins group to roles as well
- jellyfin_admins@idm.example.com
# (optional) If you want the name attribute instead of the spn attribute as username
DefaultUsernameClaim: preferred_usernameRepository · Issues · Releases · Security policy — report vulnerabilities privately, never in a public issue. Pages describe what is implemented today; if the wiki disagrees with the code, the code wins.
Getting started
- Installation
- Provider Setup
- Hardening & Options Reference
- Migrating from 9p4
- Troubleshooting
- Rollback
How it works
Security
- Security Model
- Security Conformance (ASVS / RFC 9700)
- Threat Model
- SSO-Only Login — design record
- Single Logout — design record
Standards & process (internal / maintainer)