I have been digging through the documentation and related topics to figure out how to improve our current auth0 setup. There is one aspect which I cannot readily find an answer on. To start our current setup is as follows:
We have a pretty standard SaaS application with a ExpressJS backend and React frontend. Right now if a client invites a new user to our platform we create a user in auth0 using the management API. We store this user_id auth0|… in our db together with the client id so we know who this user is and to which client it belongs. After creating the user we send a custom email to them with the password reset link[1]. This e-mail also includes an option to sign in with SSO which if used, we link the accounts if the e-mail is the same using a post login action. Clients also have the option to enforce SSO and if used we again link accounts based on e-mail.
The issue we are facing right now is that with Azure AD users have a upn that’s different from their e-mail which causes not to be able to link their accounts and we basically do not know who these people are. You can imagine someone being invited and getting a user account in auth0 with auth0|… and then using the mail to login with SSO this creates another account in auth0 with a user id waad|… and some upn that we cannot match to anyone.
From my investigation I can deduce there are a couple things wrong with this flow. First and foremost we should not be linking accounts based on e-mail without authenticating those accounts. From my understanding a normal flow would be create user in auth0 → invite with e-mail → have the user create a password → let them login to the application → link an SSO account with user initiated account linking [2]. This prevents linking accounts that shouldn’t be linked. It also let’s people link accounts with different upn/email/etc.
The one aspect which I cannot find much info on is what needs to be done if we want users to only and immediately make an account using SSO and skip the user + password flow. What I came up with was to add a query param with this users id which we can then send in the redirect callback so we know who the user was that clicked on the link and signed in with SSO. So the e-mail would have a ?token= on the SSO button. We pass this token to handleRedirectCallback({ authorizationParams: { token: url.searchParams.get(‘token’) } })now inside post login action we can access this token and find the user inside auth0 and link them.
So my question is what is the recommended way to allow only SSO signup and invitation by e-mail?
If you already have an external email solution and don’t want to configure an SMTP provider on your tenant, you can use the Management API to generate the password change ticket and email the ticket link to the user yourself instead of using Auth0’s email template and workflow.
It sounds like the real issue here isn’t Azure AD or UPNs so much as the fact that identity is being stitched together after the user has authenticated. Pre-creating a database user and then trying to link whatever SSO identity appears later (especially by email) is inherently fragile, and Entra just makes that more visible because UPN and email don’t have to match. If the intent is SSO-only onboarding via email, I’d avoid creating users up front entirely. Instead, invite the user into the tenant/org and let their first successful SSO login be what creates the Auth0 user and establishes which customer they belong to. That removes the need to match on email or UPN, cuts down technical debt, and gives you a much cleaner identity model. From a UX point of view it’s also simpler: accept invite → sign in with your company account → done.
On the Auth0 side, this is something you can support cleanly. You can use Organizations invitations to onboard users and, for customers that enforce SSO, disable or avoid the database connection for that application so there’s no password-based signup path at all. In Universal Login, that effectively removes the “sign up with email/password” option and only presents the allowed enterprise SSO connection(s) for that org. The invitation link carries the org (and optionally the connection), so Auth0 knows this is an invite-only flow and will create the user on first SSO login.
From a security and identity perspective, I’d also avoid silent account linking in Actions. If someone later needs multiple login methods, make that an explicit, user-initiated linking flow where both identities are authenticated. Your idea of passing a custom token in the invite link can work, but it’s essentially re-implementing invitation and binding logic that Auth0 already provides, which adds risk and ongoing maintenance. Treat email as a profile attribute for communication, not as an identity key, and use org/tenant membership as the stable source of truth.
Thank you for your fast and detailed reply. I fully agree that the issue is stitching together accounts. I understand what you are trying to say and it does look like organizations would be a good solution for us. However one thing I am still unclear on which kinda relates to the token solution. In our application when a client invites a member they can immediately select a bunch of options for this user. We store these options in our database. If we do not create the user upfront in auth0 how would we know who is who? Right now we create some user object like this in our db:
normally we would put the auth0 user id here as well but since we do not have that, how can we relate this back to the person who gets the invite, we can’t use the e-mail because that isn’t safe? It seems like we could use app_metadata property when creating the invite and put our id inside metadata so we know who it is?.(Welcome to Auth0 Docs - Auth0 Docs)
And if we wanted to not use organizations then such a flow is not possible to send invite urls without creating an account?
Thanks again for your reply it was already helpful