Le secret avait fui dans une sortie de diagnostic. Le faire tourner a d'abord demande de rendre la rotation possible : ni Keycloak ni Forgejo ne reconciliaient un secret OIDC existant. Le commentaire de clients-oidc.yml l'avouait (« create-si-absent »), et `update-oauth` ne passait pas --secret. Regenerer la voute aurait laisse les deux cotes sur l'ancienne valeur — ou un seul des deux, et le SSO aurait casse sans que rien ne l'annonce. Keycloak compare desormais le secret EN PLACE a celui voulu avant d'ecrire. Verifie par empreinte aux trois endroits : voute, Keycloak, Forgejo — identiques. Keycloak rejoue a changed=0. Signale sans etre corrige : `Deployer app.ini` change a chaque passage. Forgejo reecrit lui-meme ce fichier (il y persiste ses secrets generes) et le gabarit l'ecrase. Prealable au correctif : decider quelles cles appartiennent au gabarit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
51 lines
2.6 KiB
YAML
51 lines
2.6 KiB
YAML
---
|
|
# Enregistre les clients OIDC applicatifs dans le realm via kcadm — idempotent.
|
|
# Crée le client s'il est absent, et RÉCONCILIE son secret et ses URI s'il existe.
|
|
#
|
|
# « Create-si-absent » rendait la rotation d'un secret OIDC impossible : la voûte
|
|
# changeait, l'application recevait la nouvelle valeur, et Keycloak gardait
|
|
# l'ancienne — le SSO cassait sans que rien ne l'annonce. Constaté le 2026-08-07,
|
|
# au moment de faire tourner `vault_forgejo_oidc`, exposé dans une transcription.
|
|
- name: Enregistrer les clients OIDC (kcadm, idempotent)
|
|
ansible.builtin.shell:
|
|
executable: /bin/bash
|
|
cmd: |
|
|
set -euo pipefail
|
|
KC={{ serveur_keycloak_home }}/bin/kcadm.sh
|
|
"$KC" config credentials --server http://localhost:8080 --realm master \
|
|
--user {{ serveur_keycloak_admin_user }} --password "$KC_ADMIN_PW" >/dev/null
|
|
CID=$("$KC" get clients -r {{ serveur_keycloak_realm }} -q clientId={{ item.clientId }} \
|
|
--fields id --format csv --noquotes 2>/dev/null | head -1 || true)
|
|
if [ -n "$CID" ]; then
|
|
# Le secret EN PLACE, compare a celui voulu. `get client-secret` le rend en
|
|
# clair : c'est la seule facon de savoir s'il faut ecrire.
|
|
ACTUEL=$("$KC" get clients/"$CID"/client-secret -r {{ serveur_keycloak_realm }} 2>/dev/null \
|
|
| sed -n 's/.*"value" *: *"\([^"]*\)".*/\1/p' | head -1 || true)
|
|
if [ "$ACTUEL" != "$OIDC_SECRET" ]; then
|
|
"$KC" update clients/"$CID" -r {{ serveur_keycloak_realm }} \
|
|
-s secret="$OIDC_SECRET" \
|
|
-s 'redirectUris={{ item.redirect_uris | to_json }}' \
|
|
-s 'webOrigins={{ item.web_origins | default([]) | to_json }}' >/dev/null
|
|
echo SETOPS_CHANGED
|
|
else
|
|
echo SETOPS_OK
|
|
fi
|
|
else
|
|
"$KC" create clients -r {{ serveur_keycloak_realm }} \
|
|
-s clientId={{ item.clientId }} -s enabled=true -s protocol=openid-connect \
|
|
-s publicClient=false -s standardFlowEnabled=true -s directAccessGrantsEnabled=false \
|
|
-s 'redirectUris={{ item.redirect_uris | to_json }}' \
|
|
-s 'webOrigins={{ item.web_origins | default([]) | to_json }}' \
|
|
-s secret="$OIDC_SECRET" >/dev/null
|
|
echo SETOPS_CHANGED
|
|
fi
|
|
environment:
|
|
KC_ADMIN_PW: "{{ serveur_keycloak_admin_password }}"
|
|
OIDC_SECRET: "{{ item.secret }}"
|
|
loop: "{{ serveur_keycloak_clients }}"
|
|
loop_control:
|
|
label: "{{ item.clientId }}"
|
|
register: serveur_keycloak_client_reg
|
|
changed_when: "'SETOPS_CHANGED' in serveur_keycloak_client_reg.stdout"
|
|
no_log: true
|
|
when: not ansible_check_mode
|