It's not clear to me why there aren't more signing keys. After all, the public part is exposed at an URL you can retrieve whenever you're verifying the token.
I've seen service provider implementations where the access token is exchanged for a cookie or other similar token, in which case you can't really do anything about it anymore for the lifetime of the cookie.
But if you're always verifying the access token with a reasonably short cached key list, the service provider should be able to refuse the token reasonably quickly once the key is no longer advertised.
Anecdotally, I ran an experiment with Envoy to see how far the number of signing keys could scale. This was for a B2B “API Key” auth solution; we wanted user keys to be self revocable, but just be a relatively standard JWT format for maintainability. The hypothesis was that, rather than running a whitelist or blacklist, we could improve the security signature by have 1 signing key for each JWT.
When we ran some stress tests, turned out Envoy could happily run with ~300K signing keys in its JWK Set before noticeable service degradation occurred. Even then, by bumping up the memory on the validation servers, there was a small sacrifice of a few ms per extra 100K keys.
This makes me fully agree that, for many applications, there’s probably an opportunity to vastly improve the security surface by bumping up the number of signing keys dramatically.
As long as both Keys and Signing keys define a KID, key verification is prefaced only by a hash table lookup or a tight loop through a keyset to find the appropriate Signing Key, before the slower verification procedure.
I guess 640K keys ought to be enough for anybody (TM)(r) (c)
More seriously, though, I wonder how AzureAD is implemented and how hard it would be to scope keys per tenant, if not per application. If I'm not mistaken, SAML certificates are per application.
If you want 1 signing key per JWT, you would need to generate a new key pair for each JWT; wouldn’t that be too expensive? Or was the generation included in your tests?
I've seen service provider implementations where the access token is exchanged for a cookie or other similar token, in which case you can't really do anything about it anymore for the lifetime of the cookie.
But if you're always verifying the access token with a reasonably short cached key list, the service provider should be able to refuse the token reasonably quickly once the key is no longer advertised.