multi-ingress: Remove single IdP special-case#5291
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the IdP selection logic for /sso/get-by-email so that a single configured IdP is no longer automatically returned; instead, the IdP must match the requested domain (including the Nothing/unset case).
Changes:
- Removed the “single IdP always matches” branch in
getSsoCodeByEmailImpl, delegating all non-empty cases to domain-based matching. - Updated the unit property test to assert
Just idpIdonly when the IdP’s configured domain matches the requested domain.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| libs/wire-subsystems/src/Wire/IdPSubsystem/Interpreter.hs | Removes the singleton-IdP shortcut and always performs domain-based IdP selection for non-empty IdP lists. |
| libs/wire-subsystems/test/unit/Wire/IdPSubsystem/InterpreterSpec.hs | Adjusts the property test expectations to align with the updated domain-matching behavior. |
bfdec8f to
3998b98
Compare
| To align with the others, this check is also added to the `HEAD | ||
| /sso/initiate-login` pre-check endpoint. |
There was a problem hiding this comment.
@copilot Your change seems to have the same issue. Please make better proposal.
Previously, we treated a single IdP as global (spanning all domains) in multi-ingress. But, this leaks information about "something which all ingresses have in in common". Also, it's hard to impossible to configure a working setup for this on (some?) SaaS. So, we now require that - when multi-ingress is configured - the IdP used for a request must have the same domain as the ingress which received the request.
19fc31c to
d7114b3
Compare
| let ernieZHost = "nginz-https.ernie.example.com" | ||
| bertZHost = "nginz-https.bert.example.com" | ||
| kermitZHost = "nginz-https.kermit.example.com" |
| initiateSamlLoginWithZHost :: (HasCallStack, MakesValue domain) => domain -> Maybe String -> String -> App Response | ||
| initiateSamlLoginWithZHost domain mbZHost idpId = initiateSamlLoginWithZHostAndLabel domain mbZHost Nothing idpId -- | ||
|
|
||
| -- | https://staging-nginz-https.zinfra.io/v16/api/swagger-ui/#/default/auth-req-precheck |
There was a problem hiding this comment.
Can you detail a bit this comment
There was a problem hiding this comment.
Sure, I saw that there is a pattern in this module to add links to Swagger to these endpoint client functions. Then, I followed the pattern as well.
| resp.status `shouldMatchInt` 404 | ||
| resp.json %. "label" `shouldMatch` "not-found" |
There was a problem hiding this comment.
I think there is a helper like assertLabel?
There was a problem hiding this comment.
I forgot about it 😅 But, you're right: It's better 👍
Previously,
POST /sso/get-by-emailandGET /sso/initiate-loginendpointstreated an IdP as globally configured for all domains when there was only one
for a team. This led to information leakage and confusion, raising "Why do I endup at another domain's IdP when I'm on this one?" questions. Now, these endpoints
always treat IdPs as bound to a domain when multi-ingress is configured. I.e.
IdP domain and request domain must match, otherwise an error is returned.
The error resembles what would be returned if the IdP wouldn't exist.
To align with the others, this check is also added to the
HEAD /sso/initiate-loginpre-check endpoint.Ticket: https://wearezeta.atlassian.net/browse/WPB-26244
Checklist
changelog.dRead and follow the PR guidelines(Breaking behaviour, but currently no-one is using multi-ingress in prod)