Best way for users to link their Azure AD account

Details:

  • Platform is invite only
  • All users will have Username-Password-Authentication primary accounts
  • Some users may want to link their accounts to their Azure AD/Entra ID company accounts
  • They can then use a SSO Entra button to login to their account
  • This is setup via the common Microsoft endpoint so any user can do it.

My problem is:

Using the azure ad connection creates a empty account, I do not want any person to be able to do this. It seems the solution is an action to block these and delete the created account.

However, the flow in the front end seems to be:

  • User logins in via Username-Password-Authentication account
  • They click a button which prompts azure ad sign in
  • This account is then linked to the primary account

How would you distinguish between a user wanting to link their entra account and any person using the SSO button.

Any suggestions on the best and easiest way to implement this.

Hi @harry5,

Welcome to the Auth0 Community!

To prevent unwanted access, as you have mentioned as well you must implement a Post-Login Action that acts as a bouncer by evaluating the user’s identity structure before they are fully authorized. This Action is essential because it detects the “ghost” account at the moment of creation, blocks the login session, and uses the Auth0 Management API to immediately delete the unauthorized record from your database.

The distinction between a Ghost Account and a Legitimate User is found in the event.user.identities array. A ghost account appears as a standalone Entra ID profile with a single identity entry, which signals to your Action that this user has no pre-existing “Primary” account and should be deleted. For example, if identities.length === 1 and the provider is waad, the Action executes management.users.delete() to wipe the record instantly.

In order to tackle another possible distinction, once the accounts are linked, the Auth0 Action will always recognize that the user profile was originally anchored to the Username-Password-Authentication identity. Even when the user clicks the “Login with AD” button, Auth0 identifies the incoming Entra ID credentials as a “secondary” identity that belongs to the primary database account.

I hope this helps answer your inquiry and if you have further questions please let me know below!
Best regards,
Remus

Hi

The issue I have, is before the link happens.

The entra id account has to exist before linking. There does not seem to be any mechanism to add an account to your main account otherwise.

So how would you tell the difference between a legit entra id account that is about to be linked and ghost account inside your action to deny entra accounts.

Thanks

Hi @harry5,

Thank you for your clarification and sorry for the late response!

In this scenario I would recommend to introduce a button inside your app called “Link Company account”, initiated either via Client-Side Implementation or Server-Side Implementation. Instead of allowing the “Login with AD” button to create random accounts, you move the initiation inside your app’s dashboard where the user is already identified by their primary username and password.

The process begins with a “Link Account” button in your app settings that triggers a new authentication request specifically for the Entra ID connection. By including a custom flag (like link_account=true) in that request, your Post-Login Action can distinguish this as a legitimate setup phase rather than an unauthorized login attempt by using a query such as if event.request.query.link_account === 'true'.

Using a Server-Side Linking, your backend receives the Entra ID credentials and makes a secure call to the Auth0 Management API to manually merge the new AD identity into the existing primary user profile. This is the gold standard for security as the linking happens entirely on your protected server.
As for Client-Side Linking, your frontend uses an Auth0 SDK to handle the secondary login and then calls a linking method that sends the identity token back to Auth0 to append it to the current user’s session.

Once either method completes the link, the Entra ID identity is permanently stored as a secondary provider under the original Username-Password account. The next time the user clicks the SSO button on your login page, the Action sees a multi-identity profile anchored to an invited user and grants access. Anyone else clicking that button will be identified as a standalone “ghost” by the Action and immediately deleted.

I hope this helps.
Best regards,
Remus