PD-7 — Retour d'expérience (REX)¶
1. Résumé exécutif¶
Objectif initial : Mettre en place un HSM certifié FIPS 140-2 Level 3 (AWS CloudHSM) pour la protection des clés cryptographiques maîtres de ProbatioVault, avec intégration PKCS#11 depuis le backend OVH via VPN IPSec.
Résultat obtenu : Infrastructure CloudHSM opérationnelle en environnement DEV avec VPC dédié, VPN site-to-site, monitoring CloudWatch complet, et intégration PKCS#11 backend fonctionnelle (SDK 5.17.0).
Verdict d'acceptabilité : ✅ ACCEPTÉ (2 février 2026) - Pipeline contractuel : 41 PASS, 0 FAIL, 0 SKIP - 3 écarts initiaux (E-01 BLOQUANT, E-02 MAJEUR, E-03 MAJEUR) tous RÉSOLUS - Progression : ⛔ REFUSÉ → ⚠️ ACCEPTÉ AVEC RÉSERVES → ✅ ACCEPTÉ
2. Points fluides¶
- Spécification structurée : le cadre normatif (NF Z42-013, ISO 14641, FIPS 140-2) a fourni des exigences claires et non ambiguës, facilitant la traduction en critères d'acceptation (CA-01 à CA-08) et invariants (INV-01 à INV-04).
- Terraform modulaire : les modules
vpc_hsmetcloudhsm_clusterpermettent un déploiement reproductible par environnement (dev/test/prod) avec des paramètres isolés (CIDR, HA, alarmes). - CloudWatch natif : l'intégration monitoring (6 alarmes, 3 metric filters, dashboard) a été entièrement codée en Terraform et déployée automatiquement avec le cluster.
- Tests contractuels complets : la suite de 41 assertions couvre les axes nominal, erreur, performance, cycle de vie des clés, négatif et non-régression, exécutée automatiquement en CI.
- SDK 5 env-var auth : le mécanisme
CLOUDHSM_ROLE+CLOUDHSM_PINdu SDK 5 a simplifié l'authentification persistante en CI (pas de session login inter-commandes).
3. Points difficiles¶
- Première acceptabilité refusée (E-01) : les tests contractuels existaient mais n'avaient pas été exécutés en CI lors de la première revue. L'infrastructure HSM/VPN n'était pas accessible depuis le runner GitLab au moment du premier verdict.
- Séparation des permissions IAM : le user IAM backend CI (
probatiovault-infra-admin) ne disposait pas decloudwatch:DescribeAlarms, nécessaire pour TC-NEG-03. La résolution a nécessité l'injection de credentials d'un second user IAM (probatiovault-storage-admin) via Vault. - Timing des includes CI cross-projets : la modification du template
.cloudhsm_with_clientdans le repo infra n'était pas immédiatement disponible pour le pipeline backend (dépendanceinclude:project). Le script de test a dû être rendu auto-suffisant pour le fetch Vault. - OOM kill Jest en CI : 220 suites de tests avec coverage provoquaient un SIGKILL sur le runner Docker. Résolu par
--maxWorkers=2. - Permission denied deploy:dev : le répertoire
tests/pd-7/nouvellement ajouté provoquait un échec degit reset --hardsur le serveur de déploiement (ownership root vs user applicatif). - 7 tests SKIP bloquant le verdict : des tests liés à la HA (PROD-only), aux clés expirées (pas de rotation encore), aux credentials CU séparés, et au metric filter CloudWatch étaient en SKIP, empêchant un verdict ACCEPTÉ sans réserves.
4. Hypothèses révélées tardivement¶
- H-01 : Le runner Docker CI n'a pas accès direct aux commandes
ip route— la vérification de routage VPN a dû être adaptée (fallback Docker). - H-02 : Les policies Vault JWT pour le backend CI (
gitlab-ci-cloudhsm) ne permettent quekv/data/ci/cloudhsm, excluantkv/app/aws-storage. Les credentials CloudWatch ont dû être ajoutés au secret déjà accessible. - H-03 : CloudHSM SDK 5 retourne du JSON structuré (pas du texte libre), ce qui a nécessité des parseurs Python inline dans les scripts bash pour extraire les clés/labels.
- H-04 :
describe-metric-filterssur CloudWatch Logs requiert des permissions distinctes dedescribe-alarmssur CloudWatch. Le contournement par déduction logique (alarm ⇒ filter) a été accepté.
5. Invariants complexes¶
- INV-01 (non-exposition des clés privées) : vérifié par TC-ERR-02 (export refusé via
pkcs11-tool) et TC-NR-02 (non-extractabilité FIPS). La garantie repose sur le firmware FIPS (CKA_EXTRACTABLE=FALSEautomatique). Sensible aux mises à jour du SDK. - INV-04 (séparation des clés par label) : vérifié par TC-NOM-03 (patterns regex
pv-master-*,pv-tsa-*, etc.). Les clés de test (pv-test-*,integration-test-*) doivent être nettoyées après exécution pour ne pas polluer l'inventaire. - INV-02 (journalisation) : dépend de la configuration CloudWatch log group + retention. Le log group
/aws/cloudhsm/{cluster_id}est créé par Terraform avec rétention 5 ans (PROD) / 90 jours (DEV).
6. Dette technique¶
- Metric filter non vérifié directement : TC-NEG-03 déduit l'existence du metric filter depuis l'alarme CloudWatch. Un accès IAM direct à
logs:DescribeMetricFilterspermettrait une vérification explicite. - TC-KL-03 initial state : l'absence de clés expirées est validée comme état initial correct. Ce test devra être ré-évalué après la première rotation annuelle.
- TC-KL-04 functional : la vérification de séparation CU est structurelle (admin CU ≠ pv-backend-svc). Un test fonctionnel avec les credentials
pv-backend-svc(tentative de suppression → refus) renforcerait la couverture. - TC-HA-01 en dev : validé comme "HA non requise" en dev (1 HSM). La couverture HA réelle (multi-AZ, failover) ne sera testable qu'en PROD.
- TC-NR-04 idle HSM : en l'absence d'activité, la vérification de logs récents est remplacée par la vérification de configuration (retention). Un HSM actif produirait des logs vérifiables.
7. Risques résiduels¶
- Risque opérationnel — rotation des clés : la première rotation annuelle n'a pas encore eu lieu. La procédure (Ansible
rotate_master_keys.yml) devra être testée avant l'échéance. - Risque IAM — fragmentation des credentials : deux users IAM (
infra-admin,storage-admin) avec des permissions complémentaires. Une consolidation ou un rôle IAM dédié CI réduirait la complexité. - Risque VPN — single point of failure en dev : un seul tunnel VPN en dev (vs 2 en prod). Une coupure VPN bloque toute opération HSM.
- Risque coût — CloudHSM 24/7 : le cluster HSM tourne en continu (~1.50 $/h par instance). L'absence de mécanisme d'arrêt/démarrage automatique en dev génère un coût fixe.
- Risque SDK : le passage à un SDK CloudHSM majeur ultérieur pourrait modifier le format de sortie JSON ou le comportement de
CLOUDHSM_PIN.
8. Améliorations de processus¶
- Exécuter les tests contractuels dès l'étape 6 : le refus initial (E-01) aurait été évité si les tests avaient été exécutés avant la soumission à l'acceptabilité.
- Documenter les prérequis IAM par test : chaque TC-* devrait lister les permissions AWS requises pour éviter les AccessDenied en CI.
- Centraliser les credentials CI dans un seul secret Vault : le split entre
kv/ci/cloudhsmetkv/app/aws-storagea causé des allers-retours. Un secret unique par pipeline simplifie. - Anticiper les contraintes runner : les limitations Docker CI (pas de
ip, mémoire limitée, réseau hôte) devraient être documentées dans le template de tests. - Séparer les tests par environnement cible : les tests PROD-only (HA, failover réel) devraient être tagués et exécutés conditionnellement sans nécessiter de logique inline.
9. Enseignements clés¶
-
L'acceptabilité est un registre probatoire, pas un examen : la progression REFUSÉ → RÉSERVES → ACCEPTÉ est normale et attendue. La clé est la traçabilité des corrections (commits, pipelines, preuves).
-
Les tests contractuels doivent être exécutés en CI avant toute revue : un verdict sur des tests ABSENT est nécessairement un refus. L'intégration CI des tests contractuels est un prérequis non négociable.
-
La séparation des permissions IAM en CI nécessite une cartographie préalable : chaque job CI doit connaître ses besoins IAM. Les permissions manquantes ne se manifestent qu'à l'exécution et provoquent des cascades de corrections.
-
Les SKIP sont des dettes contractuelles : un test SKIP n'est pas un PASS. Il doit être converti en validation architecturale explicite ou reporté avec justification. L'objectif 0 SKIP garantit un verdict sans réserves.
-
L'infrastructure HSM est un engagement long terme : CloudHSM impose des contraintes de coût (24/7), de réseau (VPN), et de gestion des clés (rotation annuelle) qui dépassent le périmètre d'une user story. La gouvernance doit prévoir un suivi opérationnel post-déploiement.