Rotating keys in ACP
Workspace vs the AuthZ server
The key rotation in ACP can be performed on the workspace level. Each workspace is an independent OAuth server with a different set of keys.
Note
Details on this authorization server can be explored using OpenID configuration endpoint
https://<acp-domain>:<acp-port>/<tenantid>/<workspaceid>/.well-known/openid-configuration
.
Example of the OpenID-configuration endpoint
curl https://acp.example.com:8443/default/demo/.well-known/openid-configuration | jq
{
"issuer": "https://acp.example.com:8443/default/demo",
"authorization_endpoint": "https://acp.example.com:8443/default/demo/oauth2/authorize",
"token_endpoint": "https://acp.example.com.com:8443/default/demo/oauth2/token",
"jwks_uri": "https://acp.example.com:8443/default/demo/.well-known/jwks.json",
"subject_types_supported": [
"public",
"pairwise"
],
"response_types_supported": [
"id_token",
"code",
"code id_token",
"token",
"token id_token",
"token id_token code"
],
"claims_supported": [
"sub",
"acr",
"amr"
],
"grant_types_supported": [
"authorization_code",
"implicit",
"client_credentials",
"refresh_token"
],
"response_modes_supported": [
"query",
"fragment"
],
"userinfo_endpoint": "https://acp.example.com:8443/default/demo/userinfo",
"introspection_endpoint": "https://acp.example.com:8443/default/demo/oauth2/introspect",
"scopes_supported": [
"email",
"phone",
"address",
"profile",
"openid",
"offline_access",
"view_consents",
"manage_consents",
"introspect_tokens",
"revoke_tokens",
"list_clients_with_access",
"revoke_client_access",
"dcr_register"
],
"token_endpoint_auth_methods_supported": [
"client_secret_basic",
"client_secret_post",
"client_secret_jwt",
"none",
"private_key_jwt",
"self_signed_tls_client_auth",
"tls_client_auth"
],
"token_endpoint_auth_signing_alg_values_supported": [
"RS256",
"ES256",
"PS256"
],
"userinfo_signing_alg_values_supported": [
"none",
"ES256"
],
"id_token_signing_alg_values_supported": [
"ES256"
],
"request_parameter_supported": true,
"request_uri_parameter_supported": true,
"request_object_signing_alg_values_supported": [
"RS256",
"ES256",
"PS256"
],
"require_request_uri_registration": true,
"claims_parameter_supported": true,
"revocation_endpoint": "https://acp.example.com:8443/default/demo/oauth2/revoke",
"registration_endpoint": "https://acp.example.com:8443/default/demo/oauth2/register",
"backchannel_logout_supported": false,
"backchannel_logout_session_supported": false,
"frontchannel_logout_supported": false,
"frontchannel_logout_session_supported": false,
"code_challenge_methods_supported": [
"S256"
],
"tls_client_certificate_bound_access_tokens": true
}
Generate a new key
To rotate a key, you need to generate a new key first.
Note
ACP supports both RS and EC based signatures keys. Due to performance reasons, the EC-based keys are recommended and configured by default.
-
To generate a new signature, you need to start with a new key and a certificate.
openssl req -x509 -nodes -days 3650 -newkey ec:<(openssl ecparam -name prime256v1) -keyout ecdsakey.pem -out ecdsacert.pem Generating an EC private key writing new private key to 'ecdsakey.pem' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:WA Locality Name (eg, city) []:Seattle Organization Name (eg, company) [Internet Widgits Pty Ltd]:Cloudentity Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:acp.example.com Email Address []: ....
Result
You get the key in the X509 PEM format.
-
Convert your new key to the JWKS format.
Note
ACP has an embedded conversion tool that helps with the conversion process.
acp jwks convert --cert-path ./ecdsacert.pem --key-path ./ecdsakey.pem --private-jwks-path ./jwks-priv.json --public-jwks-path ./jwks-pub.json
Exemplary output
Here is an example of the generated JWT Key Set:
cat jwks-priv.json
{ "keys": [ { "use": "sig", "kty": "EC", "kid": "244861745913611684766818513248687510777770339898", "crv": "P-256", "alg": "ES256", "x": "5H1NpP-YTJbOwM-M_8wk5d4MFSA-2bIEXwr92vOXTlM", "y": "48cfpJpP9EuERXYIyJXgwaQPMCqtccBKV42Ec9kkZVc", "d": "XxpxSGD4ZDn8p3a_pgOb8aeuFSptUKliV-Hs6ik9G0w", "x5c": [ "MIICIzCCAcmgAwIBAgIUKuP6/aKEXOAR3lgCxmKR0dHA7jowCgYIKoZIzj0EAwIwZzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMRQwEgYDVQQKDAtDbG91ZGVudGl0eTEjMCEGA1UEAwwaYWNwLnYxNi5jbG91ZGVudGl0eS1zZS5jb20wHhcNMjEwMTMwMjA0NjAyWhcNMzEwMTI4MjA0NjAyWjBnMQswCQYDVQQGEwJVUzELMAkGA1UECAwCV0ExEDAOBgNVBAcMB1NlYXR0bGUxFDASBgNVBAoMC0Nsb3VkZW50aXR5MSMwIQYDVQQDDBphY3AudjE2LmNsb3VkZW50aXR5LXNlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOR9TaT/mEyWzsDPjP/MJOXeDBUgPtmyBF8K/drzl05T48cfpJpP9EuERXYIyJXgwaQPMCqtccBKV42Ec9kkZVejUzBRMB0GA1UdDgQWBBR0XtNqn673m+X0lVlTxjWWk12fCTAfBgNVHSMEGDAWgBR0XtNqn673m+X0lVlTxjWWk12fCTAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0gAMEUCIA7ajABMU1Q5sFoa1vVvN7IBaFzCZPCvalhYDM8TxfyqAiEAq6bkOL4vuAPZtq7RPFIQPBzly6mfZuA30ciK6Sc4ab0=" ], "x5t": "6xfvlWhPypSwWGct_WXzjENOHNk", "x5t#S256": "mrRCyDKOreVilIQmcz2HSWQD5PGzMaIMqaKkpZEy2Zs" } ] }
Obtain the old key
Note
To rotate the keys, both the new key and the old one are needed. The old key is available as a part of the configuration to the authorization server using GET Authorization Server Admin API
https://docs.authorization.cloudentity.com/api/admin/#operation/getAuthorizationServer
. The authorization access token with admin privileges is needed to perform this operation.
-
To retrieve the authorization access token with admin privileges, execute
curl -X GET "https://acp.example.com:8443/api/admin/default/servers/demo" -H "accept: application/json" -H "authorization: Bearer $ADMIN_ACCESS_TOKEN" | jq .jwks { "keys": [ { "use": "sig", "kty": "EC", "kid": "303446885349823077582433662447357289206", "crv": "P-256", "alg": "ES256", "x": "2NBblGjHBkT0Toaci9JwrZ-fSuaMGrWshneP_4G8J_E", "y": "XDdYypQZXuUWN0O69aZIFQLNf3RVqxLO0CLIlh0knlo", "d": "fIY9g9OU9I0N6AHJbg-xDmN8UZNPEePRz1vTmNawrmg", "x5c": [ "MIIBxTCCAWqgAwIBAgIRAORJvoqd7wNKrzlLyWGgYvYwCgYIKoZIzj0EAwIwLDEUMBIGA1UEChMLQ2xvdWRlbnRpdHkxFDASBgNVBAMTC0Nsb3VkZW50aXR5MB4XDTIxMDEyOTIwMTAzMFoXDTIxMDMwMTIwMTAzMFowLDEUMBIGA1UEChMLQ2xvdWRlbnRpdHkxFDASBgNVBAMTC0Nsb3VkZW50aXR5MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2NBblGjHBkT0Toaci9JwrZ+fSuaMGrWshneP/4G8J/FcN1jKlBle5RY3Q7r1pkgVAs1/dFWrEs7QIsiWHSSeWqNtMGswDgYDVR0PAQH/BAQDAgKkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFA3MMurUsdpPAbXnalVcpuDwEl1JMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAKBggqhkjOPQQDAgNJADBGAiEAx0dKT57UMu9jDiQ/beOeYHlRqjEJhoMSPZzh8I0amPUCIQDpiuS+8Qo7R/Qa5ttUHBvWIb+ctlcEHyx2HsdAkIW2jA==" ], "x5t": "uyOjbQzdzjVMr91rOHFagag2fFg", "x5t#S256": "uCXSufaU9pmSNS0PKFUYRgOCDB67HDz6wpuAoYzOwMo" } ] }
-
Combine the new key with the old one.
Watch it
It’s important that the the new key is listed as the first one.
"jwks": { "keys": [{ "use": "sig", "kty": "EC", "kid": "244861745913611684766818513248687510777770339898", "crv": "P-256", "alg": "ES256", "x": "5H1NpP-YTJbOwM-M_8wk5d4MFSA-2bIEXwr92vOXTlM", "y": "48cfpJpP9EuERXYIyJXgwaQPMCqtccBKV42Ec9kkZVc", "d": "XxpxSGD4ZDn8p3a_pgOb8aeuFSptUKliV-Hs6ik9G0w", "x5c": [ "MIICIzCCAcmgAwIBAgIUKuP6/aKEXOAR3lgCxmKR0dHA7jowCgYIKoZIzj0EAwIwZzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMRQwEgYDVQQKDAtDbG91ZGVudGl0eTEjMCEGA1UEAwwaYWNwLnYxNi5jbG91ZGVudGl0eS1zZS5jb20wHhcNMjEwMTMwMjA0NjAyWhcNMzEwMTI4MjA0NjAyWjBnMQswCQYDVQQGEwJVUzELMAkGA1UECAwCV0ExEDAOBgNVBAcMB1NlYXR0bGUxFDASBgNVBAoMC0Nsb3VkZW50aXR5MSMwIQYDVQQDDBphY3AudjE2LmNsb3VkZW50aXR5LXNlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOR9TaT/mEyWzsDPjP/MJOXeDBUgPtmyBF8K/drzl05T48cfpJpP9EuERXYIyJXgwaQPMCqtccBKV42Ec9kkZVejUzBRMB0GA1UdDgQWBBR0XtNqn673m+X0lVlTxjWWk12fCTAfBgNVHSMEGDAWgBR0XtNqn673m+X0lVlTxjWWk12fCTAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0gAMEUCIA7ajABMU1Q5sFoa1vVvN7IBaFzCZPCvalhYDM8TxfyqAiEAq6bkOL4vuAPZtq7RPFIQPBzly6mfZuA30ciK6Sc4ab0=" ], "x5t": "6xfvlWhPypSwWGct_WXzjENOHNk", "x5t#S256": "mrRCyDKOreVilIQmcz2HSWQD5PGzMaIMqaKkpZEy2Zs" }, { "use": "sig", "kty": "EC", "kid": "303446885349823077582433662447357289206", "crv": "P-256", "alg": "ES256", "x": "2NBblGjHBkT0Toaci9JwrZ-fSuaMGrWshneP_4G8J_E", "y": "XDdYypQZXuUWN0O69aZIFQLNf3RVqxLO0CLIlh0knlo", "d": "fIY9g9OU9I0N6AHJbg-xDmN8UZNPEePRz1vTmNawrmg", "x5c": [ "MIIBxTCCAWqgAwIBAgIRAORJvoqd7wNKrzlLyWGgYvYwCgYIKoZIzj0EAwIwLDEUMBIGA1UEChMLQ2xvdWRlbnRpdHkxFDASBgNVBAMTC0Nsb3VkZW50aXR5MB4XDTIxMDEyOTIwMTAzMFoXDTIxMDMwMTIwMTAzMFowLDEUMBIGA1UEChMLQ2xvdWRlbnRpdHkxFDASBgNVBAMTC0Nsb3VkZW50aXR5MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2NBblGjHBkT0Toaci9JwrZ+fSuaMGrWshneP/4G8J/FcN1jKlBle5RY3Q7r1pkgVAs1/dFWrEs7QIsiWHSSeWqNtMGswDgYDVR0PAQH/BAQDAgKkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFA3MMurUsdpPAbXnalVcpuDwEl1JMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAKBggqhkjOPQQDAgNJADBGAiEAx0dKT57UMu9jDiQ/beOeYHlRqjEJhoMSPZzh8I0amPUCIQDpiuS+8Qo7R/Qa5ttUHBvWIb+ctlcEHyx2HsdAkIW2jA==" ], "x5t": "uyOjbQzdzjVMr91rOHFagag2fFg", "x5t#S256": "uCXSufaU9pmSNS0PKFUYRgOCDB67HDz6wpuAoYzOwMo" } ] }
-
To update the keys, use Update Authorization Server API
https://docs.authorization.cloudentity.com/api/admin/#operation/updateAuthorizationServer
.curl -X PUT "https://acp.example.com:8443/api/admin/default/servers/demo" -H "accept: application/json" -H "authorization: Bearer $ADMIN_ACCESS_TOKEN" -H "Content-Type: application/json" -d "{ \"tenant_id\": \"default\", \"id\": \"demo\", \"profile\": \"default\", \"name\": \"Demo\", \"type\": \"regular\", \"color\": \"#007FFF\", \"secret\": \"a7PsnLjCoqfzWPbya_6ZE1gmOed0sjHm5g3z0AHo8SM\", \"rotated_secrets\": [], \"access_token_strategy\": \"jwt\", \"key_type\": \"ecdsa\", \"logo_uri\": \"\", \"issuer_url\": \"https://acp.example.com:8443/default/demo\", \"dynamic_client_registration\": { \"enabled\": false, \"initial_access_token\": { \"required\": false }, \"software_statement\": { \"required\": false, \"jwks\": { \"keys\": null }, \"jwks_uri\": \"\" }, \"payload\": { \"format\": \"json\", \"jws_payload\": { \"jwks\": { \"keys\": null }, \"jwks_uri\": \"\" } } }, \"grant_types\": [ \"authorization_code\", \"implicit\", \"client_credentials\", \"refresh_token\" ], \"token_endpoint_authn_methods\": [ \"client_secret_basic\", \"client_secret_post\", \"client_secret_jwt\", \"private_key_jwt\", \"self_signed_tls_client_auth\", \"tls_client_auth\", \"none\" ], \"access_token_ttl\": \"3h0m0s\", \"refresh_token_ttl\": \"720h0m0s\", \"authorization_code_ttl\": \"10m0s\", \"id_token_ttl\": \"3h0m0s\", \"cookie_max_age\": \"1h0m0s\", \"jwks\": {\t\t\"keys\": [{\t\t\t\t\"use\": \"sig\",\t\t\t\t\"kty\": \"EC\",\t\t\t\t\"kid\": \"244861745913611684766818513248687510777770339898\",\t\t\t\t\"crv\": \"P-256\",\t\t\t\t\"alg\": \"ES256\",\t\t\t\t\"x\": \"5H1NpP-YTJbOwM-M_8wk5d4MFSA-2bIEXwr92vOXTlM\",\t\t\t\t\"y\": \"48cfpJpP9EuERXYIyJXgwaQPMCqtccBKV42Ec9kkZVc\",\t\t\t\t\"d\": \"XxpxSGD4ZDn8p3a_pgOb8aeuFSptUKliV-Hs6ik9G0w\",\t\t\t\t\"x5c\": [\t\t\t\t\t\"MIICIzCCAcmgAwIBAgIUKuP6/aKEXOAR3lgCxmKR0dHA7jowCgYIKoZIzj0EAwIwZzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMRQwEgYDVQQKDAtDbG91ZGVudGl0eTEjMCEGA1UEAwwaYWNwLnYxNi5jbG91ZGVudGl0eS1zZS5jb20wHhcNMjEwMTMwMjA0NjAyWhcNMzEwMTI4MjA0NjAyWjBnMQswCQYDVQQGEwJVUzELMAkGA1UECAwCV0ExEDAOBgNVBAcMB1NlYXR0bGUxFDASBgNVBAoMC0Nsb3VkZW50aXR5MSMwIQYDVQQDDBphY3AudjE2LmNsb3VkZW50aXR5LXNlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOR9TaT/mEyWzsDPjP/MJOXeDBUgPtmyBF8K/drzl05T48cfpJpP9EuERXYIyJXgwaQPMCqtccBKV42Ec9kkZVejUzBRMB0GA1UdDgQWBBR0XtNqn673m+X0lVlTxjWWk12fCTAfBgNVHSMEGDAWgBR0XtNqn673m+X0lVlTxjWWk12fCTAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0gAMEUCIA7ajABMU1Q5sFoa1vVvN7IBaFzCZPCvalhYDM8TxfyqAiEAq6bkOL4vuAPZtq7RPFIQPBzly6mfZuA30ciK6Sc4ab0=\"\t\t\t\t],\t\t\t\t\"x5t\": \"6xfvlWhPypSwWGct_WXzjENOHNk\",\t\t\t\t\"x5t#S256\": \"mrRCyDKOreVilIQmcz2HSWQD5PGzMaIMqaKkpZEy2Zs\"\t\t\t},\t\t\t{\t\t\t\t\"use\": \"sig\",\t\t\t\t\"kty\": \"EC\",\t\t\t\t\"kid\": \"303446885349823077582433662447357289206\",\t\t\t\t\"crv\": \"P-256\",\t\t\t\t\"alg\": \"ES256\",\t\t\t\t\"x\": \"2NBblGjHBkT0Toaci9JwrZ-fSuaMGrWshneP_4G8J_E\",\t\t\t\t\"y\": \"XDdYypQZXuUWN0O69aZIFQLNf3RVqxLO0CLIlh0knlo\",\t\t\t\t\"d\": \"fIY9g9OU9I0N6AHJbg-xDmN8UZNPEePRz1vTmNawrmg\",\t\t\t\t\"x5c\": [\t\t\t\t\t\"MIIBxTCCAWqgAwIBAgIRAORJvoqd7wNKrzlLyWGgYvYwCgYIKoZIzj0EAwIwLDEUMBIGA1UEChMLQ2xvdWRlbnRpdHkxFDASBgNVBAMTC0Nsb3VkZW50aXR5MB4XDTIxMDEyOTIwMTAzMFoXDTIxMDMwMTIwMTAzMFowLDEUMBIGA1UEChMLQ2xvdWRlbnRpdHkxFDASBgNVBAMTC0Nsb3VkZW50aXR5MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2NBblGjHBkT0Toaci9JwrZ+fSuaMGrWshneP/4G8J/FcN1jKlBle5RY3Q7r1pkgVAs1/dFWrEs7QIsiWHSSeWqNtMGswDgYDVR0PAQH/BAQDAgKkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFA3MMurUsdpPAbXnalVcpuDwEl1JMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAKBggqhkjOPQQDAgNJADBGAiEAx0dKT57UMu9jDiQ/beOeYHlRqjEJhoMSPZzh8I0amPUCIQDpiuS+8Qo7R/Qa5ttUHBvWIb+ctlcEHyx2HsdAkIW2jA==\"\t\t\t\t],\t\t\t\t\"x5t\": \"uyOjbQzdzjVMr91rOHFagag2fFg\",\t\t\t\t\"x5t#S256\": \"uCXSufaU9pmSNS0PKFUYRgOCDB67HDz6wpuAoYzOwMo\"\t\t\t}\t\t]\t}, \"enforce_pkce\": false, \"enforce_pkce_for_public_clients\": false, \"root_cas\": \"\", \"read_client_certificate_from_header\": false, \"client_certificate_header\": \"\", \"subject_identifier_types\": [ \"public\", \"pairwise\" ], \"subject_identifier_algorithm_salt\": \"IASuYx0ffeiRJGnzkqCmcY-gH0HnGKMT9fFRlFvSrNQ\"}"
-
To verify if the key set has been updated successfully, execute
ubuntu curl -X GET "https://acp.example.com:8443/api/admin/default/servers/demo" -H "accept: application/json" -H "authorization: Bearer $ADMIN_ACCESS_TOKEN" | jq .jwks { "keys": [ { "use": "sig", "kty": "EC", "kid": "244861745913611684766818513248687510777770339898", "crv": "P-256", "alg": "ES256", "x": "5H1NpP-YTJbOwM-M_8wk5d4MFSA-2bIEXwr92vOXTlM", "y": "48cfpJpP9EuERXYIyJXgwaQPMCqtccBKV42Ec9kkZVc", "d": "XxpxSGD4ZDn8p3a_pgOb8aeuFSptUKliV-Hs6ik9G0w", "x5c": [ "MIICIzCCAcmgAwIBAgIUKuP6/aKEXOAR3lgCxmKR0dHA7jowCgYIKoZIzj0EAwIwZzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMRQwEgYDVQQKDAtDbG91ZGVudGl0eTEjMCEGA1UEAwwaYWNwLnYxNi5jbG91ZGVudGl0eS1zZS5jb20wHhcNMjEwMTMwMjA0NjAyWhcNMzEwMTI4MjA0NjAyWjBnMQswCQYDVQQGEwJVUzELMAkGA1UECAwCV0ExEDAOBgNVBAcMB1NlYXR0bGUxFDASBgNVBAoMC0Nsb3VkZW50aXR5MSMwIQYDVQQDDBphY3AudjE2LmNsb3VkZW50aXR5LXNlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOR9TaT/mEyWzsDPjP/MJOXeDBUgPtmyBF8K/drzl05T48cfpJpP9EuERXYIyJXgwaQPMCqtccBKV42Ec9kkZVejUzBRMB0GA1UdDgQWBBR0XtNqn673m+X0lVlTxjWWk12fCTAfBgNVHSMEGDAWgBR0XtNqn673m+X0lVlTxjWWk12fCTAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0gAMEUCIA7ajABMU1Q5sFoa1vVvN7IBaFzCZPCvalhYDM8TxfyqAiEAq6bkOL4vuAPZtq7RPFIQPBzly6mfZuA30ciK6Sc4ab0=" ], "x5t": "6xfvlWhPypSwWGct_WXzjENOHNk", "x5t#S256": "mrRCyDKOreVilIQmcz2HSWQD5PGzMaIMqaKkpZEy2Zs" }, { "use": "sig", "kty": "EC", "kid": "303446885349823077582433662447357289206", "crv": "P-256", "alg": "ES256", "x": "2NBblGjHBkT0Toaci9JwrZ-fSuaMGrWshneP_4G8J_E", "y": "XDdYypQZXuUWN0O69aZIFQLNf3RVqxLO0CLIlh0knlo", "d": "fIY9g9OU9I0N6AHJbg-xDmN8UZNPEePRz1vTmNawrmg", "x5c": [ "MIIBxTCCAWqgAwIBAgIRAORJvoqd7wNKrzlLyWGgYvYwCgYIKoZIzj0EAwIwLDEUMBIGA1UEChMLQ2xvdWRlbnRpdHkxFDASBgNVBAMTC0Nsb3VkZW50aXR5MB4XDTIxMDEyOTIwMTAzMFoXDTIxMDMwMTIwMTAzMFowLDEUMBIGA1UEChMLQ2xvdWRlbnRpdHkxFDASBgNVBAMTC0Nsb3VkZW50aXR5MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2NBblGjHBkT0Toaci9JwrZ+fSuaMGrWshneP/4G8J/FcN1jKlBle5RY3Q7r1pkgVAs1/dFWrEs7QIsiWHSSeWqNtMGswDgYDVR0PAQH/BAQDAgKkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFA3MMurUsdpPAbXnalVcpuDwEl1JMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAKBggqhkjOPQQDAgNJADBGAiEAx0dKT57UMu9jDiQ/beOeYHlRqjEJhoMSPZzh8I0amPUCIQDpiuS+8Qo7R/Qa5ttUHBvWIb+ctlcEHyx2HsdAkIW2jA==" ], "x5t": "uyOjbQzdzjVMr91rOHFagag2fFg", "x5t#S256": "uCXSufaU9pmSNS0PKFUYRgOCDB67HDz6wpuAoYzOwMo" } ] }
Verify
Access token
After generating the new access token with the use of the token endpoint or the demo application, check if it is similar to the example token provided.
Example token
eyJhbGciOiJFUzI1NiIsImtpZCI6IjI0NDg2MTc0NTkxMzYxMTY4NDc2NjgxODUxMzI0ODY4NzUxMDc3Nzc3MDMzOTg5OCIsInR5cCI6IkpXVCJ9.eyJhY3IiOiIxIiwiYWlkIjoiZGVtbyIsImFtciI6WyJwd2QiXSwiYXVkIjpbImRlbW8tZGVtbyIsInNwaWZmZTovL2FjcC52MTYuY2xvdWRlbnRpdHktc2UuY29tL2RlZmF1bHQvZGVtby9jMGE2bmRpZjViaW8xdG9uMHUxZyJdLCJleHAiOjE2MTIwNTEzNjAsImlhdCI6MTYxMjA0MDU2MCwiaWRwIjoiYzBhNm5tMmY1YmlvMXRvbjB1OWciLCJpc3MiOiJodHRwczovL2FjcC52MTYuY2xvdWRlbnRpdHktc2UuY29tOjg0NDMvZGVmYXVsdC9kZW1vIiwianRpIjoiMzg1YTQzMWMtMTFjNS00N2VmLWJkMTItMTc5MTk3NmFkNzRmIiwibmJmIjoxNjEyMDQwNTYwLCJzY3AiOlsiZW1haWwiLCJvcGVuaWQiLCJwcm9maWxlIl0sInN0IjoicHVibGljIiwic3ViIjoidXNlciIsInRpZCI6ImRlZmF1bHQifQ.5RPLAoBJZwwXiJHBjzn5BLH2JTs6CiaEA_1vQeEUPDMvfC8wzteOYDb5vAdsflpVj5HbAWSFQGLRtbjhWgiQvw
Decode the key
Decode the signature and check if the key_id
matches the newly-configured key.
echo eyJhbGciOiJFUzI1NiIsImtpZCI6IjI0NDg2MTc0NTkxMzYxMTY4NDc2NjgxODUxMzI0ODY4NzUxMDc3Nzc3MDMzOTg5OCIsInR5cCI6IkpXVCJ9 | base64 -d | jq .kid
"244861745913611684766818513248687510777770339898"
Check the JWKS OIDC endpoint
Check if now the JWKS OIDC endpoint includes the new key and the old.
ubuntu@:$ curl https://acp.example.com:8443/default/demo/.well-known/jwks.json | jq
{
"keys": [
{
"use": "sig",
"kty": "EC",
"kid": "244861745913611684766818513248687510777770339898",
"crv": "P-256",
"alg": "ES256",
"x": "5H1NpP-YTJbOwM-M_8wk5d4MFSA-2bIEXwr92vOXTlM",
"y": "48cfpJpP9EuERXYIyJXgwaQPMCqtccBKV42Ec9kkZVc",
"x5c": [
"MIICIzCCAcmgAwIBAgIUKuP6/aKEXOAR3lgCxmKR0dHA7jowCgYIKoZIzj0EAwIwZzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMRQwEgYDVQQKDAtDbG91ZGVudGl0eTEjMCEGA1UEAwwaYWNwLnYxNi5jbG91ZGVudGl0eS1zZS5jb20wHhcNMjEwMTMwMjA0NjAyWhcNMzEwMTI4MjA0NjAyWjBnMQswCQYDVQQGEwJVUzELMAkGA1UECAwCV0ExEDAOBgNVBAcMB1NlYXR0bGUxFDASBgNVBAoMC0Nsb3VkZW50aXR5MSMwIQYDVQQDDBphY3AudjE2LmNsb3VkZW50aXR5LXNlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOR9TaT/mEyWzsDPjP/MJOXeDBUgPtmyBF8K/drzl05T48cfpJpP9EuERXYIyJXgwaQPMCqtccBKV42Ec9kkZVejUzBRMB0GA1UdDgQWBBR0XtNqn673m+X0lVlTxjWWk12fCTAfBgNVHSMEGDAWgBR0XtNqn673m+X0lVlTxjWWk12fCTAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0gAMEUCIA7ajABMU1Q5sFoa1vVvN7IBaFzCZPCvalhYDM8TxfyqAiEAq6bkOL4vuAPZtq7RPFIQPBzly6mfZuA30ciK6Sc4ab0="
],
"x5t": "6xfvlWhPypSwWGct_WXzjENOHNk",
"x5t#S256": "mrRCyDKOreVilIQmcz2HSWQD5PGzMaIMqaKkpZEy2Zs"
},
{
"use": "sig",
"kty": "EC",
"kid": "303446885349823077582433662447357289206",
"crv": "P-256",
"alg": "ES256",
"x": "2NBblGjHBkT0Toaci9JwrZ-fSuaMGrWshneP_4G8J_E",
"y": "XDdYypQZXuUWN0O69aZIFQLNf3RVqxLO0CLIlh0knlo",
"x5c": [
"MIIBxTCCAWqgAwIBAgIRAORJvoqd7wNKrzlLyWGgYvYwCgYIKoZIzj0EAwIwLDEUMBIGA1UEChMLQ2xvdWRlbnRpdHkxFDASBgNVBAMTC0Nsb3VkZW50aXR5MB4XDTIxMDEyOTIwMTAzMFoXDTIxMDMwMTIwMTAzMFowLDEUMBIGA1UEChMLQ2xvdWRlbnRpdHkxFDASBgNVBAMTC0Nsb3VkZW50aXR5MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2NBblGjHBkT0Toaci9JwrZ+fSuaMGrWshneP/4G8J/FcN1jKlBle5RY3Q7r1pkgVAs1/dFWrEs7QIsiWHSSeWqNtMGswDgYDVR0PAQH/BAQDAgKkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFA3MMurUsdpPAbXnalVcpuDwEl1JMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAKBggqhkjOPQQDAgNJADBGAiEAx0dKT57UMu9jDiQ/beOeYHlRqjEJhoMSPZzh8I0amPUCIQDpiuS+8Qo7R/Qa5ttUHBvWIb+ctlcEHyx2HsdAkIW2jA=="
],
"x5t": "uyOjbQzdzjVMr91rOHFagag2fFg",
"x5t#S256": "uCXSufaU9pmSNS0PKFUYRgOCDB67HDz6wpuAoYzOwMo"
}
]
}
Delete the old key
When the old JWT Key is no longer needed, it can be deleted using the same Update Authorization Server
API https://docs.authorization.cloudentity.com/api/admin/#operation/updateAuthorizationServer
.
curl -X PUT "https://acp.example.com:8443/api/admin/default/servers/demo" -H "accept: application/json" -H "authorization: Bearer $ADMIN_ACCESS_TOKEN" -H "Content-Type: application/json" -d "{ \"tenant_id\": \"default\", \"id\": \"demo\", \"profile\": \"default\", \"name\": \"Demo\", \"type\": \"regular\", \"color\": \"#007FFF\", \"secret\": \"a7PsnLjCoqfzWPbya_6ZE1gmOed0sjHm5g3z0AHo8SM\", \"rotated_secrets\": [], \"access_token_strategy\": \"jwt\", \"key_type\": \"ecdsa\", \"logo_uri\": \"\", \"issuer_url\": \"https://acp.example.com:8443/default/demo\", \"dynamic_client_registration\": { \"enabled\": false, \"initial_access_token\": { \"required\": false }, \"software_statement\": { \"required\": false, \"jwks\": { \"keys\": null }, \"jwks_uri\": \"\" }, \"payload\": { \"format\": \"json\", \"jws_payload\": { \"jwks\": { \"keys\": null }, \"jwks_uri\": \"\" } } }, \"grant_types\": [ \"authorization_code\", \"implicit\", \"client_credentials\", \"refresh_token\" ], \"token_endpoint_authn_methods\": [ \"client_secret_basic\", \"client_secret_post\", \"client_secret_jwt\", \"private_key_jwt\", \"self_signed_tls_client_auth\", \"tls_client_auth\", \"none\" ], \"access_token_ttl\": \"3h0m0s\", \"refresh_token_ttl\": \"720h0m0s\", \"authorization_code_ttl\": \"10m0s\", \"id_token_ttl\": \"3h0m0s\", \"cookie_max_age\": \"1h0m0s\", \"jwks\": {\t\t\"keys\": [{\t\t\t\t\"use\": \"sig\",\t\t\t\t\"kty\": \"EC\",\t\t\t\t\"kid\": \"244861745913611684766818513248687510777770339898\",\t\t\t\t\"crv\": \"P-256\",\t\t\t\t\"alg\": \"ES256\",\t\t\t\t\"x\": \"5H1NpP-YTJbOwM-M_8wk5d4MFSA-2bIEXwr92vOXTlM\",\t\t\t\t\"y\": \"48cfpJpP9EuERXYIyJXgwaQPMCqtccBKV42Ec9kkZVc\",\t\t\t\t\"d\": \"XxpxSGD4ZDn8p3a_pgOb8aeuFSptUKliV-Hs6ik9G0w\",\t\t\t\t\"x5c\": [\t\t\t\t\t\"MIICIzCCAcmgAwIBAgIUKuP6/aKEXOAR3lgCxmKR0dHA7jowCgYIKoZIzj0EAwIwZzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMRQwEgYDVQQKDAtDbG91ZGVudGl0eTEjMCEGA1UEAwwaYWNwLnYxNi5jbG91ZGVudGl0eS1zZS5jb20wHhcNMjEwMTMwMjA0NjAyWhcNMzEwMTI4MjA0NjAyWjBnMQswCQYDVQQGEwJVUzELMAkGA1UECAwCV0ExEDAOBgNVBAcMB1NlYXR0bGUxFDASBgNVBAoMC0Nsb3VkZW50aXR5MSMwIQYDVQQDDBphY3AudjE2LmNsb3VkZW50aXR5LXNlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOR9TaT/mEyWzsDPjP/MJOXeDBUgPtmyBF8K/drzl05T48cfpJpP9EuERXYIyJXgwaQPMCqtccBKV42Ec9kkZVejUzBRMB0GA1UdDgQWBBR0XtNqn673m+X0lVlTxjWWk12fCTAfBgNVHSMEGDAWgBR0XtNqn673m+X0lVlTxjWWk12fCTAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0gAMEUCIA7ajABMU1Q5sFoa1vVvN7IBaFzCZPCvalhYDM8TxfyqAiEAq6bkOL4vuAPZtq7RPFIQPBzly6mfZuA30ciK6Sc4ab0=\"\t\t\t\t],\t\t\t\t\"x5t\": \"6xfvlWhPypSwWGct_WXzjENOHNk\",\t\t\t\t\"x5t#S256\": \"mrRCyDKOreVilIQmcz2HSWQD5PGzMaIMqaKkpZEy2Zs\"\t\t\t}\t\t]\t}, \"enforce_pkce\": false, \"enforce_pkce_for_public_clients\": false, \"root_cas\": \"\", \"read_client_certificate_from_header\": false, \"client_certificate_header\": \"\", \"subject_identifier_types\": [ \"public\", \"pairwise\" ], \"subject_identifier_algorithm_salt\": \"IASuYx0ffeiRJGnzkqCmcY-gH0HnGKMT9fFRlFvSrNQ\"}"