Help with b2b multi-tenant SPA & multi product APIs

Hi @mathiasconradt. I found your answer in this post about possible ways to go about implementing multi tenancy for that scenario quite helpful!
However I still have doubts/questions, possibly due to my use case being slightly different. I wanted to know if you could give me a hand in modeling a possible solution and flow to accomplish it.

Let me start with a bit of context. I will try to explain as clear as possible:
We have multiple APIs mapped in Auth0 each one of them being a completely different Product (api_1, api_2, …) that customer organisations can buy separately or in combination. These APIs can be accessed directly by M2M clients or be consumable by users via an SPA that we have.
For each API there are roles with their associated permissions: USER_PRODUCT_API_1, ADMIN_PRODUCT_API_1, USER_PRODUCT_API_2 and so on.

A user could belong to multiple organisations. Also this user might have different roles in each organisation. I understand this can only me mapped through his/her app_metadata (and not through through the normal dashboard) right ?, something like:

{
  "tenants": [
    {
      "name": "org_1",
      "roles": [ "USER_PRODUCT_API_1", "USER_PRODUCT_API_2" ]
    },
    {
      "name": "org_2",
      "roles": [ "ADMIN_PRODUCT_API_1" ]
    }
  ]
}

Then, to model we would most likely have an SPA app per organisation and 1 database connection for all users. We would map in each SPA app metadata which Products that organisation has access to. (correct me otherwise if other approach based on the above is recommended)

So how would we then do the following:

  • user logs in and
  • he is presented with the choice to select one of the organisations he belongs to (or not if only one)
  • the SPA then requests tokens only for authorised API audiences (those associated with the organisation)
  • for each audience token request the correct role should be applied:
    if user selected org_1 then permissions associated with USER_PRODUCT_API_1 should be put in the token when requesting token for audience PRODUCT_API_1
  • each access token is enriched with further information regarding the organisation chosen (e.g. which datasets this organisation can see based on a call to an external service)
  • the SPA makes requests to the respective APIs with their respective token.

to correctly log in and authorise a user to interact via our SPA with all the different products and correct permissions respectively ?

Thanks in advance for your help.

Gerardo.

Hi @gerardo.zenobi,

We have multiple APIs mapped in Auth0 each one of them being a completely different Product

Note that an access token can only be issued for one audience (API), if you register them as separate APIs in Auth0.
An option is to represent them as one logical API.
See Configure Logical API for Multiple APIs

But I think you’re already aware of it, since you used plural here when you said:

the SPA then requests tokens only for authorised API audiences (those associated with the organisation)

Just to let you know that we have a docs page around that (see above).


I understand this can only me mapped through his/her app_metadata (and not through through the normal dashboard) right ?

As of today, that’s right. There’s no concept or groups or organisations available to the public yet, however note that we’re working on an concept of “organizations” as part of our RBAC (role-based access control) approach.
This is planned for sometime in Q2.

Until then, using the app_metadata is a valid approach, and then handle it accordingly in a Rule for example.

each access token is enriched with further information regarding the organisation chosen (e.g. which datasets this organisation can see based on a call to an external service)

Yes, you could i.e. add permissions as custom claims into the ID and/or access token via Rule.


Just to give you an idea what it could look like with groups/organisations available in the future:

There are Roles as you know them…

and Groups/Orgs available, which I created as org1_admins, org1_users, etc. to which you can assign users…

where these groups have the roles assigned based on the products the org purchased.

To each role, there are permissions assigned as per our RBAC approach.

Note that above screenshots are from my own internal test tenant, the RBAC Groups aren’t publicly available today in tenants.

Hi @mathiasconradt, thanks for the rapid response ! Although it is still unclear to me how to go about to implement the scenario.

I wouldn’t be able to implement something similar to Option C (from the original post) since in my case, due to the fact that the roles depend on the organisation selected, it will have to be always a multiple step process: meaning I think I am forced to use what you referenced as Redirect Rules unless going for a different option like Option A for example.

Then:

If going with Option D (1 SPA app, no subdomains):

  • user logs in, we validate credentials, check the his/her app_metadata to see which orgs he/she belongs to and we redirect to custom UI for him/her to select an organisation. do we pass the organisations as a custom claim in the Id Token or what gets passed to this custom UI ?
  • user selects the organisation; authorisation flow continues ( /continue ): the selected org value is feed then to the rules engine, how is it passed? also, are we still only talking about ID Token here?
  • user is logged in within the SPA and the SPA has received an ID Token (maybe with a claim about the chosen organisation)
  • how do the, later on initiated by the SPA, access token requests behave within this scenario? This is the part I am confused as I can’t imagine how a Rule would have access to the organisation selected before since they are not part of the /continue flow. Since roles are by organisation we need this information in order to produce the access token.

If going with Option A (1 SPA app per organisations, subdomains to manage client id):

is the following more or less correct?

  • user logs in through via a particular subdomain providing the /authorise endpoint with the proper client id. Organisation is then pre-selected and we have access to it during Rules.
  • SPA receives within the ID Token the API audiences this SPA should request access token for.
  • SPA can requests access tokens for the APIs: a Rule has access to the client_id and retrieve the roles associated with the respective organisation from the user app_metadata. (?) Do we need to translate them manually into permissions and create the appropriate scope ?
  • SPA receives access tokens and calls APIs.

In order to implement option A it is mandatory, and entirely on our side, to manage subdomains (customerX.app.com) to track each client id correct ? or is there other alternative I am missing ?

Thanks again,

Gerardo.

Hi @mathiasconradt, not sure if you might have missed my response to your answer.

If you have some time I would appreciate your help :slight_smile:

Thanks in advance,

Gerardo.

Update

I managed to implement Option D. After credentials have been validated the user is asked to select a tenant if he/she belongs to many (done through Redirect rule). As a result all subsequent /authorise calls when requesting for ID and/or access tokens have as a query parameter the organisation the user is in at the moment. This is used to manually convert organisation roles into permissions within Rules.

  • Does this sound OK ? no security concerns regarding sending the org query param ?

However for Option A (1 SPA app per organisations, subdomains to manage client id):

  • any ideas how it would be possible to perform this organisation selection ? or is it not possible at all given we don’t know which ones are available before user has provided credentials ? He/she would have to land directly on the tenant vanity url ?
  • is it is mandatory, and entirely on our side, to manage subdomains (customerX.app.com) in order to identify each tenant application? or is this partly/fully managed by Auth0 and if so how?

Thanks in advance.

Gerardo.

Hey @gerardo.zenobi, did you manage to get an answer for option D?

Hi Martin,

No, unfortunately I didn’t get any answer.

Specifically what were you after, just the answer to:

Does this sound OK ? no security concerns regarding sending the org query param ?

or you had a different question ?

Regards,

Gerardo.