Token Signing Key Rotation

Token Signing Key Rotation

On this page

The Curity Identity Server uses keys to sign JSON Web Tokens (JWT) that it issues to OAuth clients. The keys are usually assymetric private keys, and it is a security best practice to renew these keys periodically. When applications or APIs need to validate a JWT, they do so by downloading the corresponding public key as a JSON Web Key (JWK). This tutorial explains how to manage renewal, with no impact on your applications.

View the Original Key Set

When applications need to validate JWTs, they read the kid field from the JWT header. A request is then made to the JSON Web Key Set (JWKS) endpoint of the Curity Identity Server, to get the public key (JWK) with which to verify the JWT's signature. This work is often done by a JWT library, which also manages caching of downloaded keys. The JWKS URL is often found via the OpenID Connect metadata endpoint, and these endpoint URLs will have values similar to those shown below:

EndpointExample URL
Metadatahttps://idsvr.example.com/oauth/v2/oauth-anonymous/.well-known/openid-configuation
JWKShttps://idsvr.example.com/oauth/v2/oauth-anonymous/jwks

An example key set is shown below, containing public key data. At the time when token signing keys are renewed, some apps will be using tokens signed with the old key. During renewal, you must ensure that JWT validation continues to work for these tokens:

json
12345678910111213
{
"keys": [
{
"kty": "RSA",
"kid": "-1930255284",
"use": "sig",
"alg": "RS256",
"n": "pSJz5kJBA3ByvqzRuTUfNKw3bQsAK_0kFIDGFY9n4FPSs2gFMGrF_ ...",
"e": "AQAB",
"x5t": "SqPBESh2KybSPWQiM3eabuVHW-A"
}
]
}

Import the New Key

When you need to renew the token signing key, the easiest option is to use the Admin UI. There is an option to generate a new keypair, or various ways to import keys. To do so, navigate to Facilities -> Keys and Cryptography --> Signing. The following screenshot shows a keypair being imported from a password protected .P12 file. Automation options are also provided, and described in Automate Certificate Renewal tutorial.

Signing Key

Update Token Issuers

Next, navigate to Token Service -> Token Issuers and first add a new token issuer, which will act as a holder of the old key, to ensure that it continues to be served in the JWKS document. Accept default options, and ensure that the algorithm and signing key fields match the old key:

New Token Issuer

Finally, update the existing token issuer with the new signing key, then commit all changes:

Updated Token Issuer

View the Updated Key Set

The updated JWKS endpoint will then serve both the old and new public keys to your applications. All future tokens the apps receive will be signed with the new token signing key, and the old entry only exists to ensure that tokens signed with the old key continue to validate correctly.

json
12345678910111213141516171819202122
{
"keys": [
{
"kty": "RSA",
"kid": "762235973",
"use": "sig",
"alg": "RS256",
"n": "805gVfTx3MaUh5yducAGHo0Mynr05WJ-ZKRTdpn85AHu9eYEX94O ...",
"e": "AQAB",
"x5t": "DNp0xi7gb6xVw4IIsF-qummwfXQ"
},
{
"kty": "RSA",
"kid": "-1930255284",
"use": "sig",
"alg": "RS256",
"n": "pSJz5kJBA3ByvqzRuTUfNKw3bQsAK_0kFIDGFY9n4FPSs2gFMGrF_ ...",
"e": "AQAB",
"x5t": "SqPBESh2KybSPWQiM3eabuVHW-A"
}
]
}

During the development process, it is recommended to practice renewal in the middle of user activity, to ensure that the renewal process works seamlessly for the end users of your applications.

Remove Old Resources

Once all JWTs issued with the old key have expired, the old token issuer should be removed, along with the old keys. This will also remove the old key from the JWKS document. You will be able to judge when it is safe to do so, based on the lifetime of tokens your applications use. In many setups it is safe to do so within hours.

Conclusion

To follow security best practices, renew your token signing keys periodically. This is best managed by updating your current token issuer, so that all future tokens are issued with the new key. Use a placeholder token issuer temporarily, to ensure that the renewal process has no impact on your applications.