Skip to content

feat: support OpenID Connect login#1505

Closed
michaelhthomas wants to merge 19 commits intoseerr-team:developfrom
michaelhthomas:feat/oidc-login
Closed

feat: support OpenID Connect login#1505
michaelhthomas wants to merge 19 commits intoseerr-team:developfrom
michaelhthomas:feat/oidc-login

Conversation

@michaelhthomas
Copy link
Copy Markdown
Contributor

@michaelhthomas michaelhthomas commented Mar 20, 2025

Description

Adds long-awaited support for OpenID Connect as a means of logging in to Jellyseerr. This implementation supports adding several third-party OpenID Connect providers to your instance, and allows existing users to link and unlink OpenID Connect accounts from their user accounts. For details on how to configure OpenID Connect, documentation updates are included in this PR.

Screenshot (if UI-related)

image

Checklist

  • Successful build pnpm build
  • Translation keys pnpm i18n:extract
  • Database migration (if required)

Issues Fixed or Closed

@michaelhthomas michaelhthomas force-pushed the feat/oidc-login branch 2 times, most recently from 4394fae to c30ef6e Compare March 21, 2025 14:14
@fallenbagel fallenbagel mentioned this pull request Mar 24, 2025
3 tasks
@gauthier-th gauthier-th mentioned this pull request Feb 28, 2025
@gauthier-th
Copy link
Copy Markdown
Member

PR available for test with the preview-OIDC tag.

@gauthier-th gauthier-th added the preview PRs deployed for testing with tag `:preview-prxx` label Mar 24, 2025
@cordlord
Copy link
Copy Markdown

cordlord commented Mar 25, 2025

It would be an improvement to have the ability to set the id field to something other than email. Jellyfin, which I am also using with OIDC and is the current account provider, does not have an email field, so I use usernames for user ids.

I would like for users to be able to have their existing accounts link automatically rather than them needing to go add them or me have to update all their emails.

Otherwise, this works great! No issues getting Authentik setup and working. Sign in works perfect once the accounts are linked!
All of your work on this is greatly appreciated!

Edit: I did have to run the CREATE TABLE query from here #183 (comment) for the current preview version.

@Zegorax
Copy link
Copy Markdown

Zegorax commented Mar 25, 2025

Since the migration to the new preview-OIDC Docker tag this night, I had to re-add the OIDC provider. After that, it seems that the migrations might not be running correctly or included. When performing an OIDC login, it fails and the following error message can be found :

Failed OIDC login attempt {"cause":"Unknown error","ip":"18.192.118.164","errorMessage":"SQLITE_ERROR: no such table: linked_accounts"}

I've looked in /app/dist/migration/sqlite, and it seems that the migration file 1742858617989-AddLinkedAccount.ts is not there.

@fallenbagel
Copy link
Copy Markdown
Collaborator

Since the migration to the new preview-OIDC Docker tag this night, I had to re-add the OIDC provider. After that, it seems that the migrations might not be running correctly or included. When performing an OIDC login, it fails and the following error message can be found :

Failed OIDC login attempt {"cause":"Unknown error","ip":"18.192.118.164","errorMessage":"SQLITE_ERROR: no such table: linked_accounts"}

I've looked in /app/dist/migration/sqlite, and it seems that the migration file 1742858617989-AddLinkedAccount.ts is not there.

We did not update the preview tag yet

@Zegorax
Copy link
Copy Markdown

Zegorax commented Mar 25, 2025

Since the migration to the new preview-OIDC Docker tag this night, I had to re-add the OIDC provider. After that, it seems that the migrations might not be running correctly or included. When performing an OIDC login, it fails and the following error message can be found :
Failed OIDC login attempt {"cause":"Unknown error","ip":"18.192.118.164","errorMessage":"SQLITE_ERROR: no such table: linked_accounts"}
I've looked in /app/dist/migration/sqlite, and it seems that the migration file 1742858617989-AddLinkedAccount.ts is not there.

We did not update the preview tag yet

I'm not sure what happened, but the tag on Docker hub was updated 12 hours ago, and this comment : #184 (comment) says the tag has been updated to this PR

@fallenbagel
Copy link
Copy Markdown
Collaborator

