My understanding was that they're supposed to only last on the order of 5-10 minutes, with a fresh one created for the next set of requests instead of reusing one JWT for days. Is revocation still an issue with the expiry so short?
In general, I tend to look at token trust as a decaying function of time, irrespective of signatures.
This is why people suggest "short tokens" as a work-around, accepting a 5min window of unrevokable tokens as trade-off.
Or, one has to justify that a blacklist implementation is significantly cheaper than a whitelist one. But is it, really?
In my experience, usage of the black list occurred with two use cases:
1) Invalidating all of a user's tokens 2) Alteration of claims that a user's JWT should have
As far as your applications go, you still have the benefit of not having to bother with checking the state (this is already done by the gateway).
On the other hand, you generally expect that you rarely ever need to actually revoke tokens, so you can naturally expect that a blacklist will change infrequently and will remain tiny compared to the whitelist.
As the size of the service grows, most people converge to a fast train/slow train design: the whitelist is big and is accessed infrequently, and the blacklist is tiny (goes obsolete within the TTL of the whitelist query) and can be pushed out quickly.
If you're one of the tech giants, it's not slightly cheaper, it's a lot cheaper.
however, once you really care about the security perimeter, i think the requirement/wish "stateless" must be dropped.
One of the biggest challenges with using JWTs is really all these gotchas that you have to think about. This isn't dissimilar to the infamous `alg:none` fiasco. In this case, it's not really about protecting against an attack, but forcing the developer on the other end to think about it. Their quick initial code that doesn't bother setting exp or has it hard-coded to 1000 years in the future will never work, so it had less chance of being left in to cause a security issue later.
Wasn't the question about using them for auth, not application state?
In general authentication/authorization isn’t just a binary in or out. For example, you might have to reauthenticate to access password or 2FA settings in your account, so now you have multiple authenticated states. So I made my comment from the assumption that you probably need to decorate the user’s authentication “state” with extra information for your service. In those cases, I was suggesting to only carry that info in the token if you need to cross service boundaries with it, such as if you have multiple front end micro services operating on independent data stores.
In more words, if you need to carry application state and you haven't outgrown the simple database cluster, then just use the tried and true formula of carrying state via SQL database. Pretty much every engineer these days understands how the architecture works, it's fast and reliable due to the sheer maturity of the components involved, and you don't add cryptography and maliciously crafted input attack surfaces to your auth system (see the recent talk at BlackHat 2019 about Outlook accepting unverified auth tokens). In this case using a predictable and mature approach is a good thing.
On the other hand, JWT's work well for (1) federated authentication, though revocation is still hard, and (2) carrying authorization claims. The reason is that these aren't state in the sense of application state. They're attestations of an existing fact and you're using the signature mechanism to let one service trust another without having to talk directly to each other or to protect any shared secrets. You need to send signed payloads containing user ID's and lists of claims anyway, and JWT's meet those requirements pretty well.