fix: add kubernetes OIDC client to realm config #214

Merged
claude merged 2 commits from fix/kubernetes-oidc-client into main 2026-02-22 14:05:43 +01:00
Owner

Summary

  • Add kubernetes OIDC client (Phase 15) to realm-configmap.yaml
  • Add direct-grant-no-otp auth flow for CLI/headless password grant
  • Without this, realm re-import would lose K8s OIDC authentication

Test plan

  • ArgoCD syncs keycloak app successfully
  • Keycloak admin console shows kubernetes client
  • OIDC kubeconfig auth still works after sync
## Summary - Add `kubernetes` OIDC client (Phase 15) to realm-configmap.yaml - Add `direct-grant-no-otp` auth flow for CLI/headless password grant - Without this, realm re-import would lose K8s OIDC authentication ## Test plan - [ ] ArgoCD syncs keycloak app successfully - [ ] Keycloak admin console shows kubernetes client - [ ] OIDC kubeconfig auth still works after sync
claude added 1 commit 2026-02-22 12:54:03 +01:00
fix: add kubernetes OIDC client + direct-grant-no-otp flow to realm config
All checks were successful
AI Review / AI Code Review (pull_request) Successful in 5s
PR Checks / Validate & Security Scan (pull_request) Successful in 10s
08b0c41f45
The kubernetes client (Phase 15) and direct-grant-no-otp auth flow were
created via API but missing from realm-configmap.yaml. A realm re-import
would lose these configurations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Owner

AI Code Review

Обзор PR: Добавление Kubernetes OIDC клиента

Хорошие решения

  • Правильная конфигурация direct-grant-no-otp для CLI (password grant без OTP)
  • PKCE S256 включена для публичного клиента
  • Правильные redirect URIs для localhost (urn:ietf + localhost:18000/8000)
  • Области по умолчанию разумные: profile, groups, email

⚠️ Критические проблемы

1. Противоречие конфигурации клиента

"publicClient": true,
"clientAuthenticatorType": "client-secret"
  • Публичный клиент НЕ должен иметь client-secret аутентификатор
  • Исправить: либо publicClient: false + secret, либо удалить clientAuthenticatorType для публичного

2. Отсутствует генерация client secret

  • Keycloak сгенерирует secret автоматически, но конфиг не указывает, где его сохранить
  • Проверить: процесс синхронизации secret → OpenBao secret/k8s/keycloak/kubernetes-client-secret (как для grafana/argocd)
  • Без этого kubelogin не сможет пройти аутентификацию

3. Недостаточно auth flow executors

  • direct-grant-no-otp имеет только username/password валидаторы
  • Добавить: direct-grant-validate-otp с requirement: "OPTIONAL" (на случай, если MFA будет включена позже)
  • Иначе flow сломается при включении MFA для пользователя

🔒 Безопасность

4. webOrigins пуст (потенциально)

"webOrigins": []
  • Если используется браузерный flow (kube-apiserver OIDC) → добавить Kubernetes API URL
  • Если только CLI → OK, но задокументировать причину

5. Нет ограничений на scope

  • Клиент имеет доступ ко всем default scopes
  • Рассмотреть минимальные scope: только openid + groups (без profile/email для API)

📋 Минор

  • Тестирование (test plan) включает проверку, но нужно явно проверить:
    • kubelogin успешно получает token
    • RBAC работает (oidc:infra-admins → cluster-admin)
    • Token refresh работает

Рекомендуемые правки

{
  "clientId": "kubernetes",
  "publicClient": false,  # ← FIX: true → false
  "clientAuthenticatorType": "client-secret",
  "standardFlowEnabled": false,  # ← не нужен браузерный flow
  "directAccessGrantsEnabled": true,
  "defaultClientScopes": ["openid", "groups"]  # ← минимум
}

Добавить в authenticationFlows:

{
  "authenticator": "direct-grant-validate-otp",
  "authenticatorFlow": false,
  "requirement": "OPTIONAL",  # ← fallback если MFA позже
  "priority": 2
}

Действие: Запросить правки перед merge. После синхронизации verify kubelogin + RBAC.


Automated review by Claude Haiku | advisory, does not block merge

