# Keycloak - an OpenID Connect and SAML identity provider, deployed as a # TWO-NODE cluster against an external PostgreSQL. # # READ THIS FIRST, because three properties shape every value below and none of # them is obvious from the outside (Gitea #83). # # 1. THERE IS NO ConfigMap IN THIS CHART, AND THAT IS NOT AN OMISSION. # Keycloak is configured entirely through options - CLI arguments and KC_* # environment variables - so no file is rendered, mounted or hashed. The # repo's checksum/config rule (#82) therefore has nothing to attach to: # there is no ConfigMap whose change could fail to restart the workload. # What IS covered is the op:// PATH of the two vault items, through # checksum/secret-ref on the pod template. A change INSIDE an item still # restarts nothing - Helm never sees it - and NOTES.txt names the manual # rollout restart for that case. # # 2. THE CHART RUNS A BUILD STEP IN AN INIT CONTAINER, AND IT HAS TO. # Keycloak distinguishes BUILD options from runtime options. Three of the # options this chart needs are build options - verified against the 26.8.0 # "All configuration" page, where each carries the tool icon: # db (default dev-file) # health-enabled (default false) # metrics-enabled (default false) # The published image is augmented with those DEFAULTS. Setting any of them # at runtime makes Keycloak re-augment itself at start, and the augmentation # rewrites four files INSIDE the install tree: # /opt/keycloak/lib/quarkus/{generated-bytecode.jar, # transformed-bytecode.jar,quarkus-application.dat, # build-system.properties} # (read out of the image layer itself, not inferred). Upstream says what # that start does, in the container guide: it "detects and applies the build # options first", which "significantly increases startup time and CREATES AN # IMAGE THAT IS MUTABLE". A mutable image is exactly what # readOnlyRootFilesystem: true forbids - so the stock image, probes on # /health and a read-only root filesystem are not a combination that can # start. And "then do not set db" is no way out: THE PROBES ALONE force the # augmentation, because health-enabled is a build option too. # # So an init container from the SAME image runs `kc.sh build` into an # emptyDir that the main container mounts at /opt/keycloak/lib/quarkus, and # the main container runs `start --optimized`. No second image to pin (this # repository publishes charts, not images), hardening intact, and the # augmentation happens once in the init container instead of inside the # serving container on every start. # # THE CONDITION THAT MAKES IT SAFE, and the line a later round will want to # "simplify": the two containers must never disagree about the build # options, because a disagreement makes the MAIN container re-augment - on # a path that is now read-only, i.e. a crash loop. This chart enforces that # structurally rather than by care: the build options exist in exactly one # place (the keycloak.buildArgs helper, which only the init container uses), # the main container passes `start --optimized` and NO build option at all, # and the render FAILS if a keycloak.env entry carries a build option's # variable name. Do not add a KC_DB, KC_HEALTH_ENABLED, KC_METRICS_ENABLED # or KC_FEATURES to the main container "for clarity". # # 3. NO PVC, AND NO StatefulSet. Keycloak 26 keeps everything in the database, # user sessions included (persistent user sessions are the default since 26; # volatile sessions are deprecated as of 26.8). There is no state on disk to # keep and no stable identity to preserve, so this is a Deployment - the # repo's StatefulSet rule is about STATEFUL applications, and here it would # be decoration. # Scale the whole chart down without uninstalling it: scaleDown: true renders # the Deployment with replicas: 0 and takes precedence over keycloak.replicas. # Secrets, Services and Ingresses stay in place; scaleDown: false brings the # workload back up. # # THIS IS ALSO HALF OF THE MINOR-UPGRADE PROCEDURE. Keycloak supports a rolling # update only inside a minor line, so a 26.8 -> 26.9 jump is: scaleDown: true, # back up configuration and database, change the version, scaleDown: false. # NOTES.txt has the sequence and the compatibility check that decides it. scaleDown: false secrets: # op:// path of the 1Password item carrying the database credentials. # REQUIRED - the chart has no default database and Keycloak does not start # without one. # # Must carry the fields: # username the database role -> KC_DB_USERNAME # password that role's password -> KC_DB_PASSWORD # # Host, port and database name are NOT in the vault: they are plain values # under keycloak.db below, because they are not secret and because putting # them in the item would mean editing a vault entry to move a database. # # THEY ARRIVE AS ENVIRONMENT VARIABLES, NOT AS FILES, and that is forced # rather than chosen. Keycloak 26 has no _FILE indirection for an option's # value: there is no KC_DB_PASSWORD_FILE and no generic KC_