You're getting refresh token using credentials (e.g. login/password). Refresh token is long-lived and basically allows you to use service without typing login/password every 5 minutes. How much refresh token should live depends on your security requirements to how long user can user your service without typing his password.
You're getting access token using refresh token. This allows server to check whether you've been banned or something like that. If you encode access permissions into access token, it also allows to adjust those permissions. So your access token lifetime is a balance between performance and security.
If your API already uses some kind of service key, then refresh token does not make much sense (may be it does to provide uniform implementation for web clients and service clients, but not from security perspective).
My opinion is that all those things are more complicated than necessary. You could use the same token both for access and refresh purposes (if token is outdated, check it using database and return new token, then client will use new token for subsequent requests).
If the user is expected to use a programming language and hit the API many times a second, then even a short expiration and moderate refresh really help (might fully authenticate every 5 mins, which could be thousands of requests for some APIs).
1. You can check for user changes when the refresh token is used and a new access token is requested (user deleted, permissions changed, access revoked)
2. Refreshes can go to a different endpoint, whereas access tokens could be used with services that don’t even have access to user auth services.
Edit: There is something to be said for ditching the refresh token and just re-authenticating when the access token expires. The benefit is that you don’t need to store the username/password in the client code to re-auth, and you might avoid some relatively expensive password checking on the server, but that is probably pretty minor.
Not guaranteed for the lifetime of refresh tokens, which is the case for access tokens.
> whats the difference?
A 5 min access token is valid for 5 minutes. A 5 minute refresh token can be revoked before its even used.
If you've just got one service endpoint, it doesn't buy you very much. Just mint a session token and be done with it.
The design philosophy seems to be, use short-lived security credential A (the jwt) for all of your requests, which (again, _theoretically_) risks its exposure, and have a Security Credential B that you keep very secure, and use that to create new instances of Security Credential A.
If SC-A were a cookie and SC-B were kept in a hardware store, then I think this might be logical, but where they're both basically cookies, it seems kind of crazy to me, too. Maybe there are some details in how the actual storage of the cookies varies, but I think it's Hopium all the way down.
By contrast, refresh tokens go to the auth server that can do whatever checks are necessary to make sure the user is still allowed to use the service. This would typically incur DB lookups and require more complex auth logic than simply validating "yeah, this JWT is legit and still in-date".
No. Focus on “token” instead of “JWT.” JWT is just a standard.
As I understand it, de-centralized verification isn't a necessary characteristic of a JWT. There are token constructions that make that a priority, however[0].
Those downstream services can then perform all their authorisation checks using just the JWTs alone. They don’t need to reach out to the authentication service to validate them, or lookup permissions, that’s already happened upstream. If those downstream services need to call other services, they can just pass along the JWT, and it allows the next service to validate the request is performing an allowed operation, without having to contact the auth service, or perform user lookups etc to determine what’s a valid operation. It’s all encoded in the passed along JWT.
There’s also security advantages because the issuing and primary validation of JWTs can be isolated to a single well vetted service, that has very limited connectivity, and every other service uses JWT validation with public keys to perform permission checking, rather than endless user auth lookups. Those service would also have to contact your central auth service to get new JWTs issued, ensuring there’s only a single place in your infrastructure that holds the sensitive private signing keys, and has the ability to issue new tokens. Which means you have a single gatekeeper that determines what types of tokens other services can access, allowing you to enforce limits on those services, even if they don’t cooperate (maybe they’re owned by a different team). It also provides a central location to limiting the blast radius of compromises, you can mass invalidate tokens with cooperation from other services, and stop issuing new tokens to services that might be compromised.
Ultimately JWTs shouldn’t be used for “efficiency” or “performance”, but rather as a tool that allows you segregate sensitive authentication and authorisation infrastructure from all your other services, and prevent “normal” services from adding ad-hoc authentication and authorisation capabilities in way that’s hard to audit or control, without limiting their ability to enforce authorisation requirements.
JWT is a format for tokens, it's not a choice between JWT and opaque tokens, as JWT can be opaque and transparent tokens can be in another format.
JWT just happens to be a format with good support in javascript. As a format, it's quite unremarkable, but as a standard it's a complete piece of shit where footguns abound. Anyway, it's easy to work with, while the alternatives tend to have the opposite features, being incredibly hard to work with, but easier to use correctly then wrongly.
Transparent tokens (the ones everybody knows how to verify) have the advantage over opaque tokens that you pointed out (they are easy to distribute). On the other hand, they are hard to revoke, so people tend to use short-lived ones. And yes, it's common for an application to have a long-lived opaque token that they only use in an authentication service to get short-lived transparent ones (that they use everywhere).
Anyway, the article is about the infrastructure for supporting JWT in javascript.
Oldish but still largely relevant: https://paragonie.com/blog/2017/03/jwt-json-web-tokens-is-ba...
The point of JWT vs opaque tokens is that you can just inspect the token itself to derive permissions without hitting any sessions in DB, right?
This means we need a short-lived access token (5 min or so?) so that sessions are revoked in a reasonable time if the token is stolen somehow (this is already scary to me TBH, someone can still do horrific things in 5 mins of intrusion time, but that's another story). Now my question is... how do you even handle the refresh token then?
I understand that long-lived refresh tokens means you can actually go to the DB/microservice/whatever and check if the refresh token has been revoked (via log out for example) since they'll valid for much larger intervals, so you can afford the session lookup... But if a refresh token is long-lived, what is the difference from having an actual long-lived access token? You'll still be handing out access token for a while. I can't see the difference here.
What am I missing?
EDIT: I could see the point if the threat models for both were different (e.g. having access tokens in memory, refresh tokens in a super safe vault, like e.g. ChatGPT would need to do for actions) but having both refresh+access tokens in the same threat model seems like it does nothing to me.