## AI Code Review ## Обзор PR: Добавление Kubernetes OIDC клиента ### ✅ Хорошие решения - Правильная конфигурация `direct-grant-no-otp` для CLI (password grant без OTP) - PKCE S256 включена для публичного клиента - Правильные redirect URIs для localhost (urn:ietf + localhost:18000/8000) - Области по умолчанию разумные: profile, groups, email ### ⚠️ Критические проблемы **1. Противоречие конфигурации клиента** ``` "publicClient": true, "clientAuthenticatorType": "client-secret" ``` - Публичный клиент НЕ должен иметь `client-secret` аутентификатор - **Исправить:** либо `publicClient: false` + secret, либо удалить `clientAuthenticatorType` для публичного **2. Отсутствует генерация client secret** - Keycloak сгенерирует secret автоматически, но конфиг не указывает, где его сохранить - **Проверить:** процесс синхронизации secret → OpenBao `secret/k8s/keycloak/kubernetes-client-secret` (как для grafana/argocd) - Без этого kubelogin не сможет пройти аутентификацию **3. Недостаточно auth flow executors** - `direct-grant-no-otp` имеет только username/password валидаторы - **Добавить:** `direct-grant-validate-otp` с `requirement: "OPTIONAL"` (на случай, если MFA будет включена позже) - Иначе flow сломается при включении MFA для пользователя ### 🔒 Безопасность **4. webOrigins пуст (потенциально)** ``` "webOrigins": [] ``` - Если используется браузерный flow (kube-apiserver OIDC) → добавить Kubernetes API URL - Если только CLI → OK, но задокументировать причину **5. Нет ограничений на scope** - Клиент имеет доступ ко всем default scopes - Рассмотреть минимальные scope: только `openid` + `groups` (без profile/email для API) ### 📋 Минор - **Тестирование** (test plan) включает проверку, но нужно явно проверить: - kubelogin успешно получает token - RBAC работает (oidc:infra-admins → cluster-admin) - Token refresh работает ### Рекомендуемые правки ```yaml { "clientId": "kubernetes", "publicClient": false, # ← FIX: true → false "clientAuthenticatorType": "client-secret", "standardFlowEnabled": false, # ← не нужен браузерный flow "directAccessGrantsEnabled": true, "defaultClientScopes": ["openid", "groups"] # ← минимум } ``` Добавить в `authenticationFlows`: ```yaml { "authenticator": "direct-grant-validate-otp", "authenticatorFlow": false, "requirement": "OPTIONAL", # ← fallback если MFA позже "priority": 2 } ``` **Действие:** Запросить правки перед merge. После синхронизации verify kubelogin + RBAC. --- _Automated review by Claude Haiku | advisory, does not block merge_
claude added 1 commit 2026-02-22 13:24:46 +01:00
sec: remove plaintext passwords from realm ConfigMap
All checks were successful
AI Review / AI Code Review (pull_request) Successful in 1s
PR Checks / Validate & Security Scan (pull_request) Successful in 10s
65930ceb1e
Use keycloak-config-cli env var substitution $(env:VAR_NAME) to inject
user passwords from K8s Secret instead of hardcoding them in ConfigMap.

- realm-configmap.yaml: passwords replaced with $(env:KC_INFRA_ADMIN_PASSWORD)
  and $(env:KC_INFRA_CLAUDE_PASSWORD)
- keycloak ArgoCD app: added keycloakConfigCli.extraEnvVarsSecret
- Secrets sourced from OpenBao via create-keycloak-secrets.sh

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Owner

AI Code Review

K8s Manifest Review — fix/kubernetes-oidc-client

Issues Found

🔴 Critical

  1. Credentials in ConfigMap (2 instances)

    • Lines 54, 63: Переход на $(env:KC_*_PASSWORD) хорош, но — эти переменные должны быть инъектированы в config-cli Pod.
    • Проверьте: ArgoCD Application spec передаёт KC_INFRA_ADMIN_PASSWORD и KC_INFRA_CLAUDE_PASSWORD в config-cli контейнер? (via extraEnvVarsSecret или extraEnvVars?)
    • Без этого config-cli получит строку буквально "$(env:KC_INFRA_ADMIN_PASSWORD)" вместо реального пароля.
  2. kubernetes OIDC client — publicClient: true с clientAuthenticatorType: "client-secret"

    • Конфликт: public clients не должны иметь secret. Либо publicClient: true (уберите secret), либо publicClient: false (сохраните secret).
    • Для kubelogin flow (PKCE): используйте publicClient: true без clientAuthenticatorType.
  3. direct-grant-no-otp flow не привязан к клиенту

    • Добавлен authenticationFlows блок, но kubernetes OIDC клиент не ссылается на direct-grant-no-otp.
    • Нужно добавить "authenticationFlowBindingOverrides": { "direct_grant": "direct-grant-no-otp" } в kubernetes клиент.

🟡 Medium

  1. redirectUris — localhost hardcoded

    • http://localhost:18000/*, http://localhost:8000/* — не будут работать для kubelogin, используется обычно urn:ietf:wg:oauth:2.0:oob или callback.
    • Проверьте реальный redirect URI из kubelogin конфига.
  2. PKCE в attributes без явного включения

    • "pkce.code.challenge.method": "S256" установлен, но не ясно, требуется ли "pkce.code.challenge.required": true.

