Search code examples
authorizationuser-permissions

supertokens revoke other users active sessions


I have a webapp that manages authorization and user roles via supertokens. When a session is initialized the app reads user role from database and passes it to supertokens role initialization.

Some users are admins and they may change the roles of other users. When the role of another user is changed I would like to revoke their active sessions, or change their role. This needs to take place immediately, even if the user has active sessions, so changing their roles in my database is not enough.

I know that supertokens have an open issue about "Define DB schema and APIs for UserRoles". Yet, I would expect that there would be some way to revoke active sessions of other users with their current structure.

Any help or explanation about how this might be approached will be appreciated.


Solution

  • First, some info about how the sessions for SuperTokens works:

    • An access token is issue which contains the payload (which has the user's role you added). The access token's verification is stateless (by default).

    • A refresh token is issued which is used to get a new access & refresh token when the existing access token expires.

    Now, when you change a user's role, you want to propagate that change to all of their sessions. The backend SDK provided by SuperTokens has functions for that. For example, if you are using NodeJS, you can do something like:

    let sessionHandles = await Session.getAllSessionHandlesForUser(userId);
    
    // we update all the session's Access Token payloads for this user
    sessionHandles.forEach(async (handle) => {
        let currAccessTokenPayload = (await Session.getSessionInformation(handle)).accessTokenPayload;
    
        await Session.updateAccessTokenPayload(handle,
                { role: "newRole", ...currAccessTokenPayload }
        );
    })
    

    Since we are changing the contents of the access token of another session, that session will only know about this after it has refreshed. So by default, there will be a delay in the propagation of this role change for that user.

    So here are your options for solving this issue:

    • Reduce the access token lifetime. This way, sessions are refreshed more often and the propagation of role change can happen more quickly.
    • Enable access token blacklisting. This can be done via the core's config.yaml setting (access_token_blacklisting: true flag). If you are using docker, you can pass ACCESS_TOKEN_BLACKLISTING=true. Through this setting, each session verification will query the core and if there is a change in the access token's payload, that will get reflected immediately. The downside to this is that session verification will not be slower due to extra network calls.

    Finally, there are hybrid approaches that you can implement yourself:

    Maintain a cache (on your own) of changes to roles and during session verification, add a middleware (after verifySession runs) to check your cache. If the role for the current user has changed, return a 401 to the frontend forcing it to refresh the session resulting in the access token's payload being updated immediately.

    Hope this helps!