Skip to content

Expose Keycloak SSO session lifetimes as KOTS config options#694

Merged
ak684 merged 1 commit into
mainfrom
alona/keycloak-session-timeouts
Jun 9, 2026
Merged

Expose Keycloak SSO session lifetimes as KOTS config options#694
ak684 merged 1 commit into
mainfrom
alona/keycloak-session-timeouts

Conversation

@ak684

@ak684 ak684 commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add KOTS options keycloak_sso_session_idle_timeout (default 1800) and keycloak_sso_session_max_lifespan (default 36000) under Advanced Options, with numeric validation.
  • Wire them through new parent-chart values keycloak.ssoSessionIdleTimeout / keycloak.ssoSessionMaxLifespan.
  • Apply them to the rendered realm JSON with jq in the keycloak-config init container (the realm template must stay valid JSON). They flow through both the realm-create and realm-update paths, so changing the KOTS value updates a live install on the next deploy.

Why

The allhands realm hardcodes a 30-minute idle timeout and 10-hour max session lifespan. Every Keycloak session expiry forces a fresh brokered IdP login, and for OAuth2 providers like Bitbucket Data Center each re-login records a new authorized-application grant on the user's Bitbucket account. Bitbucket DC has no token-revocation API (UI-only), so a Replicated customer accumulated 20 duplicate "Openhands Enterprise" entries. Session length is the only lever we control. Defaults are unchanged.

Testing

  • scripts/test_keycloak_realm_template.py: new tests assert the config script applies both values and run the script's actual jq filter against the realm template (8/8 pass).
  • Helm-rendered the config script with defaults, overrides, and KOTS-style string values.

🤖 Generated with Claude Code

The allhands realm hardcoded ssoSessionIdleTimeout=1800 (30 min) and
ssoSessionMaxLifespan=36000 (10 h). Every Keycloak session expiry sends
users back through the brokered identity provider login; for OAuth2
providers like Bitbucket Data Center each of those re-logins records a
new authorized-application grant on the user's account (Bitbucket DC has
no revocation API, so grants accumulate visibly).

Expose both lifetimes as KOTS options (Advanced Options) wired through
keycloak.ssoSessionIdleTimeout / keycloak.ssoSessionMaxLifespan chart
values. The values are applied to the rendered realm JSON with jq so the
realm template stays valid JSON, and they flow through both the
realm-create and realm-update paths of the keycloak-config init
container, so changes take effect on live installs at the next deploy.
@ak684 ak684 requested a review from all-hands-bot June 9, 2026 22:27

all-hands-bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Review complete.

This review was performed through OpenHands Cloud Automation. You can log in and view the conversation here.

@all-hands-bot all-hands-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

🟢 Good taste — Elegant, pragmatic solution to a real production problem.

Analysis

This PR exposes Keycloak SSO session lifetimes as configurable options to solve a legitimate issue: every session expiry forces a fresh Bitbucket Data Center OAuth2 login, which accumulates duplicate "authorized-application" grants on user accounts (Bitbucket DC has no revocation API).

Design choices that work:

  • Using jq to apply numeric session lifetimes after template rendering keeps the realm template valid JSON — the right tool for the job.
  • The values flow through both realm-create and realm-update paths, so changes take effect on a live install at the next deploy.
  • Validation uses ^[1-9][0-9]*$ to reject zero, negative numbers, and leading zeros — appropriate for timeout values.
  • Tests run the actual jq filter against the real realm template, verifying end-to-end behavior rather than just mocking function calls.

No critical issues found. The code is clean, well-documented in the PR description, and defaults are unchanged.

[RISK ASSESSMENT]

  • [Overall PR] ⚠️ Risk Assessment: 🟢 LOW
    This is a Helm/KOTS configuration change that only affects Keycloak session timeouts. Existing behavior is preserved by default (1800s idle, 36000s max lifespan). No breaking changes to APIs, data flows, or security boundaries.

VERDICT:
Worth merging — Core logic is sound, well-tested, and solves a real problem with minimal complexity.

KEY INSIGHT:
The jq-after-envsubst pattern is the right approach here: it keeps the JSON template clean while allowing Helm to inject computed values into the final realm configuration.


This review was generated by an AI agent (OpenHands) on behalf of the user through OpenHands Automation. View conversation

@ak684 ak684 merged commit ebe991a into main Jun 9, 2026
27 checks passed
@ak684 ak684 deleted the alona/keycloak-session-timeouts branch June 9, 2026 22:34
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.

2 participants