Files
home-network-k3s-impl/catalog/keycloak.yaml
jakman85andClaude Opus 5.5 24db269ea8 feat(renovate): track the Keycloak operator (the real Keycloak version), never auto-merge it
The Keycloak CR has no spec.image, so the operator's RELATED_IMAGE_KEYCLOAK picks the
server image; the three keycloak-k8s-resources release URLs in
platform/keycloak/kustomization.yaml are therefore THE Keycloak version, and Renovate
could not see them (no `# renovate:` marker). They now carry markers under one depName
(one branch, groupName keycloak-operator), with a packageRule: automerge false, labels
needs-review + blast-radius; majors still wait on the dashboard.

The untagged quay.io/keycloak/keycloak in catalog/keycloak.yaml renders
apps/wave-1/keycloak.yaml, which no kustomization lists. It is pinned to the operator's
26.0.6 as documentation, re-rendered, and Renovate is disabled for that image so it
cannot raise PRs against a file nothing deploys. The render is kept (not deleted): it is
the fixture for apps/wave-1/tests/app-slis.test.yaml's keycloak SLI rule tests.

README: an "Upgrading Keycloak" section — an operator bump must be checked against
passkey-reconciler.yaml's 26.0.6 Admin API assumptions.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:02:25 -05:00

53 lines
2.9 KiB
YAML

# ServiceDefinition: keycloak
# Source of truth: spec docs/13-service-catalog.md row 0; docs/15-identity-and-access.md; ADR-0014.
# public IdP | egress internet | PostgreSQL on Longhorn (irreplaceable, DR-critical) | auth native.
# Keycloak IS the IdP (root of trust): its own admin login is local + MFA, so it does not federate.
# Validates against schemas/servicedefinition.schema.json.
name: keycloak
kind: container
# DOCUMENTATION-ONLY IMAGE. The running server is NOT chosen here: the Keycloak operator
# (platform/keycloak/kustomization.yaml, three pinned release URLs) picks it via its
# RELATED_IMAGE_KEYCLOAK, and the Keycloak CR has no spec.image. This SD's render,
# apps/wave-1/keycloak.yaml, is not listed in apps/wave-1/kustomization.yaml and deploys nothing
# (ci/render-golden.sh RENDER_GOLDEN_NOT_ONBOARDED). The tag records the operator's version for
# readers; renovate.json5 disables Renovate for this image so it cannot raise PRs against a file
# nothing deploys. The Keycloak version moves with the operator — update this tag by hand then.
source:
image: quay.io/keycloak/keycloak:26.0.6
exposure: public # login/redirect flows for internet-exposed services; hardened (docs/15; R-DNS/R-NET)
egress: internet # normal WAN egress (docs/03; R-NET-05)
storage:
- name: db
size: 10Gi
class: longhorn # PostgreSQL on 3-replica Longhorn; irreplaceable (docs/15, docs/04; R-STATE-02)
dependencies:
- to: keycloak-db # explicit allow: Keycloak -> its PostgreSQL (docs/13 graph; R-NET-02)
port: 5432
protocol: tcp
ingressRoutes:
- host: keycloak.${BASE_DOMAIN}
port: 8080 # HTTP listener; TLS terminates at the Gateway (docs/08, docs/09)
auth:
mode: native # it IS the IdP; own admin login is local + MFA (docs/15; ADR-0014). Documented exception.
update:
channel: stable # R-UPD-01
range: ">=24.0.0"
cadence: "0 4 * * *"
autoRollbackOnFailedHealth: true # R-UPD-03
observability:
metrics: true
slis:
- up # IdP down/unhealthy is a critical alert (docs/10; R-OBS-01)
# WHAT "up" IS for Keycloak. The Keycloak OPERATOR runs the server as a StatefulSet named
# `keycloak` (pods keycloak-0/1), not as the Deployment this ServiceDefinition would otherwise
# imply — the operator owns the workload (platform/keycloak/keycloak-instance.yaml) and this SD
# is the catalog's declaration of intent for it. Without this override the rendered SLI would
# read a Deployment series that does not exist and its `absent()` half would fire FOREVER.
# Verified on prod 2026-09-13: kube_statefulset_status_replicas_ready{namespace="keycloak",
# statefulset="keycloak"} = 2, and the only Deployment in that namespace is keycloak-operator.
livenessWorkload:
kind: StatefulSet
name: keycloak
backup:
policy: daily-offcluster # DR-critical: rebuilds from DB + git realm config (docs/15, docs/04; R-STATE-03)