Files
infra-keycloak/k8s
Stéphane Tailland eed8c3da3b refactor(realm): rename the token-exchange broker, drop the middleware's name
Every agent has to name this client in the audience scopes it requests, so the
one thing an agent could not avoid naming was the very thing it should know
nothing about. The gateway serving those URLs is replaceable; the contract
should not imply otherwise.

kong-token-exchange-broker becomes token-exchange-broker, same credential, same
behaviour. The rename was rolled out in order — new client alongside the old,
then the callers, then the gateways, then removal — so no call ever hit a realm
that had forgotten the name its caller was still using. Followed through the
client scope, the audience mappers, the fine-grained admin policy
allow-broker-client, and the roles map.

The Vault property keeps the old name. Renaming it there means re-issuing the
value to every gateway holding a copy, for no gain; the ExternalSecret maps it
to KC_SECRET_TOKEN_EXCHANGE_BROKER instead, so everything the cluster can see
is neutral.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 07:52:58 +02:00
..
2026-08-25 07:30:20 +02:00

Infra Keycloak (Kubernetes / CaC)

Déploiement de Keycloak 26.6.0 et PostgreSQL 16 en Configuration-as-Code (CaC) sous Kubernetes dans le namespace keycloak.

Structure du Répertoire

k8s/
├── kustomization.yaml             # Manifeste Kustomize principal
├── namespace.yaml                 # Namespace keycloak
├── secret.yaml                    # Secrets (Admin, DB, OIDC secrets)
├── secret.example.yaml            # Gabarit des secrets
├── postgresql/
│   ├── pvc.yaml                   # Stockage persistant PostgreSQL (2Gi)
│   ├── statefulset.yaml           # Base de données PostgreSQL 16
│   └── service.yaml               # Service PostgreSQL (port 5432)
├── keycloak/
│   ├── configmap-realm.yaml       # Realm classic-models (Configuration-as-Code)
│   ├── deployment.yaml            # Déploiement Keycloak 26.6.0 (--import-realm)
│   └── service.yaml               # Service Keycloak (ports 8080, 9000)
└── ingress/
    ├── tls.yaml                   # Secret TLS wildcard (*.sttlab.local)
    └── ingress.yaml               # Ingress NGINX (keycloak.sttlab.local)

Fonctionnalités Clés

  • Version Keycloak : quay.io/keycloak/keycloak:26.6.0 (Runtime Quarkus).
  • Import Automatique du Realm (CaC) : Le realm classic-models est chargé au démarrage via l'option --import-realm depuis le ConfigMap monté dans /opt/keycloak/data/import/.
  • Token Exchange RFC 8693 : Activé via KC_FEATURES: "token-exchange,admin-fine-grained-authz".
  • Clients Configurés :
    • librechat : Client OIDC pour le login et le flux OAuth MCP.
    • mcp-catalog : Audience du serveur MCP.
    • kong-token-exchange-broker : Échangeur de jetons RFC 8693 de Kong Gateway.
    • catalog-api & classic-models-api : Audiences des services backend.
  • Utilisateurs & Rôles :
    • admin-user (admin)
    • pm-user (product_manager)
    • ro-user (read_only)
    • customer-user (customer)
    • support-user (support)

Déploiement

k8s/secret.yaml n'est pas versionné : il porte les mots de passe réels (base PostgreSQL, admin Keycloak, secrets clients OIDC). Le créer une fois depuis le gabarit, puis renseigner chaque <CHANGE_ME> :

cp k8s/secret.example.yaml k8s/secret.yaml
$EDITOR k8s/secret.yaml

k8s/kustomization.yaml le référence, donc le déploiement échoue tant qu'il est absent.

kubectl apply -k k8s/