Dynamic scopes: parameterized

Hello,

In my application, i have different rooms (dynamically created), in which users should have different permissions. For example: in room_1, user_1 can add comments, but user_2 can only read comments.

To set this up: I added the roles of each user for each room in app_metadata using the management API. I now need to dynamically add scopes to access token for example: create:comments-in-room_1, based on

  1. The roles i set up in app_metadata for the corresponding room
  2. The room setting that can be imported from another microservice (which says for example: members can read comments, admins can add comments, …).

How can i do so ? maybe using flows ?

Or should I do things differently ?

I guess it should be a common task but I couldn’t figure out how to do so.

Thanks a lot for your help,
Regards,
Quentin

@rueben.tiow @dan.woda Sorry for mentioning you, but I really need an answer on that question and I saw you are active responders in the auth0 Community. Thanks a lot for your help !

Hello @konrad.sopala ! Sorry for mentioning you this way but I need an answer rapidly on this question as I 'm currently blocked. I need to know the best way to manage this challenge. Thanks a lot for your help. :pray:

Hi,

Based on ChatGPT and other forum questions / answers I came to a potential solution. Please can you take the time, @konrad.sopala, @rueben.tiow, @dan.woda or anyone else, to confirm or correct this solution ?

  1. Add the role of the user for each space in the app_metadata. (using the Management API called from my app API). Here is my code:
import {ManagementClient} from "auth0";
import {AuthConfig} from "../configs/auth.config";

const authManagementAPI: ManagementClient = new ManagementClient({
    domain: AuthConfig.domain,
    clientId: AuthConfig.clientId,
    clientSecret: AuthConfig.clientSecret,
    audience: AuthConfig.audience,
    scope: '...',
});

await authManagementAPI.updateUser({id: authSub}, {app_metadata: {["spaces/" + spaceAlias]: {spaceId: spaceId, role:"admin", userId: null}}});

  1. In my frontend app (react), I use in the Auth0 Provider a custom parameter called “spaceAlias”, that i also use in my “getAccessTokenSilently” calls:
   <Auth0Provider
      domain={domain}
      clientId={clientId}
      authorizationParams={{
        redirect_uri: redirectUri,
        audience: AuthConfig.audience,
        scope: AuthConfig.scopes,
        spaceAlias: "my-room-alias"

      }}
      onRedirectCallback={onRedirectCallback}
      cacheLocation="localstorage"
    >
  1. Add a flow action that add the desired parameterized scopes to each access token based on the app-metadata, and the queried spaceAlias. (From what I saw (Manipulate scopes for ID and Access Tokens using Actions GA), it’s not possible in actions to add parameterized scopes, which is sad… and hopefully it will be changed, as of now, is it safe then to add the parameterized scopes to a custom claim ? ).
exports.onExecutePostLogin = async (event, api) => {
    const spaceAlias = event.request.query.spaceAlias;

    if(spaceAlias){
        const spaceMetadata = event.user.app_metadata[`spaces/${spaceAlias}`]
        if(spaceMetadata && spaceMetadata.role && spaceMetadata.spaceId){

            // later: fetch from permissions api
            const scopesPermissions = {
                "member" : (spaceId)=> `add:comments-in-${spaceId} request:changes-in-${spaceId}`,
                "admin" : (spaceId)=> `add:comments-in-${spaceId} make:changes-in-${spaceId} delete:comments-in-${spaceId}`,
            }
            
            const customScopes = scopesPermissions[spaceMetadata.role](spaceMetadata.spaceId);
            api.accessToken.setCustomClaim(`https://my-apis/customScopes`, customScopes);
        }
    }

};
  1. In my api, i cannot use requiredScopes(“add:comments-in-550e8400-e29b-41d4-a716-446655440000”) as my custom scopes are not in scopes, so I made my own “requiredCustomScopes” function.

This solution has several limitations as, for instance, I do not benefit from all the scopes advantages, but is there any better solution ? And if not, is my solution still safe ?

Thank you for your time and hopefully this response will help others …