Should Refresh Tokens in JWT Authentication Schemes be Signed with a Different Secret than the Access Token?

Viewed 1047

I have a very simple question that is essentially as stated in the title.

When implementing a JWT authentication scheme that incorporates short-lived access tokens and longer term refresh tokens, should these two token types be signed with different secrets?

I have been learning more about this authentication scheme recently and in my reading I didn't come across a strong opinion or conclusive answer to this question. Some brief Googling and searching Stack Overflow didn't produce any meaningful answers either.

Thank you for your time!

3 Answers

Answer: No

Why?

2 tokens we're speaking of are

  1. access token
  2. refresh token

Cryptographically there is no upper-bound on key-usage that I'm aware of for either HMAC, RSA or ECDSA. So signing with the same key is totally reasonable to protect from existential forgery.

However, if your access-token and refresh-token issuing endpoints are on separate servers, from a key-management security perspective you may wish to sign with different secrets to contain a compromise of one of the two secrets.

My intuition tells me to separate the secrets for the two tokens. But not because of security reasons. I mean, if on of the secrets leaks then you are done. And the attack surface is IMHO the same if there is one secret or two.

The reason for me to keep the secrets apart would be usability and error prevention. Developers sometimes tend to do stupid things, like mixing stuff. One day the developer will try to send a refresh token in place of an access token. If the secrets are different - the token will be simply rejected. If the secrets are the same - what happens next is beyond my imagination (so I would like to prevent this).

From cryptographic aspect I can agree with the accepted answer.

But one thing to think about is, that if you are using the same secret, you should care how you validate the refresh token. If you just check that the JWT is valid, one could send an access token as the refresh token and obtain a new access token from an previous valid access token.

So you should either use different secrets or care that you specify and validate a flag in the JWT body indicating if this is an access or refresh token.

Related