Usually, JWT implementations in a REST Api backend save the user roles and/or permissions inside the JWT token claims. In this cases, clients make use of this claims to restrict user's interaction with some of the app features.
There are some user, or server, actions that update the user's authorization roles/permissions. However, the last emitted JWT token has not expired yet so it still has the old roles/permissions in it's claims.
How do you or your team handle this scenarios in order to update user's authorization in client side apps?
I've seen many options out there:
- Create a token version and update it in server side to compare with new request
- Keep token lifetime short
- Use refresh token mechanism and invalidate the user's current token
I want to hear you...















If you need to know whether the user's permission changed before processing every request, then you will have to look up the information on every request, which is going to increase your latency. There's no way around it. To mitigate the increased latency, you can use something like Redis (memory-based DB cluster) to store the current user permissions so that lookups are fast. (You could also try more complicated solutions like a pub/sub notification on user changes. But this seems like really a high burden of proof of need vs complexity.)
Having the permission changes immediately reflected always costs something. Even before JWT existed, this was a known issue, so security frameworks would cache the permissions for a period of time. This led to the same issue of the user continuing to have the old permissions until the cache expired. You can look at the JWT as a cache.
The larger question is: how important is it that permission changes are immediate? For us, it is not that important. For scenarios like deactivating a user or changing user permissions, we inform the users that it may take up to an hour to take effect (which is the token/cache lifetime). Under extreme situations, like an active attack, there are nuclear options like changing signing key (so all of the existing tokens are invalidated) or shutting down the attacked service.
Lastly, I want to say that for our latest app, we have gone to a model where we no longer keep permission claims in the JWT. We keep the permission in our own database and after we read them for a particular user we cache it for a (configurable) period of time to amortize the latency cost. We do this for a couple of reasons. One is that the JWT size kept increasing as our app features increased. And it had to be sent on every request. Two is that it was awkward to manage user permissions through our auth provider, especially if we want to expose them to users to manage themselves. Ultimately we went for a scenario where the auth provider knows almost nothing about the user. It only handles the hard (or uninteresting) problems: auth, password storage, token issuance, forgot password, etc. When we create the user in the auth provider, we attach their ID to our own user. So when the token comes in, we can lookup our user permissions from their ID.