-
Notifications
You must be signed in to change notification settings - Fork 334
multi-ingress: cross-IdP SSO #5212
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| When a team uses multiple SAML IdPs (one per ingress domain) in a multi-ingress | ||
| setup, users can now authenticate via any of the team's IdPs even if their | ||
| account was originally provisioned under a different one. Spar resolves the | ||
| correct account by email-based NameID lookup across all team IdPs and migrates | ||
| the user's SSO identity to the authenticating IdP transparently. | ||
|
|
||
| **Important:** Email addresses (`NameID`s) must be unique across configured | ||
| IdPs! Otherwise, users may be logged in into wrong accounts! | ||
|
|
||
| Please refer to the documentation for further information. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1266,7 +1266,8 @@ Given an email address, the SSO code is looked up by these criteria: | |
| This is the case for: | ||
| - Teams with exactly one configured IdP | ||
| - There is an IdP for the given multi-ingress domain | ||
| - The user was created via SCIM | ||
| - The user is a SSO user. So it was created via SCIM with SSO enabled (any IdP | ||
| configured in SCIM token) OR created via SSO (no SCIM involved). | ||
|
|
||
| The last condition ensures that team admins cannot get into locked-out | ||
| situations due to misconfigured IdPs. | ||
|
|
@@ -1500,6 +1501,60 @@ error. Though, IdPs can be reconfigured as long as this invariant holds. | |
|
|
||
| Putting it differently: We require an unambiguous mapping `(team, domain) -> IdP`. | ||
|
|
||
| #### Multi-ingress cross-IdP SSO (fallback) | ||
|
|
||
| Terms used below: | ||
|
|
||
| - _Authenticating IdP_ — the external identity provider that issued the SAML | ||
| assertion, identified by the `Issuer` URI inside it. | ||
| - _IdP configuration_ — backend's IdP representation registered via | ||
| `/identity-providers`, storing the issuer URI, the associated multi-ingress | ||
| domain, and the team. | ||
|
|
||
| In the normal SSO flow spar looks up the authenticating user by their `(issuer, | ||
| NameID)` pair — matching the assertion's issuer against the IdP configuration | ||
| the user was provisioned under. | ||
|
|
||
| In a multi-ingress setup each domain has its own IdP configuration with its own | ||
| issuer URI. A user provisioned under domain _A_ has their SSO identity tied to | ||
| issuer _A_'s URI. When that user later authenticates via domain _B_, the IdP | ||
| authentication response's assertion carries issuer _B_'s URI, so the primary | ||
| `(issuer, NameID)` lookup finds nothing. Using a shared static issuer across | ||
| all domains is not an option because each external identity provider has its | ||
| own issuer URI that spar cannot control. | ||
|
|
||
| When this primary lookup finds no user, spar therefore attempts a cross-IdP | ||
| migration when multi-ingress is configured: | ||
|
|
||
| 1. **NameID must be an email address.** Username-based `NameID`s are rejected | ||
| to avoid ambiguity across authenticating IdPs. | ||
|
Comment on lines
+1529
to
+1530
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nit] admins need to manually guarantee that email addresses are unique, so why can't they do the same thing here? |
||
| 2. **The matching IdP configuration is resolved.** Spar looks for an IdP | ||
| configuration in the team whose issuer URI and configured domain both match the | ||
| assertion's issuer and the incoming `Z-Host` header (exact match). If no exact | ||
| match is found and the team has exactly one IdP configuration, that one is used | ||
| unconditionally (no issuer or domain check). If neither condition is met, the | ||
|
Comment on lines
+1533
to
+1535
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why pick a non-matching IdP, and not just reject right away? |
||
| login is rejected. | ||
| 3. **Team-wide user search.** Spar searches all of the team's IdP | ||
| configurations for a user whose email NameID matches the subject. This can be | ||
| understood as trying to login with all team IdP configurations. This step also | ||
| _finds_ the user, before we found them we don't know their IdP. (So, we can't | ||
| simply use their IdP first.) | ||
| 4. **Migrate or provision:** | ||
| - _Exactly one match found:_ The user's SSO identity is updated to point to | ||
| the IdP configuration for the authenticating IdP's issuer, so subsequent | ||
| logins hit the primary lookup directly. This saves the complexity of the IdP | ||
| configuration lookup and keeps the backend's representations of the user's | ||
| SSO data sound. | ||
| - _No match found:_ A new user account is auto-provisioned under the | ||
| authenticating IdP's configuration. | ||
| - _No matching IdP configuration can be resolved:_ Login is rejected. | ||
|
|
||
| ##### Security considerations | ||
|
|
||
| It must be ensured that email `NameID`s are unique across IdPs by IdP | ||
| administrators. Otherwise, users are falsely logged in into other user's | ||
| accounts! | ||
|
|
||
| ### Webapp | ||
|
|
||
| The webapp runs its own web server (a NodeJS server) to serve static files and the webapp config (based on environment variables). | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused by this sentence. How about:
If yours is more correct, I want to understand how.