Skip to main content

identity-service

Purpose

identity-service is the Keycloak-backed IAM for OpenBox. Issues OIDC tokens, manages user accounts + realms + clients, and enforces MFA / SSO federation if configured. The openbox-backend and openbox-fe are both OIDC clients of this service.

Plane: Control plane.

Ports & endpoints

PortProtocolPurposeExposed via
8080HTTPSKeycloak admin + realm endpointsIstio Gateway (public)
8080/realms/openbox/protocol/openid-connect/*OIDCToken endpoints for openbox-backend + openbox-fePublic via ingress
8080/admin/master/console/HTMLAdmin console (accessed by ops)Public via ingress; consider ZTNA gate
9000/healthHTTPKeycloak health probesK8s kubelet
9000/metricsHTTPPrometheus scrapeCluster-internal

Realms shipped by chart:

  • master — admin realm (bootstrap creds provisioned by chart)
  • openbox — application realm (users + clients live here)

Runtime

PropertyValue
Container count per pod1 (Keycloak on JVM)
Resource requests200m CPU / 1700 Mi RAM
Resource limits500m CPU / 2 Gi RAM
HPA min → max replicas3 → 5 (Keycloak HA requires ≥ 3)
HPA targetCPU 60%
Node placementGeneral CPU pool
Startup time~2-3 min (JVM warmup + DB schema migration)

JVM footprint is the reason for the high RAM request. Set -Xms / -Xmx via KEYCLOAK_JAVA_OPTS env if you need to bound heap tighter.

Configuration

Chart values keys (top-level identity-service.*)

KeyPurpose
enabledToggle whole service (rarely disabled)
replicaCountStatic; ignored when HPA on. Chart default 3 for HA
image.repository / image.tagContainer image (quay.io/keycloak/keycloak:XX.X default)
secret.stringData.KC_DB_PASSWORDRequired — Keycloak DB password
secret.stringData.KC_BOOTSTRAP_ADMIN_PASSWORDRequired — bootstrap admin password. Rotate immediately after first login.
db.host / .port / .nameExternal DB (else uses in-cluster PG)
db.userSecretRefK8s Secret with username + password for DB user

Runtime env vars

  • KC_DB_URL — JDBC URL for identity Postgres
  • KC_DB_USERNAME, KC_DB_PASSWORD — from secret refs
  • KC_HOSTNAME — public URL (used in token iss claim)
  • KC_PROXY_HEADERSxforwarded if behind ALB/NGINX
  • KEYCLOAK_ADMINadmin bootstrap user
  • KEYCLOAK_ADMIN_PASSWORD — from bootstrap secret (rotate!)

IAM permissions

None required — Keycloak does not call AWS APIs.

Dependencies

Downstream

TargetProtocolPurpose
openbox-identity-postgresqlJDBC :5432Realm + user + token storage

Upstream

  • openbox-backend — OIDC verification, token endpoint
  • openbox-fe — browser-side OIDC redirects
  • End users (via browser) — login flow

Deployment guidelines

Prod

  • Keep replicaCount: 3+ — Keycloak requires ≥ 3 for its Infinispan cluster consensus
  • Use external RDS — do not run in-cluster Postgres for identity data in prod
  • Set KC_HOSTNAME to your public FE URL (token iss claim must match)
  • Enable session sticky affinity on ingress (Keycloak sessions are node-local unless clustered — Infinispan handles this once ≥ 3 replicas)
  • Rotate bootstrap admin password immediately after first login. Chart provisions a random one, but you should replace + document it
  • Configure SSO federation (SAML / OIDC) if your org has existing IdP — Keycloak Admin Console → Identity Providers

Local PoC

  • replicaCount: 1 — HA irrelevant on laptop
  • In-cluster PG (Bitnami) is fine
  • Skip session affinity

Troubleshooting

Pod Running but backend logs "Cannot connect to identity service" → Keycloak still bootstrapping (JVM + DB migration). Takes ~2-3 min on cold start. kubectl logs deploy/identity-service — look for Keycloak … started. Backend retries auto-fix once ready.

Login page loads, but submit returns 500 → Realm openbox not created OR bootstrap admin password wrong. Log into /admin with bootstrap creds; verify realm exists + import if missing.

Token returned but backend rejects it (invalid_issuer)KC_HOSTNAME mismatch. Token iss claim = https://<KC_HOSTNAME>/realms/openbox, but backend expects a different value. Fix env.KC_HOSTNAME in values, helm upgrade, restart.

Keycloak Infinispan cluster split-brain (3 pods but session errors) → Pods can't reach each other for cluster sync. Check NetworkPolicy — Keycloak needs peer-to-peer port 7800 (JGroups) between its own pods. Chart's default NetworkPolicy allows this; if you've added a custom one, allow ingress from same-app pods.

High RAM usage / OOMKilled → JVM heap unbounded. Set KEYCLOAK_JAVA_OPTS="-Xms512m -Xmx1500m" and bump resources.limits.memory to 2 Gi (chart default).

Bootstrap password lost → Cannot recover from Keycloak (bcrypt hashed). Recovery: kubectl exec into a pod, run /opt/keycloak/bin/kc.sh in admin mode to re-add an admin user, or destroy + reinstall the realm (lose users too). Rotate immediately after install to avoid this trap.