# keycloak Identity provider for SSO across all R&D services. **Cloud-only** for now (edges get their own realms once we cover the edge layer). - **Public hostname**: `auth.wbd-rd.nl` (reverse-proxied via nginx-proxy at HTTPS → backend HTTP 8080) - **Networks**: `app` (OIDC endpoints for relying-party apps) + `mgmt` (admin console) + `data` (postgres backend) - **Backend**: postgres `keycloak` database in `sql` stack — provisioned automatically by `sql/config/init.d/01-databases.sh` on first start - **Volume**: `keycloak-data` (themes, providers, realm exports) ## First-run bootstrap `KC_BOOTSTRAP_ADMIN_USERNAME` + `KC_BOOTSTRAP_ADMIN_PASSWORD` create the master-realm admin on first start. **Change the password immediately after first login** via the admin console. After deployment: ```bash # 1. Bring it up (sql must be running first) cd /mnt/d/gitea/RnD/infra/cloud docker compose up -d sql # if not already up docker compose up -d keycloak # 2. Watch logs until you see "Keycloak on JVM started" docker compose logs -f keycloak # 3. Browse https://auth.wbd-rd.nl/ → admin console # (until cert is bootstrapped, https://:9443 portainer can show logs) ``` ## Realm + clients (TODO — design before deploy day 2) **Recommended structure**: one realm `wbd` containing all R&D apps as separate clients. | Client ID | App | Redirect URI | Flow | |---|---|---|---| | grafana | Grafana | `https://dash.wbd-rd.nl/login/generic_oauth` | code | | gitea | Gitea | `https://git.wbd-rd.nl/user/oauth2/keycloak/callback` | code | | node-red | Node-RED | `https://flow.wbd-rd.nl/auth/strategy/callback/` | code | | jenkins | Jenkins | `https://ci.wbd-rd.nl/securityRealm/finishLogin` | code | | jupyterhub | JupyterHub | `https://hub.wbd-rd.nl/hub/oauth_callback` | code | | mlflow | MLflow (via oauth2-proxy) | `https://ml.wbd-rd.nl/oauth2/callback` | code | | portainer-ce | Portainer (via oauth2-proxy) | `https://ops.wbd-rd.nl/oauth2/callback` | code | Apps **without native OIDC** (mlflow, portainer-CE) sit behind an `oauth2-proxy` sidecar that nginx `auth_request`s to. That's a TODO stack we'll add when we wire up mlflow / portainer SSO. ## Realm-as-code Drop exported realm JSON into `config/realms/`. On first start, Keycloak imports anything in `/opt/keycloak/data/import/` if `KC_IMPORT_REALM_DIR` is set or if you run `kc.sh import` manually. Recommended workflow: 1. Configure the realm by hand once in the UI 2. `docker compose exec keycloak /opt/keycloak/bin/kc.sh export --dir /opt/keycloak/data/import --realm wbd` 3. Commit the exported file under `stacks/keycloak/config/realms/` 4. Subsequent fresh deploys auto-import ## TODO - Realm bootstrap script (provision `wbd` realm + clients above) - Theme: WBD branding (logo, colors) - User federation (LDAP from corporate AD, if applicable) - 2FA policy - Session / token lifetimes per client - oauth2-proxy stack for apps without native OIDC - Realm export → `config/realms/wbd.json` committed