3 ms·
This is a good article! fusionauth looks cool =) Here are some things to consider though (I work on this problem a lotttt): 1. Do you (as the app developer) r
by rdegges 8y ago
This is a good article! fusionauth looks cool =)
Here are some things to consider though (I work on this problem a lotttt):
1. Do you (as the app developer) really care about security that much? If not, just go with local validation on your JWTs and understand that there is a window of time, whatever your token lifetime is, that you will be at risk for compromise and abuse. If you do care, continue down the list, if not, just don't worry about it.
2. So you care about security, yey! Now, your problem is this: what level of risk are you OK with? If you're ok with NO risk, continue reading. Otherwise: set your JWT expiration time to the amount of risk you're ok with. EG: 1 minute, 5 minute, 1 hour, 1 day, etc.
3. OK! So you're REALLY serious about security and want no risk. Now we're talking! You really only have one choice: validate your JWTs centrally to ensure that a user hasn't been deleted, token revoked, etc. But now you have to decide the best way to do this! Here are your options:
A) You can validate tokens centrally on every request with the IdP: this is basically the same thing as normal old session management: you check the session against a DB to validate it.
B) You create a cache of tokens that are blacklisted (aka: a blacklist), so that you can do an O(1) lookup to see if a token is expired. The only problem? This is usually centralized, too! So no real benefit over option (A) except that it's a bit quicker (if you don't make mistakes w/ cache invalidation, etc.).
C) You do what this article talks about: you distribute your blacklist directly to your edges: one way to do this is with webhooks, websockets, or really just about any method of syncing data between places. This is a great approach, but unfortunately, a lot more can go wrong: what if your webhook doesn't get processed quickly enough? What if your client breaks and stops being able to accept webhooks? What if the webhook server stops firing or gets overloaded?
In my personal opinion, (A) is the best choice, because it's the simplest, the hardest to get wrong, and can always be cached to speed things up. The only problem with (A)? The only problem is that if you're doing it this way, why use a JWT at all? Why not just use a normal old cryptographically signed session ID? Not much benefit, IMO.
- brokenwren 8y agoYeah, we work on this issue all the time as well and see all of these solutions (and others). I agree that (A) definitely feels like sessions. However, I disagree that (C) is error prone. Here are answers to your questions on (C) plus how FusionAuth does it: > what if your webhook doesn't get processed quickly enough? I'm assuming you mean at the edges. This is possible, but if you are on the same backplane, highly unlikely since our solution is simply inserting an int into a Hash. Even if it isn't backplane, then you still can retry. Think of session caches as the same situation, so really no difference if you have a distributed cache for (A). Also, FusionAuth provides configurable timeouts and transactions for Webhooks. This covers most failure cases. > What if your client breaks and stops being able to accept webhooks? I'm assuming you mean "service" rather than "client" since we want the services to know a JWT has been revoked. I'd say this should hopefully mean that the service is also not accepting API requests. If it is, then you will have issues. However, this is a failure case no matter what. Similarly, the client breaks and stops validating the JWT in (A), you are in the same situation. Plus, FusionAuth provides transactional Webhooks, so you can retry and protect against failures. > What if the webhook server stops firing or gets overloaded? Since FusionAuth is the Webhook event generator and the IdP, if it stops, you got bigger issues. :) In terms of overloading, we protect against event backlogs and failures pretty well. We can also shut the entire node down if needed to prevent any API calls. This is a bit brute force, but if you are in #3 for security, turning everything off is better than a breach.
- nunjee 8y agoWhen dealing with cloud identity providers like AWS Cognito or Firebase and the likes, the option A is actually the most quick to implement. It's centralized for sure and not that fast, you are basically left with a JWT that acts as a session but you don't have to think about that much, it brings an ok level of security.
- jgalentine007 8y agoAfter toying with JWTs for sometime I went back to sessions myself. The best use case I could think of for JWTs is where you need to relay claims between two disjoint systems. Or have extreme scale and load balancing could become an issue. Beyond the trivial JWT implementations, trying to figure out how to persist JWTs (stay logged in) and revoke access immediately got way more complicated than it needed to be when a lot frameworks already have sessions implemented and secured properly for a good while now.
- jiveturkey 8y agobrilliant reply. you covered it top-to-bottom. usually people will gloss over or neglect something. You didn't cover the case (2.5) where you make a best effort to invalidate immediately, but don't need absolute guarantee of that as long as you know it will be eventually consistent, where 'eventually' is bounded. This relaxation of requirements can be liberating. Didn't read TFA, but another way to distribute the blacklist to the edge is to return it along with other data. This isn't going to be a portable library or subsystem, if it works at all it depends very much on your arch and it will be custom. > why use a JWT at all because the JWT can carry other information, eg authz, in a portable way and that can be consumed by other backends. the portability of the JWT may also allow for much easier debugging. why not use a JWT? there's no disadvantage if you just process it like a normal signed session ID.
- rdegges 8y agoThe only disadvantage is that: 1. You are now passing large blobs of data over the network more frequently than just a signed session ID 2. If you want to ensure consistency of your data (for security purposes), that extra data embedded in the claims of the JWT are useless since you need to query for them for freshness after validating the session anyway.