Don't blacklist, use shorter lived tokens and have the client refresh as needed. A 10-15m token is plenty long life and not so long as it's a huge risk window, more than even a shorter window,.
Stakeholder: “so you are saying that after a user is denied access they can still access the resources?”
Dev: “yes, but only for 15 minutes. Also, it makes our system more simple and decreases database calls, increase performance, ...”
Stakeholder: “nope”
"Authentication takes a few minutes to replicate throughout our systems so a SLO request should be resolved within a few minutes". Stakeholder: Ok sounds good
+1 on this... it can be up to a 30 minute lag in some orgs... oh, you have access to those systems for a while until things sync up... similar for LDAP/AD sync with Nix/windows.
Which makes sense when I think about how some of the more trigger happy orgs made a point of shutting peoples accounts of as they were being walked into a room...
For parts of the site where you need to boot somebody instantly... just hit up the authentication server on every request to validate the session. For parts of the site where it doesn’t matter so much, wait for the token to expire....
I did exactly this on the last implementation of JWT I did. Common actions wouldn’t hit the database if the token was less than an hour old, but actions like changing email address or password would always check the database.
Usually in one of those scenarios, you will try to hold, say a fired employee for that long in order to deactivate all their accounts and access anyway... in reality it's not much of an increased risk...
You still could blacklist, but realistically most areas don't need a dedicated revocation check. Some critical areas might, depending on the space.
So where do you store the ones that should not allow to be refreshed? How short lived they should be in case of "Reset Password" scenario, when you need to kick out malicious user?
You can still do a redis or memcached, or even an rdbms table for that matter on revoked tokens... and do a lookup for critical systems... You don't need to do that on EVERY request though. It's really not less difficult than a session server/service/database, and more likely to scale better.
that's the whole point. That's the trade off you make, you DON'T implement those features. When you need that, it doesn't make sense to use JWT. Right tools for the right job...
But isn't the requirement for using the refresh token that it must be kept secure? For example, if you users authenticate in a browser, they get back an access token and a refresh token. If that refresh token were stolen on the wire or from within the browser, how would you prevent someone from using that refresh token perpetually if you're not blacklisting?
This is essentially an inverse blacklist (aka refresh token whitelist) which requires server-side state. The part that these things seem to miss in my mind, especially in situations where security requirements are high, is that the authentication process is equivalent to the refresh process.
For example, you can have a complicated authentication process where you require a password, 2FA, etc. These things help ensure that the user is that user. But once that process completes, it is replaced with access_token+refresh_token. Any user can take those item and impersonate that user. Attempts to lock this down require server-side state with the ability to revoke stolen tokens if detected.
Don't get me wrong, the same issues arise if you were using cookie-based session id's or the equivalent. But once you're doing this stateful token stuff, there appears to be a lot of additional complexity without a lot of additional benefit over the traditional way.
However, if you aren't worried about this level of security, there is clearly a benefit to using this newer style.