Aller au contenu

PD-37 — Retour d'expérience


Navigation User Story | Document | | | ---------- | -- | | [Spécification](PD-37-specification.md) | | | [Plan d'implémentation](PD-37-plan.md) | | | [Critères d'acceptation](PD-37-acceptability.md) | | | **Retour d'expérience** | *(ce document)* | [Retour à crypto-proof](../PD-189-epic.md) · [Index User Story](index.md)

1. Résumé exécutif

Objectif : Implémenter un service de signature HSM des journaux d'audit probatoires, garantissant non-répudiation, intégrité et auditabilité conformément aux normes NF Z42-013 et ISO 14641.

Résultat : Service livré et fonctionnel après correction de deux écarts identifiés lors de la revue d'acceptabilité. La vérification indépendante des signatures (E-01 BLOQUANT) et la gestion des échecs via Dead Letter Queue (E-03 MAJEUR) ont nécessité des développements complémentaires non prévus dans le plan initial.

Verdict : ACCEPTÉ le 2025-12-22, après refus initial le 2025-12-18.


2. Points fluides

  • Canonicalisation RFC 8785 : Implémentation directe via bibliothèque canonicalize, tests unitaires avec vecteurs RFC conformes.
  • Intégration HsmService : L'abstraction PKCS#11 existante a permis une intégration transparente de la signature ECDSA P-256.
  • SHA3-256 : HashService déjà disponible, réutilisé sans modification.
  • Table append-only : Trigger PostgreSQL simple et efficace pour bloquer UPDATE/DELETE.
  • Queue BullMQ : Configuration standard avec retry exponentiel, intégration NestJS fluide.
  • Types d'audit : Enum exhaustif couvrant l'ensemble des actions métier identifiées.

3. Points difficiles

3.1 Vérification indépendante du HSM (E-01)

  • Contexte : La spécification exige une preuve « vérifiable de façon indépendante, sans dépendre du backend ». Le plan d'implémentation proposait verifyAuditEntry() appelant HsmService.verify(), ce qui maintient la dépendance au HSM.
  • Impact : Écart BLOQUANT détecté en revue d'acceptabilité.
  • Résolution : Ajout de trois composants non planifiés :
  • Table hsm_public_keys pour persister les clés publiques exportées
  • AuditVerificationService utilisant Node.js crypto au lieu du HSM
  • Outil CLI standalone verify-audit-proof.ts pour tiers vérificateurs

3.2 Gestion des échecs définitifs (E-03)

  • Contexte : Le plan mentionnait explicitement « Dead Letter Queue » comme hors périmètre. La configuration BullMQ (removeOnFail: 1000) supprimait silencieusement les jobs après 3 échecs.
  • Impact : Violation de l'exigence de robustesse (« Aucune entrée partielle ne doit être créée »).
  • Résolution : Ajout d'une couche DLQ complète :
  • Entité AuditSignatureDlq et migration associée
  • AuditDlqService pour gestion manuelle et automatique
  • Flow Prefect audit_dlq_retry.py pour orchestration (cron */15 min)
  • Playbook Ansible audit_dlq_monitoring.yml pour déploiement

3.3 Coordination multi-repos

  • Contexte : La correction E-03 a nécessité des modifications dans deux dépôts distincts (backend + infra).
  • Impact : Synchronisation des déploiements requise, documentation dispersée.

4. Hypothèses révélées tardivement

Hypothèse implicite Découverte
La vérification peut utiliser le HSM en production Faux : les auditeurs externes n'ont pas accès au HSM
BullMQ gère nativement la DLQ Faux : removeOnFail supprime les jobs, pas de DLQ intégrée
Le plan couvre tous les invariants de la spec Faux : l'exclusion explicite de la DLQ contredit l'exigence de robustesse
La clé publique HSM peut être récupérée à tout moment Vrai mais insuffisant : nécessite persistance pour vérification offline

5. Invariants complexes

Invariant Complexité
Append-only absolu Simple (trigger SQL), mais contraint les corrections de données
Signature HSM-only Simple en signature, complexe en vérification indépendante
Aucune perte d'entrée Complexe : nécessite DLQ + monitoring + retry automatique + retry manuel
Vérification sans backend Complexe : export clé publique + outil standalone + format de preuve documenté

6. Dette technique

Élément Description Priorité
Tests E2E DLQ Pas de test d'intégration complet du flow Prefect avec le backend Moyenne
Endpoint /audit/proof/status Placeholder non implémenté (retourne toujours 0) Basse
Format preuve exportée Pas de schéma JSON formel documenté pour les tiers Moyenne
Authentification API DLQ Les endpoints /audit/proof/dlq/* ne sont pas protégés Haute

7. Risques résiduels

Risque Probabilité Impact Mitigation actuelle
Perte d'entrée si insertion DLQ échoue Faible Élevé Log CRITICAL avec payload complet, récupérable manuellement
Désynchronisation clé publique Faible Moyen Export automatique à chaque rotation (non testé en rotation réelle)
Prefect indisponible Moyenne Moyen Retry manuel possible via API, alertes si pending > seuil
Saturation DLQ Faible Moyen Alertes Prefect si > 10 entrées ou > 24h en attente

8. Améliorations processus

Suggestion Justification
Revue spec vs plan systématique L'écart E-01 aurait pu être détecté en comparant la spec (« vérifiable indépendamment ») et le plan (HsmService.verify)
Checklist invariants Vérifier explicitement chaque contrainte de la spec avant validation du plan
Éviter « hors périmètre » contradictoire La DLQ était hors périmètre du plan mais requise par la spec — cette incohérence devait être levée
Documentation multi-repo Prévoir un README de coordination quand une US touche plusieurs dépôts

9. Enseignements clés

  1. « Vérification indépendante » signifie vraiment indépendante : tout composant de preuve doit pouvoir être vérifié sans accès au système source ni au HSM.

  2. La robustesse inclut la récupération des échecs : « aucune entrée partielle » implique de gérer le cycle de vie complet, y compris les échecs définitifs après retry.

  3. « Hors périmètre » ne suspend pas les invariants : exclure une fonctionnalité du plan ne la rend pas optionnelle si la spec l'exige.

  4. Le premier verdict d'acceptabilité est rarement le dernier : prévoir des itérations entre revue et correction est normal sur les US à forte exigence de conformité.

  5. L'orchestration (Prefect/Ansible) fait partie du livrable : une fonctionnalité backend sans son déploiement automatisé n'est pas complète.


Historique du document

Date Auteur Modification
2025-12-22 Claude Création initiale du REX