Elegem lett abból, hogy a Grafanához, ArgoCD-hez, Harborhoz és minden más belső toolhoz külön loginokat kelljen kezelnem. Minden új csapattag öt fiók létrehozását jelentette. Minden offboarding azt, hogy reménykedtem, mindegyiket visszavontam. Szóval végre leültem és felraktam a Keycloak-ot a Kubernetes klaszterünkre.

Ez az, ami tényleg történt, nem a megszépített verzió.

Miért Keycloak

Megnéztem a Dex-et, az Authelia-t és a Keycloak-ot. A Dex könnyű, de korlátozott, ha többre van szükséged, mint OIDC proxy. Az Authelia egyszerű setupokra kiváló, de a mi use case-ünkhöz kevés volt. A Keycloak nehezebb, viszont kezeli az OIDC-t, SAML-t, user federation-t, és van rendes admin UI-ja. Egy csapatnak, ami 8+ belső service-t futtat, a súlya indokolt.

A Helm Chart

A Bitnami Keycloak chartot használtam. Létezik a hivatalos Keycloak operátor is, de egyszerűbb induláshoz a Helm jobb volt.

helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

helm install keycloak bitnami/keycloak \
  --namespace keycloak \
  --create-namespace \
  --set auth.adminUser=admin \
  --set auth.adminPassword=changeme-obviously \
  --set postgresql.enabled=true \
  --set postgresql.auth.postgresPassword=also-changeme \
  --set proxy.enabled=true \
  --set proxy.edge=true \
  --set ingress.enabled=true \
  --set ingress.hostname=sso.internal.example.com \
  --set ingress.tls=true \
  --set ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-prod

A proxy.edge=true flag kritikus, ha az ingress-nél terminálod a TLS-t. Enélkül a Keycloak azt hiszi, HTTP-n fut, és rossz redirect URI-kat generál. Egy órát töltöttem ezzel, mielőtt rendesen elolvastam a doksikat.

Az adatbázis kérdés

A Bitnami chart alapból tartalmaz PostgreSQL-t. Prodra átváltottam külső PostgreSQL instance-ra. Adatbázist futtatni Kubernetes-ben dev-re oké, de az identity providerednél olyat akarsz, amiben megbízol.

# values-production.yaml
postgresql:
  enabled: false
externalDatabase:
  host: postgres.internal.example.com
  port: 5432
  user: keycloak
  database: keycloak
  existingSecret: keycloak-db-secret
  existingSecretPasswordKey: password

Realm beállítás

Egyetlen realm-et hoztam létre internal néven az összes toolunkhoz. Egy realm, több OIDC kliens. Minden tool saját klienst kap, saját redirect URI-kkal.

# Admin console-ba bejelentkezés után
# Realm létrehozása: internal
# Kliens létrehozása: grafana
#   Client ID: grafana
#   Root URL: https://grafana.internal.example.com
#   Valid redirect URIs: https://grafana.internal.example.com/login/generic_oauth
#   Client authentication: ON
#   Client secret másolása

Grafana bekötése

A Grafana OIDC integrációja egyértelmű. A grafana.ini-ben vagy Helm values-on keresztül:

[auth.generic_oauth]
enabled = true
name = Keycloak
allow_sign_up = true
client_id = grafana
client_secret = ${GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET}
scopes = openid profile email
auth_url = https://sso.internal.example.com/realms/internal/protocol/openid-connect/auth
token_url = https://sso.internal.example.com/realms/internal/protocol/openid-connect/token
api_url = https://sso.internal.example.com/realms/internal/protocol/openid-connect/userinfo
role_attribute_path = contains(realm_access.roles[*], 'admin') && 'Admin' || 'Viewer'

Az utolsó sor a Keycloak role-okat Grafana role-okra mappeli. Akinek admin role-ja van Keycloak-ban, az Grafana Admin lesz. Mindenki más Viewer. Egyszerű, hatékony.

Az ArgoCD trükkösebb volt

