Use different signing key and certificate pairs per configured client or IDP

From the official documentation and experimenting (with the Keycloak Admin Console, import/export and Terraform provider) I understand that the highest prio RSA key is used for the following:

  • OAuth/OIDC clients: Keycloak signs the issued JWTs with it.
  • SAML IDP connection (“SAML clients”): Keycloak signs the generated SAML Responses with it.
  • SAML SP connections (“Identity Providers”). Keycloak signs the generated SAML AuthnRequests with it.

Is it possible to decouple these?

The problem I am trying to solve is the following:

  • Keycloak is used in PROD with the initial (self-generated, environment specific) realm RSA key+certificate, which has a validity of 10 years
  • now we are about to connect the first SAML IDP (“Identity Provider” in terms of Keycloak, so Keycloak acting as SAML SP)
  • the owner of the remote IDP has strict expectations about the certificate to be used for signing and verifying the signature of the SAML AuthnRequests: a CA signed certificate must be used
  • in case we change the Keycloak operational realm RSA key+certificate (or simply add a new with a higher priority), some of the connected OAuth clients will need to be forced to use the new certificate (unless they are able to get it from the JWK’s URI). Some apps might need a config change (or a restart). SPA apps might need a browser refresh to get the latest well-known-config (+ JWK URI info). Some of these apps are not in our sphere of influence so restarting or changing a config would lead to service disruption. In case of SPAs we are not able to force all users to make a refresh, so weird things could happen (authorization issues maybe redirect loops) until the latest JWK data is loaded.

Certificate and key management is complex and I see the advantages of DRY-ing out the number of keys+certs used, but it would be great to be able to specify (or just override) the key+cert per configured client (SAML/OIDC/OAuth) and/or IDP broker (SAML/OIDC/OAuth) connection. Then each certificate could have their own lifecycle (like the SIG and ENC realm key+cert pairs already do!).

I am aware that Keycloak gracefully accepts (validates) JWTs signed with a lower priority key+cert (e.g. when calling the REST admin API or userinfo), but it issues new JWTs (and also SAML messages) with the new realm RSA key+cert. This is handy, but solves a different problem.

Another likely scenario would be the use-case of multiple remote IDPs connected to the same Keycloak broker (acting as SAML SP towards multiple remote IDPs): imagine having tens of IDPs connected.
How should the realm certificate be rotated so that we avoid service disruptions? It’s kind of impossible to rotate the certificate trust in each remote IDP at the same time when those are owned/managed by different users from different timezones. Ideally we would like to be able to rotate one certificate at a time.

What would be the best practice to handle this kind of situations?
A possible workaround for the second use case I mentioned would be to add an extra realm for each connected IDP (with SSO from these IDP-SSO realms to the main operational realm). I am looking for something simpler if possible. Any ideas/hints would be appreciated :slight_smile: Thanks

1 Like