Skip to content

Implement automatic key rotation for realm keys#45091

Open
volck wants to merge 2 commits intokeycloak:mainfrom
volck:#11693_realmkey_rotation
Open

Implement automatic key rotation for realm keys#45091
volck wants to merge 2 commits intokeycloak:mainfrom
volck:#11693_realmkey_rotation

Conversation

@volck
Copy link

@volck volck commented Dec 28, 2025

Adds scheduled task that automatically rotates realm signing and encryption keys based on configurable rotation periods. This addresses the security concern of long-lived keys and reduces operational burden.

Key features:

  • Configurable rotation period per key provider
  • Automatic expiration of passive keys after grace period
  • Optional automatic deletion of disabled keys
  • Prometheus metrics for monitoring rotation events
  • Admin events for audit trail
  • Support for RSA, ECDSA, HMAC, and AES key providers

The rotation task runs as part of the existing scheduled tasks infrastructure and is cluster-aware to prevent race conditions.

Closes #11693

Adds scheduled task that automatically rotates realm signing and
encryption keys based on configurable rotation periods. This addresses
the security concern of long-lived keys and reduces operational burden.

Key features:
- Configurable rotation period per key provider
- Automatic expiration of passive keys after grace period
- Optional automatic deletion of disabled keys
- Prometheus metrics for monitoring rotation events
- Admin events for audit trail
- Support for RSA, ECDSA, HMAC, and AES key providers

The rotation task runs as part of the existing scheduled tasks
infrastructure and is cluster-aware to prevent race conditions.

Closes keycloak#11693

Signed-off-by: Emil Volckmar Ry <emilvry@gmail.com>
@volck volck requested a review from a team as a code owner December 28, 2025 17:08
@volck
Copy link
Author

volck commented Jan 19, 2026

@stianst I dont know who to tag, but is some one going to review this soon?

@ahus1
Copy link
Member

ahus1 commented Feb 15, 2026

@volck - thank you for this PR. I see some emoji, it would be great if someone of those people would help to assess this PR.

Some things I notice:

  • When setting an deletion time, keys need to be around so that they exceed the maximum idle time for any of the session types in the realm. Assuming that offline sessions could be idle for several days this should be validated. Maybe the deletion time could be derived from those settings instead leaving it to the user to configure it manually.
  • Please post some screenshots of your UIs as they are presented the user, this helps with the review.
  • There might be blocker as key rotation might not be work yet in all places. This needs at least a review - who can help? First possible issue identified: The RestartLoginCookie does not allow for key rotation as it always uses the active key for verification #46350

@volck
Copy link
Author

volck commented Feb 16, 2026

@ahus1 thanks for getting back to me! Please see attached screenshots:
this is adding a new provider:
image

  • this is from the "edit provider" in realmkeys:
image ...when a key is set to be rotated:

in console we get the following messages:

2026-02-16 09:03:55,937 INFO [org.keycloak.services.scheduled.AutomaticKeyRotationTask] (Timer-0) Automatic key rotation task: 1 providers with auto-rotation enabled, rotated=0, expired=0, deleted=0 keys in 3 ms, next run in 900 seconds 2026-02-16 09:18:55,981 INFO [org.keycloak.services.scheduled.AutomaticKeyRotationTask] (Timer-0) ROTATING KEY for provider 'rsa-enc-generated' (id=f82ee2b3-120b-4a08-a3ac-51a15b8d9640) in realm 'master' 2026-02-16 09:18:59,088 INFO [org.keycloak.services.scheduled.AutomaticKeyRotationTask] (Timer-0) Automatic key rotation activated: Created and configured new key provider 'rsa-enc-generated-1771229936000' (id=5fd75630-8a93-4777-8b4f-b0a730241b57) for realm 'master' 2026-02-16 09:18:59,090 INFO [org.keycloak.services.scheduled.AutomaticKeyRotationTask] (Timer-0) Automatic key rotation task: 1 providers with auto-rotation enabled, rotated=1, expired=0, deleted=0 keys in 3154 ms, next run in 900 seconds 2026-02-16 09:33:56,012 INFO [org.keycloak.services.scheduled.AutomaticKeyRotationTask] (Timer-0) Disabled expired passive key provider 'rsa-enc-generated' in realm 'master' at 1771230836004 2026-02-16 09:33:56,021 INFO [org.keycloak.services.scheduled.AutomaticKeyRotationTask] (Timer-0) ROTATING KEY for provider 'rsa-enc-generated-1771229936000' (id=5fd75630-8a93-4777-8b4f-b0a730241b57) in realm 'master' 2026-02-16 09:33:58,777 INFO [org.keycloak.services.scheduled.AutomaticKeyRotationTask] (Timer-0) Automatic key rotation activated: Created and configured new key provider 'rsa-enc-generated-1771230836034' (id=b86572c1-a1f1-4a5b-bd7c-94d0014fc130) for realm 'master' 2026-02-16 09:33:58,781 INFO [org.keycloak.services.scheduled.AutomaticKeyRotationTask] (Timer-0) Automatic key rotation task: 2 providers with auto-rotation enabled, rotated=1, expired=1, deleted=0 keys in 2843 ms, next run in 900 seconds 2026-02-16 09:48:55,938 INFO [org.keycloak.services.scheduled.AutomaticKeyRotationTask] (Timer-0) ROTATING KEY for provider 'rsa-enc-generated-1771230836034' (id=b86572c1-a1f1-4a5b-bd7c-94d0014fc130) in realm 'master' 2026-02-16 09:48:56,851 INFO [org.keycloak.services.scheduled.AutomaticKeyRotationTask] (Timer-0) Automatic key rotation activated: Created and configured new key provider 'rsa-enc-generated-1771231735955' (id=ffc54da8-77a0-4c4d-9a1e-97f33c828178) for realm 'master' 2026-02-16 09:48:56,863 INFO [org.keycloak.services.scheduled.AutomaticKeyRotationTask] (Timer-0) Disabled expired passive key provider 'rsa-enc-generated-1771229936000' in realm 'master' at 1771231736854 2026-02-16 09:48:56,865 INFO [org.keycloak.services.scheduled.AutomaticKeyRotationTask] (Timer-0) Automatic key rotation task: 3 providers with auto-rotation enabled, rotated=1, expired=1, deleted=0 keys in 927 ms, next run in 900 seconds

image

For the deletion/retention period: Ican try to derive the minimum passive key retention as max(ssoSessionMaxLifespan, ssoSessionMaxLifespanRememberMe, offlineSessionMaxLifespan, clientOfflineSessionMaxLifespan) plus a configurable safety margin, and validate user-configured values against this floor. Is this a good first stab?

As for #46350, could we expire the cookie by default when a key is outside of both deletion periods?

Passive keys must remain available at least as long as the longest-lived
session type in the realm to ensure tokens signed with those keys can
still be verified. This change:

- Add computeMinimumPassiveKeyRetention() that computes max(all session
  timeouts) + safety margin (10%, min 1 hour)
- Enforce session-derived minimum in expirePassiveKeys(), logging a
  warning when the configured expiration is overridden
- Propagate deletion settings (autoDeleteDisabledKeys, deletionGracePeriod)
  to newly created providers during key rotation
- Fix duplicate imports and indentation in rotateKey()
- Add tests for session-aware retention guardrails
- Fix test cleanup to catch rotated provider names
- Fix testAutomaticKeyDeletion JPA L1 cache issue (use getComponentsStream)

Closes keycloak#46350
@volck
Copy link
Author

volck commented Feb 16, 2026

Added b60f7ee which derives the minimum passive key retention period from the realm's session timeout settings (max of all session types + a safety margin of 10%, minimum 1 hour). This prevents keys from being expired before long-lived sessions (e.g. offline sessions) have a chance to verify tokens signed with them. Added tests for the guardrail. If someone could verify I'd appreciate it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Automatic realm key rotation

2 participants