Key Rotation - consumer

OIDC login flow

  • Adapter (application) redirects to Keycloak
  • Keycloak authenticates user
  • Keycloak creates token and sign with Keycloak private key
  • Keycloak sends token to the adapter
  • Adapter validates token with Keycloak public key

How is Keycloak public key known to the adapter?

2 possibilities

Hardcoded key in adapter config

                    {
                      "realm" : "demo",
                      "resource" : "product-portal",
                      "realm-public-key" : "MBcxwz46...",
                      ...
                    }
                

Key dynamically downloaded

  • Adapter downloads the public key from Keycloak
  • This supports key rotation.
  • Also supports more public keys available at the same time

Key rotation example flow

  • User authenticates. Token signed by private-key-1 sent
  • Adapter downloads public-key-1 from Keycloak
  • Adapter verifies token1

Example flow - continue

  • Admin rotates keys on Keycloak server and generates keypair2
  • Another user authenticates. Token signed by private-key-2 sent
  • Adapter downloads again new keys from Keycloak. Both key1 and key2
  • Adapter verifies token2
  • Tokens signed by token1 still supported
  • How adapter recognize it should download new keys?
  • How adapter recognize which public key to use?

KID (Key ID)

  • Keys published by Keycloak are in JWK format and have KID field on them
  • JWT tokens also have "kid" field - in the JWT header
  • Adapter downloads new key when recognize unknown "kid"

Implementation - adapter

  • PublicKeyLocator interface
  • field on KeycloakDeployment
  • HardcodedPublicKeyLocator - used when realm-public-key in keycloak.json
  • JWKPublicKeyLocator - used otherwise. Ability to dynamically download keys
  • New adapter option - min-time-between-jwks-requests

Keycloak as "consumer"

  • Used when Keycloak itself needs to download public keys of external entities
  • 2 cases:
    • OIDC Identity providers
    • Client auth with signed JWT

PublicKeyStorageProvider SPI

  • 1 impl based on infinispan
  • Used for both idp and clients
  • Again 2 possibilities:
    • Hardcoded key in config
    • JWKS URL (keys dynamically downloaded when needed. Again based on "kid")
  • Better performance than before (Keys cached locally)
  • 10 seconds timeout by default
  • Configurable eviction and expiration (at infinispan level)