openova/clusters
e3mrah 7ca9541ef9
fix(handover): provision Keycloak service-account credentials zero-touch (Phase-8b followup) (#691)
* fix(handover): provision Keycloak service-account credentials zero-touch (Phase-8b followup)

Sovereign-side catalyst-api needs Keycloak service-account credentials
to provision the operator's user during /auth/handover. Today the chart
references K8s Secret `catalyst-kc-sa-credentials` with keys addr/realm/
client-id/client-secret in the catalyst-system namespace — but no
zero-touch path materialised it. The dead SealedSecret template at
09a-keycloak-catalyst-api-secret.yaml had a different name AND different
keys (CATALYST_KC_*), used PLACEHOLDER_SEALED_VALUE markers no
provisioner replaced, and wasn't even listed in the bootstrap-kit
kustomization.

Symptom on otech48: GET /auth/handover?token=<valid-jwt> returns
"server misconfiguration: keycloak not configured"
(auth_handover.go:169).

Fix: bp-keycloak chart's configmap-sovereign-realm.yaml template now
emits the realm-import ConfigMap AND the catalyst-kc-sa-credentials
Secret in a single template scope so they share the same generated
client secret. Pattern mirrors platform/powerdns/chart/templates/
api-credentials-secret.yaml (canonical seam, ADR-0001 §11.3
anti-duplication).

Secret-value resolution order (first match wins):
  1. operator-supplied .Values.catalystApiServerClientSecret
  2. helm `lookup` of existing Secret in keycloak ns (idempotent)
  3. fresh randAlphaNum 32 (zero-touch on first install)

The Secret carries the four keys exactly as the catalyst-api Pod's
secretKeyRef expects — addr / realm / client-id / client-secret —
with addr derived from gateway.host (https://auth.<sovereignFQDN>).
Reflector annotations auto-mirror the Secret to catalyst-system as
soon as that namespace materialises (bootstrap-kit slot 13).

The realm import already creates the catalyst-api-server client with
serviceAccountsEnabled + impersonation/manage-users/view-users/
query-users role mappings — so once Keycloak is Ready and the realm
imports, the SA is fully provisioned and the K8s Secret carries a
matching client secret. No post-install Job, no Admin-API script,
no out-of-band SealedSecret ceremony.

Cleanup: removes the dead 09a SealedSecret template (not in
kustomization, never produced a working Secret).

Bumps:
  - bp-keycloak chart 1.3.0 -> 1.3.1
  - clusters/_template/bootstrap-kit/09-keycloak.yaml HelmRelease
    pin 1.3.0 -> 1.3.1

Existing per-Sovereign overlays (clusters/otech.omani.works/,
clusters/omantel.omani.works/) intentionally remain on 1.3.0 — fresh
otechN provisioning consumes _template at provision time.

Will be verified live on otech49 — handover end-to-end without ANY
manual Secret creation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(keycloak): bump blueprint.yaml spec.version to match chart 1.3.1

TestBootstrapKit_BlueprintCardsHaveRequiredFields/keycloak asserts
Chart.yaml.version == blueprint.yaml.spec.version. Forgot to bump
blueprint.yaml in the previous commit.

Note: 8 other blueprints (cert-manager, flux, crossplane, sealed-secrets,
spire, nats-jetstream, openbao, gitea) carry the same pre-existing
mismatch and the test fails on main too. Out of scope for this PR;
fixing the keycloak case to keep the new chart version internally
consistent.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: hatiyildiz <hatice@openova.io>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 19:50:06 +04:00
..
_template fix(handover): provision Keycloak service-account credentials zero-touch (Phase-8b followup) (#691) 2026-05-03 19:50:06 +04:00
contabo-mkt/tenants provision: deploy tenant test-2 (plan: m, apps: 1) 2026-05-02 22:18:35 +04:00
omantel.omani.works feat(catalyst-api): /auth/handover endpoint for seamless single-identity flow (Closes #606) (#612) 2026-05-02 17:34:26 +04:00
otech.omani.works feat(catalyst-api): /auth/handover endpoint for seamless single-identity flow (Closes #606) (#612) 2026-05-02 17:34:26 +04:00