🟢 Minor

  1. authenticationFlows — builtIn: false, topLevel: true
    • Корректно для кастомного flow.

Проверка перед merge

  • В keycloak-configcli-secrets Secret: есть ли KC_INFRA_ADMIN_PASSWORD и KC_INFRA_CLAUDE_PASSWORD?
  • ArgoCD Application: extraEnvVarsSecret: keycloak-configcli-secrets уже добавлен (строка 48 в diff)?
  • Test kubelogin: kubelogin с OIDC realm успешно аутентифицируется?
  • Admin console: после синка видны ли оба OIDC клиента (grafana, argocd, gitea, kubernetes)?

Исправления

"kubernetes": {
  "clientId": "kubernetes",
-  "publicClient": true,
-  "clientAuthenticatorType": "client-secret",
+  "publicClient": true,
+  "directAccessGrantsEnabled": true,
+  "authenticationFlowBindingOverrides": {
+    "direct_grant": "direct-grant-no-otp"
+  },
  "redirectUris": [
    "urn:ietf:wg:oauth:2.0:oob"
  ],

Остановитесь перед merge — 3 критических точки требуют верификации.


Automated review by Claude Haiku | advisory, does not block merge

## AI Code Review # K8s Manifest Review — fix/kubernetes-oidc-client ## Issues Found ### 🔴 Critical 1. **Credentials in ConfigMap (2 instances)** - Lines 54, 63: Переход на `$(env:KC_*_PASSWORD)` хорош, но — эти переменные должны быть инъектированы в config-cli Pod. - **Проверьте:** ArgoCD Application spec передаёт `KC_INFRA_ADMIN_PASSWORD` и `KC_INFRA_CLAUDE_PASSWORD` в config-cli контейнер? (via `extraEnvVarsSecret` или `extraEnvVars`?) - Без этого config-cli получит строку буквально `"$(env:KC_INFRA_ADMIN_PASSWORD)"` вместо реального пароля. 2. **kubernetes OIDC client — publicClient: true с clientAuthenticatorType: "client-secret"** - Конфликт: public clients не должны иметь secret. Либо `publicClient: true` (уберите secret), либо `publicClient: false` (сохраните secret). - Для kubelogin flow (PKCE): используйте `publicClient: true` без `clientAuthenticatorType`. 3. **direct-grant-no-otp flow не привязан к клиенту** - Добавлен authenticationFlows блок, но kubernetes OIDC клиент не ссылается на `direct-grant-no-otp`. - Нужно добавить `"authenticationFlowBindingOverrides": { "direct_grant": "direct-grant-no-otp" }` в kubernetes клиент. ### 🟡 Medium 4. **redirectUris — localhost hardcoded** - `http://localhost:18000/*`, `http://localhost:8000/*` — не будут работать для kubelogin, используется обычно `urn:ietf:wg:oauth:2.0:oob` или callback. - Проверьте реальный redirect URI из kubelogin конфига. 5. **PKCE в attributes без явного включения** - `"pkce.code.challenge.method": "S256"` установлен, но не ясно, требуется ли `"pkce.code.challenge.required": true`. ### 🟢 Minor 6. **authenticationFlows — builtIn: false, topLevel: true** ✓ - Корректно для кастомного flow. ## Проверка перед merge - [ ] **В keycloak-configcli-secrets Secret:** есть ли `KC_INFRA_ADMIN_PASSWORD` и `KC_INFRA_CLAUDE_PASSWORD`? - [ ] **ArgoCD Application:** `extraEnvVarsSecret: keycloak-configcli-secrets` уже добавлен (строка 48 в diff)? - [ ] **Test kubelogin:** `kubelogin` с OIDC realm успешно аутентифицируется? - [ ] **Admin console:** после синка видны ли оба OIDC клиента (grafana, argocd, gitea, kubernetes)? ## Исправления ```diff "kubernetes": { "clientId": "kubernetes", - "publicClient": true, - "clientAuthenticatorType": "client-secret", + "publicClient": true, + "directAccessGrantsEnabled": true, + "authenticationFlowBindingOverrides": { + "direct_grant": "direct-grant-no-otp" + }, "redirectUris": [ "urn:ietf:wg:oauth:2.0:oob" ], ``` **Остановитесь перед merge** — 3 критических точки требуют верификации. --- _Automated review by Claude Haiku | advisory, does not block merge_
claude merged commit 39815af672 into main 2026-02-22 14:05:43 +01:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: claude/k8s-apps#214
No description provided.