PD-238 — Livrable Agent Developer : Infrastructure Keycloak¶
Tâche 1 du manifest de décomposition Date : 2026-02-06 Agent : agent-developer (Claude)
Périmètre¶
src/modules/auth/mfa/config/keycloak-admin.config.tssrc/modules/auth/mfa/services/keycloak-admin.service.ts
Modifications effectuées¶
1. keycloak-admin.config.ts¶
Aucune modification nécessaire. Le fichier existant est conforme au contract : - registerAs('keycloakAdmin') - Toutes les env vars définies - deriveTokenEndpoint - Validation function
2. keycloak-admin.service.ts¶
| Problème identifié | Correction |
|---|---|
Utilisait un KeycloakAdminError interne au lieu de la hiérarchie MfaManagementError | Remplacé par MfaInternalError, MfaTotpInvalidError, MfaTotpInitFailedError, MfaDisableFailedError, MfaRecoveryRegenFailedError importés de ../errors/mfa-management.errors |
classifyError retournait des strings (HTTP_5xx) — impossible de matcher les codes spécifiques 502/503 pour le retry | Refactoré avec une interface ClassifiedError qui porte category (pour circuit breaker) ET httpStatus numérique (pour retry sur 502/503) |
Retry : RETRYABLE_ERRORS contenait 'HTTP_503'/'HTTP_502' mais classifyError ne retournait jamais ces valeurs | isRetryable() vérifie maintenant classified.httpStatus contre RETRYABLE_HTTP_STATUSES = [502, 503] |
HttpError interne mal typé (string parsing dans les messages) | Introduit une classe HttpError propre avec status: number pour une classification précise |
| Fallback circuit breaker ne matchait pas le message exact de la spec | checkCircuit() lance new MfaInternalError('Keycloak unavailable') — conforme au fallback spec |
Hypothèses documentées¶
-
@nestjs/axios/HttpService: Le contract spécifieHttpServicecomme dépendance, mais@nestjs/axiosn'est pas installé dans le projet. L'implémentation existante utilisefetchnatif (Node.js 18+), cohérent avec le pattern du codebase (captcha.service.ts,reauth.service.ts). Maintenu tel quel. -
Endpoints Keycloak OTP : Les endpoints
/users/{id}/credentials/otp/init,/users/{id}/credentials/otp/verify, et/users/{id}/credentials/{credId}/recovery-codessont des endpoints Keycloak custom supposés disponibles (potentiellement via un SPI Keycloak). -
INV-238-07 (invalidation anciens codes) : Déléguée au endpoint Keycloak
POST .../recovery-codesqui est responsable d'invalider les anciens codes côté serveur d'identité.
Conformité invariants¶
| Invariant | Statut |
|---|---|
| INV-238-05 | Conforme — activation uniquement si code valide |
| INV-238-07 | Conforme — délégué à Keycloak |
| INV-238-08 | Conforme — codes retournés une seule fois |
| INV-238-09 | Conforme — secrets jamais loggés |
| INV-238-10 | Conforme — aucun stockage local |
| INV-238-13 | Conforme — erreurs explicites sans effet partiel |
Fichiers hors périmètre identifiés¶
Aucun.