I need to verify the signature of tokens from the Microsoft Graph API. I understand that the thumbprint of the the signing key used is in the header of the JWT here:
And that it corresponds to the keys you can obtain from the well known endpoint:
https://login.microsoftonline.com/[TENANT-ID]/discovery/v2.0/keys
Which returns an array of keys including the signing key for the token :
My plan is to store the list of keys in cache so I can look up the correct signing key for a token when I need to do a verification. However I understand that at times keys may get rotated.
Since there is not much documentation on this my question is in multiple parts:
Is this a sound strategy?
Do new keys get appended to the list at the well known endpoint? I'm assuming this list grows over time so I can always get an older key if the token calls for it? As well as refresh my cache should it ever need to be rehydrated with the available keys.
At what point do older keys drop off this list? I'm assuming there must be a time or count cut-off.
It seems as though the latest key is the first record and is sorted in descending order?
Why is x5c an array? Shouldn't there only ever be one signing key per record? I assume I should only use .x5c[0] but in what scenario would there be multiple items here?
Key rollover has been implemented for you in various libraries; a sound strategy is to use one of them rather than rolling your own.
The JSON document from https://login.microsoftonline.com/[TENANT-ID]/discovery/v2.0/keys
conforms to JSON Web Key (JWK) specification (RFC 7517). The spec does not dictate the order of keys in the keys
array:
The value of the
"keys"
parameter is an array of JWK values. By default, the order of the JWK values within the array does not imply an order of preference among them, although applications of JWK Sets can choose to assign a meaning to the order for their purposes, if desired.
Microsoft's implementation of key rollover appears to add newer keys to the top of the list. There's no documented guarantee of this and we wouldn't recommend relying on it. As far as when keys drop off the list, again there's no published spec on this. If the cert is revoked or it expires, it cannot be used to validate a signature. Common sense dictates that it should be removed from the list at that point in time. Microsoft's key rollover doc notes that
in an emergency, [keys] could be rolled over immediately.
Translation: the decision of how often you should go back to the published "master" list of keys at https://login.microsoftonline.com/[TENANT-ID]/discovery/v2.0/keys
depends on importance / consequences of not being able to validate a token in your app.
x5c
is an array because it represents a certificate chain. Microsoft's implementation is using a single certificate (chain's length = 1) but nothing stops them from going with a longer chain at some future point in time. Practically speaking, it is unlikely they will do so because it will impact a number of non-conforming apps as well as their own libraries.