JSON Web Tokens (JWTs) (RFC, introduction) are digitally signed using a secret key (which can be symmetric, but for distributed use cases will typically be asymmetric). The signature forms the third and final part of the JWT, and can be verified from the JWT recipient side using the same secret key (for symmetric signing), or the private key's corresponding public key (for asymmetric signing). This allows the JWT recipient to verify the integrity of the JWT, i.e. that it has not been tampered with by some third party.
Further recommended validation mechanisms include verifying that the token has not yet been expired, that the recipient is the intended audience, etc.
For asymmetric signatures, the public key might be transmitted embedded as part of the JWT itself (jwk
or x5c
claim), or a URL to the public key might be provided (jku
or x5u
claim). There may be further public key transmission mechanisms of which I am not aware.
However, how can the JWT recipient verify that the JWT was in fact actually generated by the issuer that it claims (iss
claim) to be generated by? What prevents any arbitrary malicious actor from generating a JWT with their own private key, masquerading in the iss
claim as an issuer they do not actually represent, and passing in the JWT itself the public key (or a link to it) for verifying the signature. In such a scenario, the recipient would be able to know that the JWT wasn't tampered with, but they wouldn't know that the issuer was false, and that the content therefore could not be trusted.
As far as I've been able to gather, the best practice in when using asymmetric JWT signing is for the JWT recipient to explicitly whitelist specific public keys or public key URLs/domains. This would allow the recipient to know for sure whether the JWT was generated by the purported issuer, assuming that the recipient can be confident in which domains or public keys the issuer actually owns.
Does verification of issuer always rely on manual whitelisting such as this by each and every recipient, or are there other mechanisms by which the recipient can verify with certainty whether the JWT was indeed generated by the issuer it claims to be, without the same level of manual effort.
I've found little information about this conundrum online, and the original JWT RFC itself also does not seem to touch upon it, from what I can see.