# login — Keycloak Operator-managed instance Keycloak HA deployment for `login.olb42.com`, managed by the official Keycloak Operator. Backs all OIDC authentication across the home-lab. ## Architecture - **Namespace**: `login` - **Operator namespace**: `keycloak-system` - **Database**: CNPG cluster `login-postgres` (2 instances, `local-postgres` storage) - **Replicas**: 2 Keycloak pods with Infinispan jdbc-ping cluster discovery - **Ingress**: `login.olb42.com` via Traefik IngressRoute (no CF Access — bypass) ## Bootstrap order 1. ArgoCD applies `login-operator` ApplicationSet → Keycloak Operator deployed 2. ArgoCD applies `login` ApplicationSet → CRDs reconciled: - CNPG Cluster `login-postgres` created - `Keycloak` CR reconciled → Operator deploys Keycloak pods - `KeycloakRealmImport` applied → `home-lab` realm created - IngressRoute activates `login.olb42.com` ## Sealing the admin secret ```bash # Edit admin.secret.plain.yaml with your chosen password, then: kubeseal --context homelab-argocd \ --secret-file manifest/overlays/production/admin.secret.plain.yaml \ --sealed-secret-file manifest/overlays/production/admin.sealed.secret.yaml ``` ## Adding a per-app Keycloak client Create a `KeycloakRealmImport` in the app's own repo: ```yaml apiVersion: k8s.keycloak.org/v2alpha1 kind: KeycloakRealmImport metadata: name: my-app-client namespace: login # must match the Keycloak CR namespace spec: keycloakCRName: keycloak # must match the Keycloak CR name realm: realm: home-lab clients: - clientId: traefik-oidc-my-app ... ``` ArgoCD syncs the `KeycloakRealmImport` → Operator registers the client in Keycloak → Operator writes `traefik-oidc-my-app` secret → traefikoidc Middleware references it. ## Upgrading Keycloak 1. Update `image: quay.io/keycloak/keycloak:` in `keycloak-instance.yaml` 2. Update the operator remote URL version in `manifest/operator/kustomization.yaml` 3. Commit and push — ArgoCD self-heals both ApplicationSets in order