So I've been trying to learn as much as I can about JWT tokenisation, and auth0 seems to be the defacto JWT information hub.
However, the more I read about refresh tokens, the more I cringe - the very idea of an "infinitely" refreshable (or at least a very long expiry) doesn't sit with me.
So here is what I've decided to implement.
The architecture of the system: 1. API (pure API layer, also the auth server at the moment) - creates the tokens and validates them 2. App layer (flask handling requests).
When a user tries to enter the app - they are sent to the login page. They enter their details, and these are sent to the /authorize endpoint on the API.
These details are validated and a token created with a claim containing: "iat" issued at "exp" expiry 30 mins "oct" original created time
As far as the auth server and API are concerned, this token will expire in 30 minutes.
Now on the App Layer, each request checks the token and sees whether there is less than 5 minutes left before expiry.
If it finds there is it creates its own JWT (signed with the same secret as the API knows). It uses the original JWT (about to expire) as a payload object, then sends it to an endpoint on the auth /refresh_token
The /refresh_token endpoint then validates the token, extracts the original token from the payload, validates that and if it's a valid token (hasn't yet expired). It then checks the original created time, and makes sure a max timeout (set by the customer of our App) hasn't been reached - this is a system hard limit of 12hrs (but our customers can opt for shorter total sessions). If those checks are OK, it creates a NEW token and sends it back to the App Layer.
In this way, my thinking is:
The Auth server can always trust this refresh request, because it must receive a trusted JWT that contains the JWT originally created by the Auth server. This means, it could only have been created by the App Layer (or any server that has the secret).
The Auth server doesn't infinitely hand out refresh tokens.
If the secret is compromised - you're up the proverbial anyway, and until you know it's been compromised, there isn't much you can do - of course we have IP checkers to ensure requests for JWTs come from trusted sources, but still - IP spoofing isn't difficult if the attacker knew what they were doing.
The App Layer, has the ability to stop sending refreshes by killing the user session - hence a compromised JWT would only be "dangerous" for up to 30 minutes.
A lot of people get very worked up about security, and rightly so - but would you say this approach provides adequate checks and balances?
If not, I would love to hear ideas, improvements in process etc. Security is definitely not my strong suit, so all help will be greatly appreciated!