Help With Multi-Tenant SPA/REST Application

I’m hoping people can help with the structure of my application.

I want to create a SPA & REST API. The registration will be handled by the SPA. When a user signs up, both an organization and user record will be created in Postgres. A user will also be created in Auth0.

The tricky part is a User can belong to many Organizations and an Organization can have many Users. So for example, a single individual, lets say “joe@example.com”, can belong to both “ABC Inc” and “XYZ Travel.”

Pre or Post Sign In, I would like the User to CHOOSE an organization they want to sign in as.

Do either of these sound possible, if so how would it be structured in Auth0:

  1. Different subdomains are created per Organization. Each subdomain would represent a different Application in Auth0 (So their client ID’s are different) When a user logs in via Universal Login, the Organization ID belonging to that Client ID is returned in the JWT. Any calls to the REST API will have 1 Organization in the JWT.

  2. (prefer this option) A single domain takes users to the Universal Login page. After the user successfully authenticates, the user can choose “ABC Inc” or “XYZ Travel.” The organization choice is added to the JWT somehow, so any calls to the REST API will have 1 Organization in the JWT.

Hopefully this makes sense. Any help is appreciated.

There are different options to decide which organization a user wants to work on.

Option A

Your mentioned option 1. is a valid choice, but if you don’t like the subdomain approach, here are the others.


Option B

In case of a single domain, let him select the organization via input field, similar to what Slack is doing (that’s not Auth0, but just to give you an example):

This would work, the effect is similar using a subdomain. You let the user preselect, however, a text input field isn’t that user-friendly, and you also don’t want to use a pre-filled drop down list revealing all the organizations in your system.
So, while an input field is an option, it’s still not the best imo.


Option C

This one here would be my preference - a bit similar to your option 2 but not exactly:

Let the user login first via single domain, include the organizations of which the user is a member of as custom claims in the JWT (ID Token).

For this, you could actually consider using RBAC (Role Based Access Control) and use group or roles to assign the organization to the user. I would actually suggest this approach.

So you would create different roles (org1, org2, org3, etc.) and respective permissions assigned to these roles (permission_org1, permission_org2, etc.). Remember to enable RBAC in the API registered in Auth0.

So, after the user has logged in to your application and you got the ID token, check the roles within the JWT and offer the user a choice via a UI/drop down list in which context he wants to work right now. This context switcher can happen entirely within your application.

I don’t see a need to use different JWT and also a need to add this org selection to a JWT. Based on the current context selected in your application, the calls to your backend API will contain the currently selected organization in each request (via request parameter, header, anything of your choice).
So, the JWT (access token) that the user has can be used in all contexts / for all organizations for which the user is a member of. You can validate the permissions in your backend based on the JWT permissions claim.

However, the choice for which organization the current API request is meant to be can be based simply on a request parameter or header, doesn’t have to based on a JWT claim. I also don’t see a security issue there.

This approach is imo the easiest.


Option D

If you prefer your original option 2 and want to get a separate JWT for each organization that a user is a member of, you can use Redirect Rules and a page you put in between for the user to select the organization. Based on his selection, you’d put his selected organization as custom claim in the JWT.


Here are some general resources on multi-tenancy:

3 Likes

Thank you for your detailed response. I’m reviewing your options now.

1 Like

First, your post has been tremendously helpful. Thank you.

I do have 1 question. You said “check the roles within the JWT.” I’m not seeing a way to add roles into the JWT. I’m only seeing the ability to add permissions. This is what I see in the JWT returned from Auth0.

 permissions: [ 'abc_inc', 'xyz_travel' ]

RBAC is enabled as well as “Add Permissions in the Access Token”. Did you perhaps mean to say to check the permissions within the JWT?

1 Like

Yes, you are right. I was first thinking of using roles, but then remembered that RBAC only automatically adds permissions but not roles to the JWT.
So, while it’s possible to also add roles to a JWT via a Rule, it’s an unnecessary step, since you can as well just rely on the permissions (if you semantically set them up in the same way: “permissions_org1” belongs to role “org1”, “permissions_org2” belongs to role “org2”, etc.).

So, yes, just go with permissions; outcome is the same in the end.

Right. Understood. Thank you again. You helped me so much.

1 Like

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.