Since the migration to the new preview-OIDC Docker tag this night, I had to re-add the OIDC provider. After that, it seems that the migrations might not be running correctly or included. When performing an OIDC login, it fails and the following error message can be found :
Failed OIDC login attempt {"cause":"Unknown error","ip":"18.192.118.164","errorMessage":"SQLITE_ERROR: no such table: linked_accounts"}
I've looked in /app/dist/migration/sqlite, and it seems that the migration file 1742858617989-AddLinkedAccount.ts is not there.

We did not update the preview tag yet

I'm not sure what happened, but the tag on Docker hub was updated 12 hours ago, and this comment : #184 (comment) says the tag has been updated to this PR

I was wrong. I thought we didn't but apparently @gauthier-th did

@DuvelCorp
Copy link
Copy Markdown

DuvelCorp commented Mar 25, 2025

Lets us know when you fix the CREATE TABLE linked_accounts issue. Once done I will test the preview on my real database (I understand it should work with it) and several users having an Authentik account

@fallenbagel
Copy link
Copy Markdown
Collaborator

Lets us know when you fix the CREATE TABLE linked_accounts issue. Once done I will test the preview on my real database (I understand it should work with it) and several users having an Authentik account

#183 (comment)
You could try that too ^

@DuvelCorp
Copy link
Copy Markdown

Lets us know when you fix the CREATE TABLE linked_accounts issue. Once done I will test the preview on my real database (I understand it should work with it) and several users having an Authentik account

#183 (comment) You could try that too ^

Yes but no :-D
We know the manual CREATE works anyway.
I am gonna wait the definitive automatic creation as its the most meaningful to test (and coz I am a bit lazy also...)

@fallenbagel
Copy link
Copy Markdown
Collaborator

Lets us know when you fix the CREATE TABLE linked_accounts issue. Once done I will test the preview on my real database (I understand it should work with it) and several users having an Authentik account

#183 (comment) You could try that too ^

Yes but no :-D
We know the manual CREATE works anyway.
I am gonna wait the definitive automatic creation as its the most meaningful to test (and coz I am a bit lazy also...)

I was wrong again. @gauthier-th did not update the Image after migrations was added. So i was right the first time. We didn't update image yet. Database migrations has been added.

@gauthier-th
Copy link
Copy Markdown
Member

@Zegorax I just updated the preview tag: preview-OIDC (it's building, done in 30min), it didn't include the last commit with the migrations, my bad.

@DuvelCorp
Copy link
Copy Markdown

DuvelCorp commented Mar 26, 2025

Just tested the last preview image
Stopped my :latest Jellyseer container.
Backuped my config (including db) directory
Changed the tag to :preview-OIDC and restarted the stack.

Jellyseer starts fine and the db migration seems to work

Configured everything in Authentik
Configured everything in Jellyseer

At first tries I had this message message from Authentik after pushing the new button on jellyseer login screen
image

Because I had tried this as redirect uri :
https://jellyseer.domain.com/login/oidc/callback
https://jellyseer.domain.com/login/oidc/callback/slug-in-jellyseer

and nothing worked.

Then I found this #183 (comment)

I thus made another try without specifying a redirect URI in Authentik, and there it worked with my test user in an incognito window. The test user was not existing in Jellyseer and it created it, and logged me in

I then made another test with my own admin user, and I got this :
image

Those are the logs (nothing more)

2025-03-26T07:19:39.198Z [info]: Creating user for tom@xxxxxxx.tld {"ip":"::ffff:192.168.2.10","email":"tom@xxxxxxx.tld"}

2025-03-26T07:19:39.210Z [error]: Failed OIDC login attempt {"cause":"Unknown error","ip":"::ffff:192.168.2.10","errorMessage":"SQLITE_CONSTRAINT: UNIQUE constraint failed: user.email"}

So the issue is that it tries to create my user. It fails because it already exists, with that email address
image

The question is, why does it fails (or doesn't do) the lookup for my user email, before deciding to create the user??

Additional question : I am having hard to figure out how this will work with my existing user base. All of them are imported from Jellyfin, and thus none of them have an email address in Jellyseer. If the auth works only with emails and not username, I dont see how it can there be any match for existing users. If no username login is possible, I suppose that to use Authentik login, all of them will have to first login normally in Jellyseer and edit their profile to add their Authentik email. Its a bit annoying when you have several dozens of users.

@RobertRvB
Copy link
Copy Markdown

Just tested the last preview image Stopped my :latest Jellyseer container. Backuped my config (including db) directory Changed the tag to :preview-OIDC and restarted the stack.

Jellyseer starts fine and the db migration seems to work

Configured everything in Authentik Configured everything in Jellyseer

At first tries I had this message message from Authentik after pushing the new button on jellyseer login screen image

Because I had tried this as redirect uri : https://jellyseer.domain.com/login/oidc/callback https://jellyseer.domain.com/login/oidc/callback/slug-in-jellyseer

and nothing worked.

Then I found this #183 (comment)

I thus made another try without specifying a redirect URI in Authentik, and there it worked with my test user in an incognito window. The test user was not existing in Jellyseer and it created it, and logged me in

I then made another test with my own admin user, and I got this : image

Those are the logs (nothing more)

2025-03-26T07:19:39.198Z [info]: Creating user for tom@xxxxxxx.tld {"ip":"::ffff:192.168.2.10","email":"tom@xxxxxxx.tld"}

2025-03-26T07:19:39.210Z [error]: Failed OIDC login attempt {"cause":"Unknown error","ip":"::ffff:192.168.2.10","errorMessage":"SQLITE_CONSTRAINT: UNIQUE constraint failed: user.email"}

So the issue is that it tries to create my user. It fails because it already exists, with that email address image

The question is, why does it fails (or doesn't do) the lookup for my user email, before deciding to create the user??

Additional question : I am having hard to figure out how this will work with my existing user base. All of them are imported from Jellyfin, and thus none of them have an email address in Jellyseer. If the auth works only with emails and not username, I dont see how it can there be any match for existing users. If no username login is possible, I suppose that to use Authentik login, all of them will have to first login normally in Jellyseer and edit their profile to add their Authentik email. Its a bit annoying when you have several dozens of users.

I had the same issue, but was able to resolve it by linking my Authentik account to the automatically created Plex user.

image

Once these were linked, I did not get the error anymore.

@DuvelCorp
Copy link
Copy Markdown

DuvelCorp commented Mar 26, 2025

I had the same issue, but was able to resolve it by linking my Authentik account to the automatically created Plex user.

image

Once these were linked, I did not get the error anymore.

ok this worked indeed, thanks !

@RobertRvB
Copy link
Copy Markdown

@michaelhthomas is there a way to have it automatically go to the OIDC login page (Authentik in my case) whenever that is the only available login provider? I could not find a setting for this

image

@Ruakij
Copy link
Copy Markdown

Ruakij commented Mar 26, 2025

@michaelhthomas is there a way to have it automatically go to the OIDC login page (Authentik in my case) whenever that is the only available login provider? I could not find a setting for this

Such a setting doesnt exist (yet) as far as i have seen. Give them some time.

@voc0der
Copy link
Copy Markdown

voc0der commented Mar 26, 2025

As someone who is clinging on to the old preview-OIDC from the last PR, can anyone chime in on if the upgrade process is relatively straightforward? I really appreciate the work and want to jump back to the branch with the new stuff.

@michaelhthomas
Copy link
Copy Markdown
Contributor Author

FYI, the ability to link to an existing account (with the same email) while logging in is planned. It may end up being a separate PR though, this one is quite large as it is.

@michaelhthomas
Copy link
Copy Markdown
Contributor Author

Also, I've created a discussion for support/issues with the OpenID Connect preview. Please use this discussion for any questions or issues encountered with the OIDC preview and refrain from commenting them here, allowing this PR to be more effective for code review.

@github-actions github-actions bot added the merge conflict Cannot merge due to merge conflicts label Apr 8, 2025
@CoenWarmer

This comment has been minimized.

voc0der pushed a commit to voc0der/seerr that referenced this pull request Jan 28, 2026
Replaces the native fetch() API with axios for all OIDC-related frontend API calls. This improves
consistency with other parts of the codebase and simplifies error handling.

Addresses seerr-team#1505 (review)
voc0der pushed a commit to voc0der/seerr that referenced this pull request Jan 28, 2026
Updates the user settings documentation to be more generic. Instead of stating users can only sign
in with their email address, the text now correctly states that they can use their username or email
address. This accounts for both local and media server users.

Addresses seerr-team#1505 (comment)
voc0der pushed a commit to voc0der/seerr that referenced this pull request Jan 28, 2026
Moves the processCallback function from src/utils/oidc.ts directly into the OidcLoginButton.tsx
component where it is used. The now-empty oidc.ts utility file has been removed. This improves code
co-location as the function is only used in a single place.

Addresses seerr-team#1505 (comment)
voc0der pushed a commit to voc0der/seerr that referenced this pull request Jan 28, 2026
Adds a check to ensure a user with the same email address does not already exist before creating a
new user during an OIDC callback. If a duplicate email is found, the process is aborted with a 409
Conflict error.

Addresses seerr-team#1505 (comment)
voc0der pushed a commit to voc0der/seerr that referenced this pull request Jan 28, 2026
Deletes the ErrorCallout.tsx file as it is not used anywhere in the codebase. This cleans up dead
code from the project.

Addresses seerr-team#1505 (comment)
voc0der pushed a commit to voc0der/seerr that referenced this pull request Jan 28, 2026
Refactors the form in EditOidcModal to display validation errors manually using a `div` instead of
Formik's `<ErrorMessage>` component. This change brings the component's style in line with the
established pattern used in other forms throughout the application, improving code consistency.

Addresses seerr-team#1505 (comment)
voc0der pushed a commit to voc0der/seerr that referenced this pull request Jan 28, 2026
Adds a check to ensure a user with the same email address does not already exist before creating a
new user during an OIDC callback. If a duplicate email is found, the process is aborted with a 409
Conflict error.

Addresses seerr-team#1505 (comment)
voc0der pushed a commit to voc0der/seerr that referenced this pull request Jan 28, 2026
Deletes the ErrorCallout.tsx file as it is not used anywhere in the codebase. This cleans up dead
code from the project.

Addresses seerr-team#1505 (comment)
voc0der pushed a commit to voc0der/seerr that referenced this pull request Jan 28, 2026
Refactors the form in EditOidcModal to display validation errors manually using a `div` instead of
Formik's `<ErrorMessage>` component. This change brings the component's style in line with the
established pattern used in other forms throughout the application, improving code consistency.

Addresses seerr-team#1505 (comment)
@michaelhthomas
Copy link
Copy Markdown
Contributor Author

From a security standpoint and to ease implementation of e.g. pkce, wouldn't it make more sense to use a "battle-tested" and certified OIDC implementation like https://www.npmjs.com/package/openid-client?

I am in no way affiliated with https://www.npmjs.com/package/openid-client

When I began this work (almost 4 years ago!), it was based on a similar Overseerr PR, which implemented everything "by hand." I evaluated migrating everything to use a library then, and IIRC considered the Auth0 client library and found it was somewhat coupled to their service and not mature enough for the use-case. Looking at that library now, it seems to have improved significantly, so I may give that another shot. While I did my best to implement within the spec, I would also be more comfortable leveraging a "battle-tested" library than a bespoke implementation.

As an update on the status of this PR generally, I am considering closing this and splitting it further into pieces, in hopes that it will be more likely to be reviewed in a timely manner (and also easier for me to keep up-to-date). As part of that work, I may explore a new server implementation using such a library instead of a hand-rolled and likely flawed implementation.

@michaelhthomas michaelhthomas marked this pull request as draft February 8, 2026 22:41
@michaelhthomas
Copy link
Copy Markdown
Contributor Author

michaelhthomas commented Feb 8, 2026

Hey @michaelhthomas, what do you think about a "Auto-connect" feature? I was thinking about some kind of URL, or option that starts the OIDC flow automatically, like Mailcow's ?iam-sso=1 flag that starts SSO directly. It's useful for Authentik/Keycloak and other homepages.

1. The admin sets up the homepage element

2. He sets the url to https://seerr.example.com/login?autologin=authentik

3. When the user loads the webpage, it directly executes the login flow associated to the SSO provider.

4. The user is then logged in, without having to push any button.

This is a great compromise between those who do not like individual login pages and want to skip the login page entirely, and those who do want the possibility for the user to login by username/password; while minimizing the complexity of the login process in the codebase.

This is in fact already possible, though admittedly should be better documented. Your example was already almost correct, but https://seerr.example.com/login?provider=authentik should work as described.

@coolguy1771
Copy link
Copy Markdown

I'd be willing to take up this work, I have a working prototype I'll push in the next couple of days

Arakmar pushed a commit to Arakmar/seerr that referenced this pull request Feb 19, 2026
Replaces the native fetch() API with axios for all OIDC-related frontend API calls. This improves
consistency with other parts of the codebase and simplifies error handling.

Addresses seerr-team#1505 (review)
Arakmar pushed a commit to Arakmar/seerr that referenced this pull request Feb 19, 2026
Updates the user settings documentation to be more generic. Instead of stating users can only sign
in with their email address, the text now correctly states that they can use their username or email
address. This accounts for both local and media server users.

Addresses seerr-team#1505 (comment)
Arakmar pushed a commit to Arakmar/seerr that referenced this pull request Feb 19, 2026
Moves the processCallback function from src/utils/oidc.ts directly into the OidcLoginButton.tsx
component where it is used. The now-empty oidc.ts utility file has been removed. This improves code
co-location as the function is only used in a single place.

Addresses seerr-team#1505 (comment)
Arakmar pushed a commit to Arakmar/seerr that referenced this pull request Feb 19, 2026
Adds a check to ensure a user with the same email address does not already exist before creating a
new user during an OIDC callback. If a duplicate email is found, the process is aborted with a 409
Conflict error.

Addresses seerr-team#1505 (comment)
Arakmar pushed a commit to Arakmar/seerr that referenced this pull request Feb 19, 2026
Deletes the ErrorCallout.tsx file as it is not used anywhere in the codebase. This cleans up dead
code from the project.

Addresses seerr-team#1505 (comment)
Arakmar pushed a commit to Arakmar/seerr that referenced this pull request Feb 19, 2026
Refactors the form in EditOidcModal to display validation errors manually using a `div` instead of
Formik's `<ErrorMessage>` component. This change brings the component's style in line with the
established pattern used in other forms throughout the application, improving code consistency.

Addresses seerr-team#1505 (comment)
@adiojoe627
Copy link
Copy Markdown

Is this implemented in seerr?

@edbourque0
Copy link
Copy Markdown

Is this implemented in seerr?

No, this PR is still a draft.

@adiojoe627
Copy link
Copy Markdown

Is this implemented in seerr?

No, this PR is still a draft.

Gotcha thank you for the hard work you guys put in.

@cordlord
Copy link
Copy Markdown

cordlord commented Mar 4, 2026

I'm willing to donate/pay to get this feature merged/closed by the end of the month. March 20th is the 1 year mark...for this PR. The original issue was opened Jul 2022...

@0xSysR3ll
Copy link
Copy Markdown
Contributor

0xSysR3ll commented Mar 4, 2026

I'm willing to donate/pay to get this feature merged/closed by the end of the month. March 20th is the 1 year mark...for this PR. The original issue was opened Jul 2022...

Offering payment or donations does not affect whether or when a PR is merged. This project is volunteer-maintained, and reviews are based on technical merit and available time.

Also, as noted by the original author, this PR is likely to be reworked or split into smaller pieces to improve reviewability and long-term maintainability. Any next steps will follow from that.

Please be respectful of the maintainers' time.

@zcraftelite9495
Copy link
Copy Markdown

What are the current plans for integrating OIDC into the new master Seerr project?

I run my own media service for fam and friends and have used preview-OIDC for quite a while now, I have doubts that migration would be easy.

@michaelhthomas
Copy link
Copy Markdown
Contributor Author

Closed in favor of #2715

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge conflict Cannot merge due to merge conflicts preview PRs deployed for testing with tag `:preview-prxx`

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] Support login with OIDC [Feature request] SSO