Skip to content

feat(networking): implement forward auth#1564

Open
ishanjain28 wants to merge 9 commits into
seerr-team:developfrom
ishanjain28:fw-auth-11
Open

feat(networking): implement forward auth#1564
ishanjain28 wants to merge 9 commits into
seerr-team:developfrom
ishanjain28:fw-auth-11

Conversation

@ishanjain28

@ishanjain28 ishanjain28 commented Apr 6, 2025

Copy link
Copy Markdown
Contributor

Description

This PR adds the Forward Auth feature. It fixes the feedback received in previous attempt here

  1. A few different header names are allowed but they have to added to the allow list in the code. Supporting completely arbitrary headers was difficult.
  2. Forward auth headers are only processed if request came from a trusted proxy and configuring trusted proxy is required to use the forward auth feature.
  3. Forward auth can be done in 3 ways.
    a. Verify the user field against jellyfinUsername | plexUsername columns.
    b. Verify the email field against email column.
    c. Verify both the user and email fields.

How Has This Been Tested?

This has been tested using the included test suite and manually in different environments. Manual test examples,

  1. With Seerr behind 1 trusted proxy and 2 trusted proxies.
  2. With Seerr configured with no trusted proxies
  3. Different header names in use and sometimes they were set, sometimes they were not set and I got the expected result every time.

Screenshots / Logs (if applicable)

Screenshot 2025-04-06 at 17 42 14

Checklist:

  • I have read and followed the contribution guidelines.
  • Disclosed any use of AI (see our policy)
  • I have updated the documentation accordingly.
  • All new and existing tests passed.
  • Successful build pnpm build
  • Translation keys pnpm i18n:extract
  • Database migration (if required)

Summary by CodeRabbit

  • New Features

    • Forward Authentication (SSO) via trusted proxies with configurable user/email headers and Advanced Network Settings UI (trusted IPv4/IPv6 lists, validation).
  • Documentation

    • Added guide for configuring Forward Authentication with Traefik and example auth provider setup.
  • Chores

    • Added runtime IP validation dependency.
  • Tests

    • Updated end-to-end test covering trusted-proxy/forward-auth and restart modal behavior.
  • Quality

    • Centralized server-side auth header handling and allowlist for forwarded headers.

@ishanjain28 ishanjain28 changed the title Fw auth 11 feat: Forward Auth Apr 6, 2025
@ishanjain28

Copy link
Copy Markdown
Contributor Author

@fallenbagel @gauthier-th This PR is now ready for review!

@fallenbagel fallenbagel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't fully review this yet but I noticed one issue. The Dockerfile. Also in terms of UI, I would recommend putting the forwardAuth stuff to be indented like how http(s) proxy is done:
image

Also I would argue that this should be under the advanced networking section as this is not for the normal user. Wdyt about that @gauthier-th

Comment thread Dockerfile
@gauthier-th

Copy link
Copy Markdown
Member

I didn't fully review this yet but I noticed one issue. The Dockerfile. Also in terms of UI, I would recommend putting the forwardAuth stuff to be indented like how http(s) proxy is done:
image

Also I would argue that this should be under the advanced networking section as this is not for the normal user. Wdyt about that @gauthier-th

100% agree

@ishanjain28

Copy link
Copy Markdown
Contributor Author

@fallenbagel @gauthier-th Applied all the suggestions.

  1. reverted changes to dockerfile
  2. Moved the trusted proxies section, forward auth sections to advanced menu. forward auth depends on trusted proxy.
  3. Indented as requested
Screenshot 2025-04-07 at 22 36 49

@ishanjain28 ishanjain28 force-pushed the fw-auth-11 branch 2 times, most recently from a7729d8 to 3c4134f Compare April 7, 2025 17:41
Comment thread src/components/Settings/SettingsNetwork/index.tsx Outdated
Comment thread src/utils/forwardAuthList.ts Outdated
Comment thread server/middleware/auth.ts Outdated
Comment thread src/components/Settings/SettingsNetwork/index.tsx
@github-actions

github-actions Bot commented Apr 8, 2025

Copy link
Copy Markdown

This pull request has merge conflicts. Please resolve the conflicts so the PR can be successfully reviewed and merged.

@github-actions github-actions Bot removed the merge conflict Cannot merge due to merge conflicts label Apr 8, 2025
@bash9810

Copy link
Copy Markdown

excited for this, would love to setup authentik as the auth for jellyseerr, think this is the way to get that done.

@ishanjain28 ishanjain28 requested a review from fallenbagel April 14, 2025 04:42
@github-actions github-actions Bot added the merge conflict Cannot merge due to merge conflicts label Apr 30, 2025
@github-actions

Copy link
Copy Markdown

This pull request has merge conflicts. Please resolve the conflicts so the PR can be successfully reviewed and merged.

@github-actions github-actions Bot removed the merge conflict Cannot merge due to merge conflicts label May 21, 2025
@ishanjain28

Copy link
Copy Markdown
Contributor Author

Rebased this PR on top of latest develop and fixed a small bug. Ready for review!

@github-actions github-actions Bot added the merge conflict Cannot merge due to merge conflicts label Jun 13, 2025
@github-actions

Copy link
Copy Markdown

This pull request has merge conflicts. Please resolve the conflicts so the PR can be successfully reviewed and merged.

@ishanjain28

ishanjain28 commented Apr 18, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @natemccurdy, that was a good observation! It was indeed authenticating every request and setting the user id in session avoids a lot of unnecessary work!

edit: Actually @natemccurdy, this change will introduce a bug. Authelia sets a cookie _sso, seerr sets a cookie connect.sid. Clear _sso cookie and refresh the page. It takes back to the authelia login page and now if you login as a different user, it'll still login as the user you were logged in as before deleting the _sso cookie.

edit: reverted the change since it introduces a bug.

@github-actions github-actions Bot added the merge conflict Cannot merge due to merge conflicts label Apr 24, 2026
@github-actions

Copy link
Copy Markdown

This pull request has merge conflicts. Please resolve the conflicts so the PR can be successfully reviewed and merged.

@exenza

This comment was marked as off-topic.

@ishanjain28

This comment was marked as off-topic.

@exenza

This comment was marked as off-topic.

@gauthier-th gauthier-th requested a review from M0NsTeRRR May 6, 2026 12:07
@Sapd

Sapd commented May 7, 2026

Copy link
Copy Markdown

3 issues:


/api/v1/* returns 401 cookie 'connect.sid' required once forward-auth is on, even when the proxy headers are set correctly.

In OpenAPIValidator: cookieAuth is the security scheme on every endpoint and the validator runs before the auth middleware, so requests without a session cookie get rejected before forward-auth even has a chance.

Fixed like this server/index.ts:

 OpenApiValidator.middleware({
   apiSpec: API_SPEC_PATH,
   validateRequests: true,
+  validateSecurity: false,
 })

isAuthenticated() already does the actual auth check, so the validator's cookie requirement is redundant and it breaks any non-cookie auth path (this PR, OIDC in #2715, future API-key flows). @Jycreyn flagged the
same thing on #2715.


Can we get also automatic user creation?

 if (!user && hasUserHeader && userValue) {
    user = userRepository.create({
      jellyfinUsername: userValue,
      email: emailValue || `${userValue}@forward-auth.local`,
      userType: UserType.JELLYFIN,
      permissions: settings.main.defaultPermissions,
    });
    await userRepository.save(user);
  }

The lookup uses exact SQL equality on jellyfinUsername. That bites in practice because:

  • Jellyfin's AuthenticateByName lowercases the username before storing, so the row is joe
  • Authentik (and most IDPs) preserve original casing in property mappings, so the header arrives as Joe (upper case)

Could the WHERE be case-insensitive? With TypeORM:

  qb.where(
    'LOWER(user.jellyfinUsername) = LOWER(:u) OR LOWER(user.plexUsername) = LOWER(:u)',
    { u: userValue }
  );

Edit: I did fixes here, incl auto creation of users: https://github.com/Sapd/seerr/commits/forward-auth-fixes/

@Xatrekak

Copy link
Copy Markdown

@M0NsTeRRR I have carried forward the work of @ishanjain28 and @Sapd HERE fixing some issues regarding the cloudflare forward auth workflow as well as a bug if the proxy is running a dual stack listener.

If the original author does not return I am willing to put in the work to get this over this finish line whether its fixing any actual issues or just resolving the merge conflicts.

I have end-to-end tested my current branch and it seems fully functional.

@ishanjain28

Copy link
Copy Markdown
Contributor Author

I can take a look at this again on upcoming weekend.

@M0NsTeRRR

M0NsTeRRR commented Jun 11, 2026

Copy link
Copy Markdown
Member

@Xatrekak feel free to open some pull requests on @ishanjain28 fork. That way, he can review your fix and merge it when he has time this weekend.

@github-actions github-actions Bot removed the merge conflict Cannot merge due to merge conflicts label Jun 13, 2026
@ishanjain28

ishanjain28 commented Jun 13, 2026

Copy link
Copy Markdown
Contributor Author

This has been rebased with changes from @Xatrekak. I also verified it in my instance, it works correctly. Ready for review!

Comment thread server/middleware/auth.ts Dismissed
Comment thread server/middleware/auth.ts Dismissed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for Forward Auth