Az ArgoCD alapból Dex-et használ belsőleg OIDC-hez. Vagy a Dex-et konfigurálod, hogy a Keycloak-kal beszéljen, vagy kihagyod a Dex-et és közvetlenül a Keycloak-ra irányítod az ArgoCD-t. Én a közvetlen megoldást választottam.

Az ArgoCD ConfigMap-ben:

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  url: https://argocd.internal.example.com
  oidc.config: |
    name: Keycloak
    issuer: https://sso.internal.example.com/realms/internal
    clientID: argocd
    clientSecret: $oidc.keycloak.clientSecret
    requestedScopes:
      - openid
      - profile
      - email
      - groups    

A groups scope-hoz mapper kell Keycloak-ban. Az argocd kliensben, Mappers fül, új mapper:

  • Mapper type: Group Membership
  • Token claim name: groups
  • Full group path: OFF

Aztán az argocd-rbac-cm-ben:

data:
  policy.csv: |
    g, /devops-team, role:admin
    g, /developers, role:readonly    

A Keycloak csoportok közvetlenül ArgoCD role-okra mappolódnak. Ha valaki csatlakozik a csapathoz vagy elmegy, egy helyen kell frissítened.

A session és token buktató

Az alapértelmezett Keycloak token élettartamok rövidek. Kb. 5 perc az access tokenekre. Ez azt jelenti, hogy a felhasználóid folyton kijelentkeznek a Grafanából. Emeld meg az access token élettartamát a realm beállításokban valami ésszerűre:

  • Access Token Lifespan: 30 perc
  • SSO Session Idle: 8 óra
  • SSO Session Max: 24 óra

Ez egy normál munkanaphoz passzol. Az emberek reggel egyszer belépnek, és kész.

Health check-ek és readiness

A Keycloak health endpoint-ja változott a verziók között. Újabb verzióknál (22+):

livenessProbe:
  httpGet:
    path: /health/live
    port: http
readinessProbe:
  httpGet:
    path: /health/ready
    port: http

Régebbi verziónál mások az útvonalak. Nézd meg a saját verziód doksijait. 20 percet néztem, ahogy a podok újraindulnak, mert a readiness probe 404-et kapott.

Mit csinálnék másképp

A Keycloak Operátorral kezdenék. A Helm chart működik, de az operátor jobban kezeli az upgrade-eket, és a realm konfigurációt CRD-kként definiálhatod. Prodra ez tisztább.

Terraform-ot használnék a realm konfighoz. Van Keycloak Terraform provider, amivel a realm-eket, klienseket és mappereket kódként definiálhatod. Én először kézzel állítottam be mindent az UI-on, ami azt jelenti, most vissza kell fejtenem Terraform-ba. Ne ismételd meg a hibámat.

resource "keycloak_openid_client" "grafana" {
  realm_id    = keycloak_realm.internal.id
  client_id   = "grafana"
  name        = "Grafana"
  enabled     = true
  access_type = "CONFIDENTIAL"

  valid_redirect_uris = [
    "https://grafana.internal.example.com/login/generic_oauth"
  ]
}

Tervezd meg a csoport struktúrát korán. Elkezdtem felvenni a usereket csoportok nélkül, és később kellett átszerveznem. Döntsd el a csoport hierarchiát, mielőtt bárkit felveszel.

Az eredmény

Egy login mindenhez. Új csapattag bekerül a Keycloak-ba, hozzárendelődik a megfelelő csoportokhoz, és azonnal hozzáfér a Grafanához, ArgoCD-hez, Harborhoz és a belső wikinkhez. Offboarding: egy fiók törlés.

Kb. egy napba telt rendesen beállítani, beleértve a zsákutcákat. Ha háromnál több belső toolt kezelsz külön auth-tal, csináld meg. A befektetett idő egy héten belül megtérül.

A KubeCon Europe 2026 közeledtével és a KeycloakCon-nal mint társrendezvénnyel a projekt komoly lendületet kap. A közösség aktív, a dokumentáció javul, az operátor gyorsan érik. Jó időpont beszállni.