Aller au contenu

PD-235 — Rétrospective

1. Contexte

Champ Valeur
Story ID PD-235
Titre Keycloak OAuth2/OIDC auto-hébergé
Domaine infrastructure-souveraine
Projet infra
Date complétion 2026-01-08
Verdict ACCEPTÉ

2. Métriques

Métrique Valeur
Tests contractuels 100% PASS
Realms déployés 3 (pv-dev, pv-staging, pv-prod)
Clients OIDC 4 (api, services, workers, frontend)
Invariants INV-01 à INV-06, INV-IAM-01 à INV-IAM-11

3. Learnings clés

  • Gestion certificats SAN : Toujours vérifier que le certificat utilisé par Nginx correspond au domaine servi, en particulier pour les sous-domaines multiples partageant un certificat SAN.

  • Arithmétique bash et set -e : L'expression ((var++)) retourne 1 quand var=0. Toujours utiliser ((var++)) || true dans les scripts avec set -e.

  • Encodage JWT base64url : Les JWT utilisent base64url (RFC 4648 §5), pas base64 standard. Implémenter une fonction de conversion explicite pour le parsing.

  • Précédence variables Ansible : Le répertoire group_vars/<group>/ a priorité sur le fichier group_vars/<group>.yml. Ne pas mélanger les deux approches.

  • Scope tests infra vs backend : Définir explicitement dès la spécification quels tests relèvent de l'infrastructure (émission tokens) vs du backend applicatif (validation tokens).

4. Patterns applicables

Nouveau pattern : Décodage JWT base64url en bash

# Fonction de conversion base64url → base64 standard
decode_base64url() {
  local input="$1"
  # Remplacer caractères URL-safe
  input="${input//-/+}"
  input="${input//_/\/}"
  # Ajouter padding si nécessaire
  local pad=$((4 - ${#input} % 4))
  [ $pad -lt 4 ] && input+=$(printf '=%.0s' $(seq 1 $pad))
  echo "$input" | base64 -d
}

# Usage: extraction claims JWT
jwt_payload=$(echo "$token" | cut -d. -f2)
claims=$(decode_base64url "$jwt_payload" | jq .)

Nouveau pattern : Architecture Ansible Keycloak modulaire

# Rôles séparés par responsabilité
roles:
  - keycloak          # Installation + config base
  - keycloak-realm    # Création realms par environnement
  - keycloak-clients  # Clients OIDC avec secrets Vault
  - keycloak-audit    # Event listeners journalisation

# Variables par realm
keycloak_realms:
  - name: pv-dev
    issuer: "https://id.dev.probatiovault.com/realms/pv-dev"
    access_token_lifespan: 300
  - name: pv-prod
    issuer: "https://id.probatiovault.com/realms/pv-prod"
    access_token_lifespan: 300

5. Signal CLAUDE.md

Priorité moyenne : Gestion arithmétique bash avec set -e.

### Bash — Arithmétique et set -e (2026-02-XX)

**PIÈGE** : `((var++))` retourne exit code 1 quand var=0, causant l'arrêt du script avec `set -e`.

```bash
# INTERDIT avec set -e
((PASSED++))  # Exit code 1 si PASSED=0

# OBLIGATOIRE
((PASSED++)) || true
# ou
PASSED=$((PASSED + 1))

Découverte PD-235 : Tests contractuels marqués en échec malgré exécution correcte. ```

6. Conclusion

PD-235 a livré Keycloak auto-hébergé avec realms isolés par environnement, endpoints OIDC discovery/JWKS, clients configurés, intégration Vault, TLS Let's Encrypt, et journalisation conforme. Les patterns décodage JWT base64url et architecture Ansible modulaire sont réutilisables. Le scope infra vs backend (émission vs validation tokens) clarifié évite les confusions de responsabilité.


Rétrospective générée 2026-02-19 (Étape 10 batch infra-souveraine)