Skip to content

Repository files navigation

Jellyfin Plugin: Authentik SSO

Single sign-on authentication for Jellyfin using Authentik as the OpenID Connect identity provider.

Features

  • OIDC authentication via Authentik with PKCE (Proof Key for Code Exchange)
  • Automatic user provisioning — creates Jellyfin users on first SSO login
  • Group-based permissions — map Authentik groups to Jellyfin admin/user roles
  • Admin permission sync — admin group members get full server management rights
  • Content rating restrictions — map optional Authentik groups to Jellyfin parental rating thresholds
  • Profile image sync — automatically sync user avatars from Authentik to Jellyfin
  • Access control — restrict Jellyfin access to specific Authentik groups
  • Reverse proxy support — force HTTPS redirect URIs for TLS-terminating proxies
  • Themed callback page — dark-by-default login interstitial that respects prefers-color-scheme and Jellyfin's Custom CSS
  • Minimal configuration — only 3 required settings (URL, Client ID, Client Secret)

Setup

Authentik Side

  1. Create an OAuth2/OpenID Provider in Authentik
    • Authorization flow: Use your standard authorization flow
    • Client type: Confidential
    • Redirect URI: https://your-jellyfin-url/authentik/callback
    • Scopes: openid, profile, email (ensure groups scope is included — it is by default)
  2. Create an Application linked to the provider
  3. Assign users/groups to the application

Profile Image Sync (Optional)

To sync user avatars from Authentik to Jellyfin, you need to expose the avatar URL in the userinfo response:

  1. Go to Customization → Property Mappings → Create → Scope Mapping
  2. Configure the mapping:
    • Name: Jellyfin Avatar
    • Scope name: profile
    • Expression:
      return {
          "picture": request.user.avatar
      }
  3. Go to Applications → Providers → Your Jellyfin Provider → Advanced protocol settings
  4. Under Scopes, ensure the profile scope is selected (it should include your new mapping)

Note: If you store the avatar in a custom user attribute instead (e.g., attributes.photo), adjust the expression to request.user.attributes.get("photo", "") and update the Profile Image Claim Path in the Jellyfin plugin config to match (e.g., photo).

Jellyfin Side

Installation via Plugin Repository (Recommended)

  1. Go to Dashboard → Plugins → Repositories
  2. Click + to add a new repository
  3. Enter the repository URL:
    https://scottfridwin.github.io/jellyfin-plugin-authentik/manifest.json
    
  4. Go to Dashboard → Plugins → Catalog
  5. Search for Authentik SSO and click Install
  6. Restart Jellyfin

Dev/testing builds: To test pre-release builds, use this repository URL instead:

https://scottfridwin.github.io/jellyfin-plugin-authentik/dev/manifest.json

Dev builds are updated on every push to the dev branch and may be unstable. Use only for testing.

Manual Installation

  1. Download the latest release from GitHub Releases
  2. Extract the zip file into your Jellyfin plugins directory:
    <jellyfin-data>/plugins/Jellyfin.Plugin.Authentik/
    
  3. Restart Jellyfin

Configuration

After installation, go to Dashboard → Plugins → Authentik SSO and configure:

Setting Description Default
Authentik URL Your Authentik base URL (e.g., https://auth.example.com) (required)
Client ID From the Authentik OAuth2 provider (required)
Client Secret From the Authentik OAuth2 provider (required)
Admin Group Authentik group name for Jellyfin admins jellyfin-admins
Required Group Authentik group required to log in (leave blank to allow all Authentik users) jellyfin-users
Auto-Create Users Create Jellyfin accounts on first SSO login true
Enable Group Sync Sync Authentik groups → Jellyfin permissions on each login true
Enable Content Policy Sync Sync Authentik groups → Jellyfin parental rating restrictions on each login false
G / TV-G / TV-Y Group Optional Authentik group that restricts users to G, TV-G, and TV-Y content (empty)
TV-Y7 Group Optional Authentik group that restricts users to TV-Y7 and below (empty)
PG / TV-PG Group Optional Authentik group that restricts users to PG, TV-PG, and below (empty)
PG-13 Group Optional Authentik group that restricts users to PG-13 and below (empty)
TV-14 Group Optional Authentik group that restricts users to TV-14 and below (empty)
Sync Profile Image Sync the user's profile image from Authentik on each login true
Profile Image Claim Path Dot-notation path to the image URL in the userinfo response picture
Force HTTPS Redirect Force https:// in the OAuth callback URI (enable if behind a TLS-terminating reverse proxy) false

Content Rating Restrictions

When Enable Content Policy Sync is on, the plugin checks the configured restriction groups and applies Jellyfin's normalized parental rating thresholds.

  • Users in the Admin Group always remain unrestricted.
  • Users in the Required Group but in none of the configured restriction groups remain unrestricted.
  • If a user matches multiple restriction groups, the plugin applies the least restrictive matching threshold.
  • Users in a restriction group also have unrated content blocked.

This uses Jellyfin's built-in rating normalization, so movie and TV ratings align to the same parental score where possible. For example, PG and TV-PG map to the same threshold, while PG-13 and TV-14 remain separate thresholds.

Safety behavior: if Enable Content Policy Sync is enabled, Enable Group Sync is disabled, and a restricted user cannot be loaded with an existing Jellyfin policy during login, access is denied for that login rather than risk unintentionally broad access.

Example Authentik groups:

  • jellyfin-users
  • jellyfin-admins
  • jellyfin-rating-g
  • jellyfin-rating-y7
  • jellyfin-rating-pg
  • jellyfin-rating-pg13
  • jellyfin-rating-tv14

Example results:

  • jellyfin-users only: unrestricted standard user
  • jellyfin-users + jellyfin-rating-g: restricted to G, TV-G, and TV-Y content
  • jellyfin-users + jellyfin-rating-pg: restricted to PG, TV-PG, and below
  • jellyfin-users + jellyfin-rating-pg + jellyfin-rating-tv14: restricted to TV-14 and below
  • jellyfin-users + jellyfin-admins + any restriction group: unrestricted admin user

Usage

Navigate to https://your-jellyfin-url/authentik/login to initiate SSO login.

Login Button (Optional)

To add a "Sign in with Authentik" button on the login page, use two Jellyfin settings:

1. Login Disclaimer (Dashboard → General → Login Disclaimer)

Paste this HTML:

<form action="/authentik/login" class="sso-login-form">
  <button type="submit" class="sso-login-btn">
    Sign in with Authentik
  </button>
</form>

2. Custom CSS (Dashboard → General → Custom CSS Code)

Paste this CSS (customize as needed):

/* SSO Login Button */
.sso-login-form {
  margin-top: 1.5em;
  text-align: center;
}

.sso-login-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  padding: 0.75em 1.5em;
  width: 100%;
  max-width: 300px;
  background: #4051b5;
  color: #fff;
  border: none;
  border-radius: 4px;
  font-size: 1em;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.2s;
}

.sso-login-btn:hover {
  background: #3444a3;
}

/* Optional: add a logo/icon before the text */
/* .sso-login-btn::before {
  content: '';
  display: inline-block;
  width: 20px;
  height: 20px;
  background: url('https://your-domain.com/logo.svg') no-repeat center/contain;
} */

Customization Examples

Add a logo image inside the button — modify the Login Disclaimer HTML:

<form action="/authentik/login" class="sso-login-form">
  <button type="submit" class="sso-login-btn">
    <img src="https://your-domain.com/logo.svg" alt="" class="sso-login-logo">
    Sign in with Authentik
  </button>
</form>

Then add to Custom CSS:

.sso-login-logo {
  width: 20px;
  height: 20px;
  object-fit: contain;
}

Match your Authentik branding colors:

.sso-login-btn {
  background: #fd4b2d; /* Authentik orange */
}
.sso-login-btn:hover {
  background: #e0432a;
}

Full-width button with rounded corners:

.sso-login-btn {
  max-width: 100%;
  border-radius: 2em;
  padding: 1em;
}

Callback Page Styling

The intermediate "Completing login..." page uses a dark theme by default and respects prefers-color-scheme. It also loads Jellyfin's Custom CSS, so you can override its appearance:

/* Override the SSO callback page */
.sso-container { background: #1a1a2e; }
.sso-spinner { border-top-color: #e94560; }

How It Works

  1. User clicks "Sign in with Authentik" (or navigates to /authentik/login)
  2. Plugin generates a PKCE code verifier/challenge and redirects to Authentik
  3. User authenticates in Authentik
  4. Authentik redirects back to /authentik/callback with an authorization code
  5. Plugin exchanges the code for tokens, fetches user info from Authentik
  6. Plugin checks group membership for authorization
  7. Plugin creates/updates the Jellyfin user and syncs permissions
  8. A callback page completes the login client-side, storing the session in the browser
  9. User is redirected to the Jellyfin home page

Permission Sync

When Enable Group Sync is on, every login updates the user's Jellyfin permissions:

Authentik Group Jellyfin Permissions
Admin Group member Full admin: manage server, delete content, remote control, live TV management
Allowed Group member (non-admin) Standard user: playback, transcoding, remote access, all libraries

When Enable Content Policy Sync is on, every login also updates the user's Jellyfin MaxParentalRating based on the configured restriction groups.

Development

Prerequisites

  • .NET 9.0 SDK

Build

dotnet build

Test

dotnet test

Dev Container

Open in VS Code with the Dev Containers extension for a pre-configured development environment.

License

GPL-3.0 — see LICENSE for details.

About

Authentik SSO plugin for Jellyfin

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages