Skip to content

Add multi-domain OAuth/OpenID support#26074

Merged
AlexGaillard merged 48 commits intomainfrom
gaetan/prod-737-sso-redirect-issue-with-external-url
Nov 18, 2025
Merged

Add multi-domain OAuth/OpenID support#26074
AlexGaillard merged 48 commits intomainfrom
gaetan/prod-737-sso-redirect-issue-with-external-url

Conversation

@gaetansenn
Copy link
Contributor

@gaetansenn gaetansenn commented Oct 29, 2025

Scope

What's changed:

  • Added support for dynamic OAuth redirect URIs based on the originating request's host
  • Modified OAuth2 and OpenID drivers to use request origin from AUTH_<PROVIDER>_REDIRECT_ALLOW_LIST env
  • Centralized OAuth callback URL generation logic in oauth-callbacks.ts utility
  • Added X-Forwarded-Host and X-Forwarded-Proto forwarding in Vite development proxy

Potential Risks / Drawbacks

  • If IP_TRUST_PROXY is misconfigured behind a reverse proxy, host headers could be spoofed (same risk as existing code, but now used for OAuth callbacks)

Tested Scenarios

  • Single-domain deployment (legacy mode)
  • Multi-domain deployment with AUTH_<PROVIDER>_REDIRECT_ALLOW_LIST configured
  • Request origin extraction with and without IP_TRUST_PROXY
  • Invalid origins and callback URL matching

Checklist

  • Added or updated tests
  • Documentation PR created here or not required

Fixes #25404

@linear
Copy link

linear bot commented Oct 29, 2025

@gaetansenn gaetansenn changed the title Multi-domain OAuth/OpenID support Add multi-domain OAuth/OpenID support Oct 29, 2025
@codecov
Copy link

codecov bot commented Oct 29, 2025

Codecov Report

❌ Patch coverage is 41.17647% with 40 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.51%. Comparing base (bbd4802) to head (8a6d9fd).
⚠️ Report is 9 commits behind head on main.

❌ Your patch status has failed because the patch coverage (41.17%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #26074      +/-   ##
==========================================
+ Coverage   59.13%   59.51%   +0.37%     
==========================================
  Files        2076     2077       +1     
  Lines      131333   131352      +19     
  Branches     7848     7976     +128     
==========================================
+ Hits        77666    78174     +508     
+ Misses      53667    53178     -489     
Flag Coverage Δ
api 44.32% <41.17%> (+1.11%) ⬆️
app 70.54% <ø> (ø)
composables 82.25% <ø> (ø)
create-directus-extension 94.44% <ø> (ø)
create-directus-project 98.43% <ø> (ø)
env 99.67% <ø> (ø)
errors 97.47% <ø> (ø)
extensions 35.63% <ø> (ø)
extensions-registry 95.27% <ø> (ø)
extensions-sdk 14.38% <ø> (ø)
format-title 100.00% <ø> (ø)
memory 95.75% <ø> (ø)
pressure 77.63% <ø> (ø)
release-notes-generator 81.14% <ø> (ø)
schema-builder 80.59% <ø> (ø)
sdk 8.33% <ø> (ø)
storage 92.00% <ø> (ø)
storage-driver-azure 76.76% <ø> (ø)
storage-driver-cloudinary 81.14% <ø> (ø)
storage-driver-gcs 69.72% <ø> (ø)
storage-driver-local 69.76% <ø> (ø)
storage-driver-s3 46.73% <ø> (ø)
storage-driver-supabase 68.20% <ø> (ø)
system-data 71.81% <ø> (ø)
update-check 55.67% <ø> (ø)
utils 87.16% <ø> (ø)
validation 44.50% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@gaetansenn gaetansenn marked this pull request as ready for review October 29, 2025 19:43
@gaetansenn gaetansenn requested a review from a team as a code owner October 29, 2025 19:43
@gaetansenn gaetansenn requested a review from a team as a code owner October 30, 2025 15:07
Copy link
Member

@ComfortablyCoding ComfortablyCoding left a comment

Choose a reason for hiding this comment

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

At some point this looks to have stopped working.

Tests

  • Expect non SSO login to succeed
  • Expect multi domain non SSO login to succeed
  • Expect regular SSO login to succeed
  • Expect multi domain SSO login to succeed - FAIL -Non-issue

Reproduction

Screen.Recording.2025-11-13.at.9.57.32.PM.mov

@gaetansenn
Copy link
Contributor Author

At some point this looks to have stopped working.

Tests

  • Expect non SSO login to succeed
  • Expect multi domain non SSO login to succeed
  • Expect regular SSO login to succeed
  • Expect multi domain SSO login to succeed - FAIL

Reproduction

Screen.Recording.2025-11-13.at.9.57.32.PM.mov

From what I see it's because isUrlAllowed is checking the port (protocol+domain+port) + pathname.
From your .env you doesn't have included 8055 http://app1.com expecting http://app1.com:8055.
You proposed to not include the port from isLoginRedirectAllowed why not ?

@ComfortablyCoding
Copy link
Member

ComfortablyCoding commented Nov 14, 2025

From what I see it's because isUrlAllowed is checking the port (protocol+domain+port) + pathname.
From your .env you doesn't have included 8055 http://app1.com expecting http://app1.com:8055.
You proposed to not include the port from isLoginRedirectAllowed why not ?

I suggested that we stay consistent with the existing end-of-flow check in isLoginRedirectAllowed and check protocol + domain instead of origin, I didn't request any changes to isUrlAllowed.Since the port was not previously required for this flow to work, it shouldn't be necessary now. The domain matching the public url still functions as expected, so it is likely something else is at play here

@ComfortablyCoding ComfortablyCoding dismissed their stale review November 14, 2025 14:38

Expected, only PUBLIC_URL should have domain fallback

@ComfortablyCoding ComfortablyCoding self-requested a review November 14, 2025 14:38
@AlexGaillard AlexGaillard merged commit aa7d1ac into main Nov 18, 2025
79 of 82 checks passed
@AlexGaillard AlexGaillard deleted the gaetan/prod-737-sso-redirect-issue-with-external-url branch November 18, 2025 16:32
@github-actions github-actions bot added this to the Next Release milestone Nov 18, 2025
AlexGaillard pushed a commit that referenced this pull request Nov 19, 2025
* feat: use origin host for authentification

* fix: remove context for client error

* build: add changeset

* fix: fix lint

* feat: optimise code

* fix: rename utils method

* fix: optimise code

* feat: use AUTH_**_REDIRECT_ALLOW_LIST

* fix: remove old env

* fix: avoid empty redirectUris

* feat: handle some optimisation

* refactor: optimize util

* tests: add oauth-callbacks util test

* build: update changeset

* fix: fix lint

* refactor: clean up code

* refactor: remove ordering logic

* feat: add new tests

* fix: update tests

* fix: update tests

* test: update it

* test: clean up code

* test: update test

* test: update tests

* fix: fix vite proxy

* fix: handle feedbacks

* build: change sentence in past

* refactor: disable change origin

* refactor: optimize code

* fix: format code

* fix: format code

* refactor: optimise code

* refactor: lint

* fix: fix callback injection

* refactor: handle feedbacks

* fix: fix isLoginRedirectAllowed usage

* fix: handle feedbacks

* fix: handle feedbacks

* refactor: revert logic

* lint: clean up

* fix: update tests

* refactor: fix formating

* fmt

---------

Co-authored-by: daedalus <[email protected]>
@BlackDahlia313
Copy link
Contributor

Don't think this was ready for production...

Just upgraded one of my backends from 11.9.2 to the latest version that includes this and with absolutely no change to my ENV I am seeing this now on every single SSO provider I have setup.

No SSO is working anymore.

image

ComfortablyCoding added a commit that referenced this pull request Nov 21, 2025
AlexGaillard pushed a commit that referenced this pull request Nov 21, 2025
* Revert "Add multi-domain OAuth/OpenID support (#26074)"

This reverts commit aa7d1ac.

* add changeset

* Update salty-bees-win.md
@AlexGaillard
Copy link
Member

Thanks for reporting @BlackDahlia313 👍.

We've reverted it and sent out a patch release. It seems this one needed a bit longer in the oven. We'll try to address the cases uncovered here and send it back out when it's ready.

@BlackDahlia313
Copy link
Contributor

Thanks for reporting @BlackDahlia313 👍.

We've reverted it and sent out a patch release. It seems this one needed a bit longer in the oven. We'll try to address the cases uncovered here and send it back out when it's ready.

NP! Thanks for the taking the time to deep dive into this! I think it was just perfect timing I caught this haha.

I like the direction of what's intended. Here to help test if needed!

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 24, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SSO redirect Issue with external URL

4 participants