Fix SSO session, MFA and provisioning accuracy in 13-3 - #449
Conversation
Three corrections to the Access Controls and SSO article, verified against the production Auth0 tenant and the post-login Action: - Session Management stated that IdP session values "take precedence over Light's defaults". This is backwards: Light's session limits apply to all users including SSO users, and the IdP does not extend them. - The MFA section described only Light's internal administrative access, so customers had no indication that their own users are prompted for a second factor — including when signing in through SSO. - SSO setup did not mention that users are never auto-provisioned on first sign-in. Accounts must exist in Light beforehand or authentication is denied, which is a common go-live surprise.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 06cd546c3c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| - **Authenticator app**: Users verify with a one-time password from an authenticator app such as Google Authenticator. | ||
| - **Applies in addition to SSO**: Signing in through your identity provider does not replace Light's MFA step. If your identity provider also enforces MFA, users complete both. | ||
| - **Remember this device**: Users can choose to be remembered, which suppresses the prompt on subsequent sign-ins until the session reaches its inactivity or maximum lifetime (see [Session Management](#session-management)). |
There was a problem hiding this comment.
Decouple remembered MFA from the session lifetime
When a user selects Remember this device, Auth0 records that choice in a separate remember-browser cookie; expiring Light's Auth0 application session does not necessarily expire that cookie. Consequently, after the inactivity or maximum lifetime triggers a new authentication transaction, the remembered browser can still bypass the MFA prompt. Tying MFA remembrance to these session limits gives customers the incorrect expectation that every session expiration forces MFA again, so this should describe the independently configured remember-device lifetime instead.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Accepted, wording changed. I had based the coupling on an Auth0 support article stating that tenant session settings apply to MFA cookies as well as session cookies — but that page is scoped to ephemeral sessions, so it does not generalise.
Tenant logs do show MFA events at roughly the same volume as successful logins, but that is equally consistent with users simply not selecting "remember this device", so it does not establish the coupling either. Removed the mechanism claim rather than assert it: the bullet now says the prompt is suppressed "for a limited period".
|
@tiagoengel could you please have a look and confirm these changes are actually correct? |
tiagoengel
left a comment
There was a problem hiding this comment.
Looks good @mtantawy, just a few small comments
|
|
||
| ### MFA for your users | ||
|
|
||
| Light also applies its own MFA step to users signing in to the application: |
There was a problem hiding this comment.
This is missing that not all roles require it. I think reimbursement role and card holder don't require it. Don't remember exactly, but this would be defined in the auth0 action code.
There was a problem hiding this comment.
Good catch, added. One correction: Cardholder is not exempt — the only exempt roles are REIMBURSEMENT and INVOICE_APPROVER, and the check is "every role the user holds is in that set", so a Cardholder does get prompted.
Worth flagging since the belief that Cardholders skip MFA is wrong in the unsafe direction if it reaches a customer.
|
|
||
| SSO controls how users authenticate — it does not create their Light accounts. Users are **not** provisioned automatically on first sign-in, so each user must already exist in Light before they can sign in through SSO. | ||
|
|
||
| Create users in advance under **Business partners > Users**, using the same email address they will present from your identity provider. A user who authenticates successfully at your identity provider but has no matching Light account will be denied access. |
There was a problem hiding this comment.
Might be worth mentioning we support auto provisioning by integrating with HRM systems, but not JIT provisioning from the identity provider
There was a problem hiding this comment.
Added — the User Provisioning section now separates HRM auto-provisioning (supported, via Finch: imports employees, keeps active/inactive in step, assigns a default role) from JIT provisioning by the IdP (not supported), with a link to 11-8-hrm-finch.
…ording - State which users are prompted for MFA. Any role beyond Reimbursement and Invoice approver requires a second factor; users limited to those two do not. Raised by @tiagoengel, who recalled Cardholder as exempt — it is not. - Distinguish HRM-based auto-provisioning (supported, via Finch) from just-in-time provisioning by the identity provider (not supported), and link to the HRM integration article. - Drop the claim that "remember this device" lapses when the Light session reaches its inactivity or maximum lifetime. Auth0 stores that choice in a separate remember-browser cookie, and the coupling is not established well enough to state in customer documentation.
Corrects inaccuracies in Access Controls and SSO (
13-3), found while answering a customer SSO question. Everything here was verified against the production Auth0 tenant and the post-login Action, not inferred.What's fixed
1. Session Management — the SSO claim was backwards
The article said:
Auth0 maintains its own session, and our tenant-level inactivity and maximum session limits apply to every user including SSO users. The IdP governs how users authenticate; it does not extend our session lifetime. As written, a customer would plan around their own IdP timeout and be wrong.
2. MFA section only covered Light's internal access
It described MFA for "administrative and engineering access to production systems" — i.e. our staff. Nothing told customers that their users get an authenticator-app prompt, that it applies on top of their own SSO/IdP MFA, or that recovery codes aren't enabled so a lost device needs an admin reset. This is the first thing a customer's IT team asks and the article was silent on it.
Now also states who is prompted: any role beyond Reimbursement and Invoice approver. Added after review at @tiagoengel's request — note that Cardholder is not exempt, contrary to the recollection in the review thread.
3. Provisioning was undocumented
Users are never auto-provisioned by the identity provider on first sign-in — an unknown email is denied outright. Confirmed in code (
getUserForLoginByEmailthrowsUserNotFoundByEmailException) with a covering integration test. The new User Provisioning section separates this from HRM-based auto-provisioning via Finch, which is supported.Deliberately not changed — needs a check
Unrelated drift worth a separate look
The Notion record for this article documents an accuracy pass (Local currency vs "base currency", Dunning vs "Invoice-to-cash", the hardcoded "at least two approvers" example, the permissions-matrix count) that is not in the git source — lines 79, 91 and 104 still carry the old text. Those edits appear to have been made in Notion only. Out of scope here, but the two copies are out of sync.
Note before merging
sync-to-cms.ymlfires on push tomain, so merging publishes straight to the live knowledge base.