-
-
Notifications
You must be signed in to change notification settings - Fork 0
Migrating from 9p4
Note
This plugin is at the Beta stage of its maturity ladder (see the Roadmap). As with any auth change, do the migration described here first on a test instance with a config backup, then roll it out once you have confirmed sign-in works. The archived upstream receives no security updates anymore, so switching is the right move.
This project continues the archived 9p4/jellyfin-plugin-sso from its last release (4.0.0.4). The short version: it is an in-place upgrade, not a move.
Both versions share the same plugin identity:
- Plugin GUID
505ce9d1-d916-42fa-86ca-673ef241d7df - Plugin name
SSO Authentication - Configuration type
Jellyfin.Plugin.SSO_Auth(same XML file)
Jellyfin therefore treats them as the same plugin. Swapping the binaries keeps the existing
configuration file (<jellyfin data dir>/plugins/configurations/Jellyfin.Plugin.SSO_Auth.xml),
and with it:
- every configured OpenID and SAML provider (endpoints, client ids, certificates),
- secrets (
OidSecret, signing material), - all linked accounts (
CanonicalLinks), - role/folder/Live-TV mappings.
New configuration fields added by this project are additive with safe defaults (false), so a
config written by 4.0.0.4 loads unchanged. Nothing has to be re-entered.
- Back up the config file named above (a plain file copy is enough).
- Stop Jellyfin.
- Install this plugin over the old one. The recommended path is the plugin catalog: add the
stable repository URL under Dashboard → Plugins → Repositories and update
SSO Authentication from the catalog — the GUID is unchanged, so it upgrades in place. See
Installation. Building from source and dropping the binaries into
<jellyfin data dir>/plugins/SSO-Auth*/also works. - Start Jellyfin and test a login for each configured provider.
This project hardens the login path fail-closed. A provider that "worked" on 4.0.0.4 because nothing was checked can now be rejected — that is the hardening doing its job, and the fix is on the identity-provider side. If a login stops working, check these in order:
OpenID Connect
- The id_token is now fully validated (signature against the discovery JWKS, issuer, audience, expiry). It must be signed with an asymmetric algorithm — RS256/384/512, PS256/384/512 or ES256/384/512. Tokens signed with HS256 or unsigned tokens are rejected; switch the IdP client's id_token signing algorithm to RS256. EdDSA is not supported.
- A
subclaim is required and must be stable. Account links are now keyed onsubinstead of the username. Existing username-keyed links migrate tosub, but because the username is IdP-mutable that migration is gated behindAllowExistingAccountLink— so enable that flag for the provider before your users log in again (a short supervised window), or link accounts with the admin endpoint. With the flag off, an OpenID login whose name still matches its account is refused until you migrate it. Keep a non-SSO admin with a password login so you cannot lock yourself out. Full runbook, break-glass, and the takeover-window caveat: the Security Model page and Provider Setup. A user renamed at the IdP before the switch cannot be matched to their old link and gets a fresh account (the same outcome a rename already had on 4.0.0.4). -
Account links are now bound to the issuer that created them. If you later repoint a
provider's endpoint at a different identity provider, the plugin drops that provider's
accumulated links (the same way it already drops the stored client secret on an endpoint
change) rather than risk a colliding
subsigning a new user into an old account. A straight 9p4 upgrade with the endpoint left unchanged is unaffected; existing links are simply stamped with the current issuer on next login. - Clocks matter: expiry is checked with a 5-minute skew. Keep Jellyfin and the IdP on NTP.
- Details and per-provider notes: Provider Setup.
SAML
- Responses signed with SHA-1 are rejected — reconfigure the IdP to sign with RSA/ECDSA-SHA-256 or stronger.
- A response carrying a DOCTYPE/DTD is rejected outright (XXE defense); well-formed SAML never has one.
- An assertion without a parseable NotOnOrAfter, or failing its AudienceRestriction, is rejected instead of silently accepted. Replayed assertions are rejected (one-time use).
Optional new hardening (off by default)
Nothing else changes unless you opt in. Two new per-provider SAML switches
(ValidateRecipient, ValidateInResponseTo) bind responses to this server and to solicited
logins — see Provider Setup
before enabling them (ValidateInResponseTo deliberately disables IdP-initiated SSO).
Straightforward: stop Jellyfin and put the 9p4 4.0.0.4 binaries back. The GUID is the same and the new config fields are additive, so the old version simply ignores them — the configuration, including account links, stays intact. Two caveats:
- OpenID account links that were already migrated to
subkeying are not consulted by the old username-keyed code; affected users are re-linked by name exactly as they were before the switch. - If a provider's client secret or SAML signing key has been re-saved since upgrading, it is now
stored encrypted (
ssoenc:v1:) — 4.0.0.4 cannot read that format and behaves as if the secret were unset. Re-enter the secret/key on 4.0.0.4 after rolling back, or restore a pre-upgrade plaintext config backup. Details: Security Model § Secrets encrypted at rest.
Check the Jellyfin log first — the plugin logs why a login was rejected (weak algorithm, missing
sub, expired assertion, audience mismatch) with remediation hints, then see
Troubleshooting. If you hit something undocumented, please
open an issue.
Repository · 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)