PD-235 — Retour d'expérience (REX)¶
1. Resume executif¶
Objectif initial : Mise en place d'un fournisseur d'identite OAuth2/OIDC auto-heberge (Keycloak) servant de socle transverse d'authentification pour ProbatioVault, avec isolation par environnement, tokens JWT signes verifiables hors-ligne, et journalisation conforme.
Resultat obtenu : Keycloak deploye sur VM OVH avec : - Realms isoles par environnement (pv-dev, pv-staging, pv-prod) - Endpoints OIDC discovery et JWKS exposes - Clients OIDC configures (probatiovault-api, probatiovault-services, probatiovault-workers, probatiovault-frontend) - Integration secrets HashiCorp Vault - Reverse proxy Nginx avec TLS Let's Encrypt - Journalisation evenements auth/token - Tests contractuels automatises en CI/CD
Verdict d'acceptabilite : ✅ ACCEPTE (2026-01-08, commit d6ab08b)
Etat des tests contractuels : - Suites OIDC Discovery, Token Validation, Environment Isolation, Audit Logging : 100% PASS - Tests dependants backend (TC-ERR-01/03, TC-NEG-02/04) reclasses vers PD-26
2. Points fluides¶
Specification claire et structuree¶
- Invariants bien definis (INV-01 a INV-06, INV-IAM-01 a INV-IAM-11)
- Annexe B normative avec valeurs concretes (issuers, audiences, algorithmes)
- Separation nette entre annexe explicative (A) et normative (B)
Architecture Ansible modulaire¶
- Roles separes :
keycloak,keycloak-realm,keycloak-clients,keycloak-audit - Configuration declarative et idempotente
- Integration Vault sans secrets en clair dans le repository
Tests contractuels automatisables¶
- Scripts bash autonomes executables en CI
- Format JUnit pour integration GitLab
- Couverture tracable via matrice invariants → tests
Documentation opposable¶
- Artefacts de preuve (inventaire infra, runbook, controle acces) structures
- Traceabilite specification → implementation → tests
3. Points difficiles¶
Certificat SSL SAN incorrect¶
Le certificat Let's Encrypt genere pour api.dev.probatiovault.com incluait id.dev.probatiovault.com dans le SAN, mais la configuration Nginx pour Keycloak pointait vers le mauvais fichier certificat (dev.probatiovault.com). - Detection : Erreur curl SSL: no alternative certificate subject name matches target host name - Resolution : Ajout certbot_primary_domain dans group_vars/all/app.yml
Arithmetique bash avec set -e¶
Les scripts de test utilisaient ((PASSED++)) qui retourne exit code 1 quand PASSED=0, causant l'arret du script avec set -e. - Detection : Tests marques en echec malgre execution correcte - Resolution : ((PASSED++)) || true dans toutes les fonctions log_pass/log_fail
Encodage base64url JWT¶
Les JWT utilisent base64url (caracteres URL-safe, sans padding) mais base64 -d attend du base64 standard. - Detection : Erreur syntax error in expression lors du parsing des claims - Resolution : Fonction decode_base64url() avec conversion _- → /+ et ajout padding
Precedence variables Ansible¶
Le fichier group_vars/all.yml n'est pas lu quand le repertoire group_vars/all/ existe. - Detection : Variable metabase_enabled ignoree causant erreur 502 - Resolution : Deplacement de metabase_enabled vers group_vars/all/metabase.yml
Symlink Nginx converti en fichier¶
L'edition directe via sed -i sur un symlink le convertit en fichier regulier. - Detection : Echec Ansible refusing to convert from file to symlink - Resolution : Recreation manuelle du symlink, puis deploiement Ansible
4. Hypotheses revelees tardivement¶
| ID | Hypothese | Moment de decouverte | Impact |
|---|---|---|---|
| H-07 | Event listeners Keycloak synchrones | Implementation journalisation | Mitigation ajoutee : buffer local + retry + monitoring (§7.4 du plan) |
| - | Tests TC-ERR-01/03, TC-NEG-02/04 relevent du backend | Revue d'acceptabilite | Reclassement vers PD-26, pas de blocage PD-235 |
| - | Certificat SAN doit inclure tous les sous-domaines | Echec tests OIDC discovery | Configuration certbot_primary_domain requise |
5. Invariants complexes¶
INV-IAM-09 — Journalisation conforme¶
- Complexite : Garantir l'absence de secrets dans les logs tout en conservant la traceabilite
- Risque regression : Event listeners mal configures peuvent exposer tokens
- Couverture : TC-NOM-05, TC-NOM-06, TC-NEG-06
INV-IAM-11 — Signal d'indisponibilite IdP¶
- Complexite : 3 canaux normatifs a implementer (HTTP 503, log obligatoire, health endpoint)
- Risque regression : Confusion avec 401/403 si mal implemente
- Note : Implementation complete cote IdP ; validation consumer dans PD-26
INV-IAM-05 — Contraintes temporelles¶
- Complexite : Tolerance horloge (±2 min) a appliquer uniformement
- Pre-requis : Synchronisation NTP < 2 min entre IdP et consumers (H-08)
- Couverture : TC-NEG-02 (cote backend PD-26)
6. Dette technique¶
| Dette | Raison d'acceptation | Impact | Remediation prevue |
|---|---|---|---|
| Instance Keycloak unique (pas de HA) | Complexite MVP, budget | SPOF potentiel | V2 avec clustering Keycloak |
| Pas de Disaster Recovery automatise | Budget | Risque perte config | Plan DR documente, backups manuels |
| Monitoring basique | MVP | Alerting limite | Prometheus/Grafana V2 |
| Pas de rate limiting | MVP | Risque DDoS | WAF V2 |
| Rotation cles manuelle | Complexite | Risque operationnel | Automatisation V2 |
7. Risques residuels¶
| Risque | Probabilite | Impact | Mitigation actuelle | Surveillance |
|---|---|---|---|---|
| Indisponibilite IdP | Moyenne | Critique (auth impossible) | Backups, runbook | Health checks, alerting |
| Compromission admin Keycloak | Faible | Critique | RBAC admin, audit logs | Logs console admin |
| Derive horloge > 2 min | Faible | Majeur (tokens rejetes) | NTP configure | Monitoring NTP |
| Rotation cles mal executee | Moyenne | Majeur | Runbook documente | Tests pre-rotation |
| Fuite secrets dans logs | Faible | Critique | Event listeners filtrants | Audit periodique logs |
8. Ameliorations de processus¶
Template scripts bash pour tests contractuels¶
Creer un template standardise avec : - Gestion correcte de set -e et arithmetique - Fonction decode_base64url() pre-implementee - Format de sortie JUnit uniforme - Variables d'environnement documentees
Definition scope infra vs backend¶
Clarifier des le debut quels tests relevent de l'infra (IdP) vs backend (consumer) : - Tests emission token → infra (PD-235) - Tests validation token → backend (PD-26) - Tests erreur IdP observable cote client → backend (PD-26)
Matrice certificats SSL/SAN¶
Documenter les dependances certificats pour chaque sous-domaine : - Quel certificat couvre quels domaines - Ordre d'emission (domaine principal vs SAN) - Configuration Nginx correspondante
Checklist pre-deploiement Ansible¶
Verifier avant deploiement : - [ ] Variables lues depuis le bon fichier (group_vars/all/ vs all.yml) - [ ] Symlinks Nginx intacts - [ ] Secrets Vault accessibles depuis runner CI
9. Enseignements cles¶
-
Gestion certificats SAN : Toujours verifier que le certificat utilise par Nginx correspond au domaine servi, en particulier pour les sous-domaines multiples partageant un certificat SAN.
-
Arithmetique bash et set -e : L'expression
((var++))retourne 1 quand var=0. Toujours utiliser((var++)) || truedans les scripts avecset -e. -
Encodage JWT base64url : Les JWT utilisent base64url (RFC 4648 §5), pas base64 standard. Implementer une fonction de conversion explicite pour le parsing.
-
Precedence variables Ansible : Le repertoire
group_vars/<group>/a priorite sur le fichiergroup_vars/<group>.yml. Ne pas melanger les deux approches. -
Scope tests infra vs backend : Definir explicitement des la specification quels tests relevent de l'infrastructure (emission tokens) vs du backend applicatif (validation tokens, gestion erreurs cote consumer).
References¶
- Epic : EPIC-193 — Infrastructure Souveraine
- JIRA : PD-235
- Specification : PD-235-specification.md
- Plan d'implementation : PD-235-plan.md
- Tests contractuels : PD-235-tests.md
- Acceptabilite : PD-235-acceptability.md
- Pipeline de validation : GitLab CI #2251423458
- Commit de reference :
d6ab08b(branchedev)