|
| 1 | +# A brief research on how Organization works in Auth0 |
| 2 | + |
| 3 | +## Concepts |
| 4 | + |
| 5 | +This section introduces a few concepts you must know in order to read this document. |
| 6 | + |
| 7 | +### Tenant |
| 8 | + |
| 9 | +- A tenant is like an Authgear project. |
| 10 | +- It can have many connections, applications, and organizations. |
| 11 | + |
| 12 | +### Connection |
| 13 | + |
| 14 | +- An isolated user pool. |
| 15 | +- Each connection presents a way to identity an user, and the means to authenticate them, for example, email-password, email-OTP, username-password, or Social Login Provider like Google Login. |
| 16 | +- The same email address in 2 different email connections represent different users. |
| 17 | +- For connection like email-password and username-password, each connection has its own password policy separate from each other. |
| 18 | + |
| 19 | +### User |
| 20 | + |
| 21 | +- A user belongs to one and only one connection. |
| 22 | + |
| 23 | +### Application |
| 24 | + |
| 25 | +- An application is an OIDC client application. |
| 26 | +- Applications and connections form a N-to-M relationship. This relationship controls what users can sign in to a particular application. |
| 27 | +- The above relationship does not hold always. It depends on the "Login Experience" option of your application. |
| 28 | + - When "Login Experience" is "Individuals", the application is NOT organization-aware, the application-connection relationship control what users can sign in. |
| 29 | + - When "Login Experience" is "Business Users", the application-connection relationship is ignored. Any users from any organizations can sign in. |
| 30 | + The "Login Flow" option further determines the behavior. |
| 31 | + - When "Login Flow" is "Prompt for Credentials", the end user enters email, authenticate with password, and finally got asked which organization to sign in to. |
| 32 | + - When "Login Flow" is "Prompt for Organization", the end user enters the organization slug first, and then enter email, authenticate with password. |
| 33 | + - When "Login Flow" is "No Prompt", you need to specify which organization to sign in to in the SDK integration code. |
| 34 | + |
| 35 | +### Organization |
| 36 | + |
| 37 | +- An organization is a way to organize users. |
| 38 | +- Organizations and users form a N-to-M relationship through what Auth0 calls Membership. |
| 39 | +- Organizations and connections form a N-to-M relationship. This relationship controls what users can belong to a particular organization. |
| 40 | +- There is no relationship between organizations and applications. See above to understand how applications and organizations work together. |
| 41 | + |
| 42 | +## How to do usecase X |
| 43 | + |
| 44 | +This section explains how to do a certain usercase X in Auth0, with an example oriented around a company called FormX having a tenant (also called Formx) on Auth0. |
| 45 | + |
| 46 | +FormX is a SaaS doing form extraction with self-built machine learning models, as well as LLM-powered models. |
| 47 | +It serves both casual end-users like those with a `@gmail.com` email, and enterprise end-users. |
| 48 | + |
| 49 | +### Usecase 1: Different password policies |
| 50 | + |
| 51 | +For casual end-users, FormX does not want to impose a very restrictive password policy on them. |
| 52 | +FormX just wants their casual end-users to have a password of at least 8 characters long. |
| 53 | + |
| 54 | +FormX also serves an enterprise called GreatMall, which require a more restrictive password policy of 16 characters long. |
| 55 | + |
| 56 | +To fulfil this usecase, FormX does |
| 57 | + |
| 58 | +- Create a connection `casual-email-password` to store casual end-users. The password policy is 8 characters long. |
| 59 | +- Create a connection `greatmall-email-password` to store end-users from GreatMall. The password policy is 16 characters long. |
| 60 | +- Create an organization `greatmall`. |
| 61 | + Assign `greatmall-email-password` as the only connection to organization `greatmall`. |
| 62 | + Restrict the email domain of organization `greatmall` to `@greatmall.com`. |
| 63 | + Turn on auto-membership. |
| 64 | + |
| 65 | +### Usecase 2: IAM |
| 66 | + |
| 67 | +Most cloud providers offer IAM to allow their customers to manage IAM users within their account. |
| 68 | + |
| 69 | +In FormX, GreatMall also wants IAM. |
| 70 | +Since in Auth0, connection is already a isolated user pool. This requirement is automatically fuifilled. |
| 71 | + |
| 72 | +### Usecase 3: Enable MFA for some organization |
| 73 | + |
| 74 | +FormX does not want to force their casual end-users to enroll MFA mandatorily. |
| 75 | +However, GreatMall requires all of its employee to enable MFA when its employee sign in subprocessor services like FormX. |
| 76 | + |
| 77 | +In Auth0, MFA is a tenant-wise option which cannot be turned on and off for a particular connection, application, nor organization. |
| 78 | +To implement this requirement, FormX has to use Auth0 post-login action to dynamically require MFA when the end-user is signing in to GreatMALL. |
| 79 | + |
| 80 | +### Usecase 4: Invitation |
| 81 | + |
| 82 | +One of the common usecase of organization is to invite someone in the organization to join it. |
| 83 | +Often, the invitation is in form of an email with a link to sign in. |
| 84 | +When the end-user signs in with the link, the end-user joins the organization automatically, and be redirected to a application to continue their journey. |
| 85 | + |
| 86 | +In Auth0, to create an invitation to an organization, one must select an application. |
| 87 | +If the application does not have `initiate_login_uri` configured, the invitation CANNOT be created. |
| 88 | +This means FormX must first implement `initiate_login_uri` before they can use the invitation feature. |
| 89 | +The details are documented in https://auth0.com/docs/authenticate/login/auth0-universal-login/configure-default-login-routes and https://auth0.com/docs/authenticate/login/auth0-universal-login/configure-default-login-routes#invite-organization-members. |
| 90 | + |
| 91 | +> [!WARNING] |
| 92 | +> Implication on Authgear |
| 93 | +> This means https://openid.net/specs/openid-connect-core-1_0.html#ThirdPartyInitiatedLogin is a pre-requisite of organization. We must first implement that before we work on supporting organization. |
| 94 | +
|
| 95 | +### Usecase 5: Email discovery |
| 96 | + |
| 97 | +FormX has a lot of enterprise customers, not just GreatMall. |
| 98 | +FormX wants the sign-in page to show a single email input, |
| 99 | +and depending on what the end-user enters, select the organization, |
| 100 | +and possibly redirect the end-user to the configured enterprise connection, like Azure Entra ID. |
| 101 | + |
| 102 | +This can be implemented with [Identifier First Authentication](https://auth0.com/docs/authenticate/login/auth0-universal-login/identifier-first) and [Home Realm Discovery](https://auth0.com/docs/authenticate/login/auth0-universal-login/identifier-first#define-home-realm-discovery-identity-providers) |
| 103 | + |
| 104 | +### Usecase 6: Organization switcher |
| 105 | + |
| 106 | +FormX has another enterprise customer called GreatProperty, who is onf of the leading property developer in the city. |
| 107 | +GreatProperty has many contractors. GreatProperty and its contractors deal with a lot of textual documents. |
| 108 | + |
| 109 | +An employee of GreatProperty `johndoe@greatproperty.com` of course belong to the organization `greatproperty`. |
| 110 | +He also belongs one of the contractor GreatContractor, represented by the organization `greatcontractor`. |
| 111 | + |
| 112 | +In the daily work of `johndoe@greatproperty.com`, he needs to work on both the documents of GreatProperty and GreatContractor. |
| 113 | +So he needs to be able to switch between the two organizations. |
| 114 | + |
| 115 | +In Auth0, switching between organizations is not supported natively. During sign-in, the organization is provided via |
| 116 | +- With "Login Flow" being "Prompt for Credentials", Auth0 asks the end-user just before the authentication finishes. |
| 117 | +- With "Login Flow" being "Prompt for Organization", the end-user provides it. |
| 118 | +- With "Login Flow" being "No prompt", the application developer provide it in the integration code. |
| 119 | + |
| 120 | +In either case, the sign-in is specific to the 1 organization only. |
| 121 | + |
| 122 | +To support organization switcher, the application developer has to implement themselves. |
| 123 | + |
| 124 | +> [!NOTE] |
| 125 | +> I didn't dig into how to do this exactly. But I believe this is do-able. |
| 126 | +
|
| 127 | +## Caveats |
| 128 | + |
| 129 | +This section documents the known caveats around organization in Auth0. |
| 130 | + |
| 131 | +### Caveat 1: Resolution to ambiguous account |
| 132 | + |
| 133 | +This caveat is caused by an organization can have more than 1 connections, and email addresses are NOT unique across different connections. |
| 134 | + |
| 135 | +It is better to explain this with a concrete example so |
| 136 | + |
| 137 | +- Connection `email-password-1` |
| 138 | + - User `johndoe@example.com` |
| 139 | +- Connection `email-password-2` |
| 140 | + - user `johndoe@example.com` |
| 141 | +- Org `org1` |
| 142 | + - Connection `email-password-1` |
| 143 | + - Members |
| 144 | + - `johndoe@example.com` from `email-password-1`. |
| 145 | +- Org `org2` |
| 146 | + - Connection `email-password-2` |
| 147 | + - Members |
| 148 | + - `johndoe@example.com` from `email-password-2`. |
| 149 | +- Application `myspa` |
| 150 | + - "Login Experience" set to `Business Users` with "Login Flow" being `Prompt for Credentials`. |
| 151 | + |
| 152 | +The end-user (owner of the email `johndoe@example.com`) enters his email in the Auth0 sign-in page. |
| 153 | +He will either sign in `johndoe@example.com` from `email-password-1` or `johndoe@example.com` from `email-password-2`. |
| 154 | +Which one will be used is not documented by Auth0. |
| 155 | +But by observation, the resolution is consistent. |
| 156 | +In my own testing, Auth0 always resolves to `johndoe@example.com` from `email-password-1`. |
| 157 | +So if I enter the password of `johndoe@example.com` from `email-password-2`, Auth0 will tell me the password is incorrect. |
| 158 | + |
| 159 | +To avoid this, it is your own responsibility to make sure the end-users identifier within an organization NEVER overlap. |
0 commit comments