3

If I understand correctly, a JSON Web Token (JWT) can be asymmetrically signed with a special private key (JWK). At least in some common configurations, the public part of the signing key can't be obtained via classic x.509 certificates, but rather by accessing some trusted API endpoint, fetching the public key, and using that to verify the JWT signature.

How is that any better than just sending the entire token over to the trusted API and asking it to validate it? I thought that the whole point of using tokens was that they can be verified without contacting the token issuer, just by checking its signature with a widely available public key.

EDIT: Also, like I commented on @bk2204's answer, even if you cache the JWK, every time you need to refresh the JWK, you need to use the x.509 key to make an HTTPS request to the JWK server. And if the x.509 certificate is expired or revoked, then one should also revoke the JWKs. Seems to me that if the x.509 key can be used for every single HTTPS request that the JWK server gets, then surely it should be good enough to sign the tokens directly.

2 Answers 2

3

The benefit of using some sort of public key for verification is that the verification can be done offline. For example, say I ask service XYZ to validate a user and, if authorized, provide a JWT. I can query service XYZ to provide me their long-term signing key once, and validate the JWTs that have been issued. As long as they continue to use the same signing key, I can validate the JWTs, even if service XYZ goes down or is otherwise unavailable.

There is, of course, a tradeoff here. You want to rotate keys every so often to limit the risk of compromise, but you also don't want to fetch the key all the time, so there needs to be a balance.

Note that a X.509 certificate isn't necessarily ideal for verifying things that don't use the X.509 framework, such as JWTs. It certainly can be used, but a JWK can provide similar key material without the overhead of public certificate issuance if the provenance of the key can be trusted (as with a trusted API endpoint).

Note also that the X.509 certificate in use might not be suitable for other reasons as well. Publicly trusted X.509 certificates cannot currently use Ed25519, which may be desirable; they may expire before the tokens become invalid if they have a short duration; and the service that performs TLS termination in the environment may be totally separated from the service that issues tokens.

2
  • 1
    But every time I contact the JWK server for a fresh new key, I must use the x.509 certificate to secure my HTTPS request, so the JWK is kind of bound to the x.509 certificate. In fact, if the x.509 gets revoked, I should also revoke any cached JWK key. So why not sign the token directly with the x.509 key? If it's good enough to sign stuff on every HTTPS request the JWK server gets, then surely it's good enough to sign the tokens
    – user986730
    Jul 5, 2021 at 11:16
  • I've added some other reasons that one may not want to use X.509 certificates for signing JWTs. Additionally, as long as you used a cipher suite with perfect forward secrecy, you don't need to revoke the JWKs unless the X.509 private key was compromised when you made the connection. X.509 certificates are just used as part of the process to set up the encrypted tunnel. You could ask as well why you don't sign it with the server's SSH key if you got the JWT over SSH.
    – bk2204
    Jul 5, 2021 at 14:30
2

This might not provide a full answer but I am unable to comment. The most common reason I can think of is the token containing data you might not want to leak to the user agent. This applies primarily to access tokens, which by design are only to be handled through the resource server. This could be either:

  • Claims that might hint on how your API logic behaves;
  • Internal user Information, such as a GUID, you want to keep obscure.

Think of an attacker somehow being able to sniff the data traffic of an API running in business intranet and thus hijacking a bunch of tokens. Since these are encrypted, it limits his ability to construct valid requests. If your tokens were merely signed, he might just grab the one out of dozens of tokens with the longest remaining validity and the claim "role: Admin".

2
  • "token containing data you might no want to leak tot he user agent" but I would be sending the token straight back to the issuer, on the backend, not through the user agent. "If your tokens were merely signed, he might just grab the one out of dozens of tokens with the longest remaining validity and the claim 'role: Admin'": an attacker cannot do that and produce a valid signature as if they were the token issuer, since that requires their private key.
    – user986730
    Jul 1, 2021 at 14:39
  • Why would you send the token right back? You might as well let the resource server own a client secret to decrypt the token and then validate it without the additional round-trip. An attacker wouldn't need to tamper with the token, but being merely signed and not encrypted allows him to read it's contents in the first place and thus getting hints on which token might helpful in getting the most desirable information.
    – Beltway
    Jul 1, 2021 at 14:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .