PD-7 — Plan d'implémentation
ID : PD-7 Epic : PD-193 — INFRA Version : 1.2 Statut : Draft (post-review v2 — INV-04 renforcé) Documents source : PD-7-specification.md, PD-7-tests.md
1. Architecture technique
1.1 Diagramme d'architecture
┌─────────────────────────────────────────────────────────────────────────────┐
│ OVH (Paris) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Backend ProbatioVault │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │ │
│ │ │ API Server │───▶│ Crypto │───▶│ PKCS#11 Client Library │ │ │
│ │ │ (NestJS) │ │ Service │ │ (cloudhsm-pkcs11) │ │ │
│ │ └─────────────┘ └─────────────┘ └───────────┬─────────────┘ │ │
│ └─────────────────────────────────────────────────────┼───────────────┘ │
│ │ │
│ ┌─────────────────────────────────────────────────────┼───────────────┐ │
│ │ VPN Gateway OVH │ │ │
│ │ (IPSec IKEv1/AES-256) │ │ │
│ └─────────────────────────────────────────────────────┼───────────────┘ │
└────────────────────────────────────────────────────────┼────────────────────┘
│
══════════════════════════════════
VPN IPSec Tunnel
══════════════════════════════════
│
┌────────────────────────────────────────────────────────┼────────────────────┐
│ AWS (eu-west-3 Paris) │ │
│ ┌─────────────────────────────────────────────────────┼───────────────┐ │
│ │ VPC HSM (10.0.0.0/16) │ │ │
│ │ ┌──────────────────────────────────────────────────┼─────────────┐ │ │
│ │ │ Private Subnet HSM │ │ │ │
│ │ │ (10.0.1.0/24) ▼ │ │ │
│ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │
│ │ │ │ CloudHSM #1 │ │ CloudHSM #2 │ HA Cluster │ │ │
│ │ │ │ (eu-west-3a) │◀──▶│ (eu-west-3b) │ (sync auto) │ │ │
│ │ │ │ ENI: 10.0.1.x │ │ ENI: 10.0.1.y │ │ │ │
│ │ │ └─────────────────┘ └─────────────────┘ │ │ │
│ │ └────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌────────────────────────────────────────────────────────────────┐ │ │
│ │ │ VPN Gateway AWS │ │ │
│ │ │ (Virtual Private Gateway) │ │ │
│ │ └────────────────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ CloudWatch (eu-west-3) │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │ │
│ │ │ Logs │ │ Metrics │ │ Alarms │ │ │
│ │ │ (audit HSM) │ │ (latence, │ │ (santé cluster, │ │ │
│ │ │ │ │ dispo) │ │ failover) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────────┘
| Composant | Resource Terraform | Fichier | Description |
| VPC HSM | aws_vpc | vpc.tf | VPC dédié 10.0.0.0/16 |
| Subnet privé | aws_subnet | vpc.tf | Subnet HSM 10.0.1.0/24 (multi-AZ) |
| Security Group | aws_security_group | security.tf | Règles PKCS#11 (port 2223-2225) |
| CloudHSM Cluster | aws_cloudhsm_v2_cluster | cloudhsm.tf | Cluster HA eu-west-3 |
| CloudHSM HSM #1 | aws_cloudhsm_v2_hsm | cloudhsm.tf | Instance eu-west-3a |
| CloudHSM HSM #2 | aws_cloudhsm_v2_hsm | cloudhsm.tf | Instance eu-west-3b |
| VPN Gateway | aws_vpn_gateway | vpn.tf | Virtual Private Gateway |
| Customer Gateway | aws_customer_gateway | vpn.tf | Gateway OVH |
| VPN Connection | aws_vpn_connection | vpn.tf | Tunnel IPSec |
| CloudWatch Log Group | aws_cloudwatch_log_group | monitoring.tf | Logs audit HSM |
| CloudWatch Alarms | aws_cloudwatch_metric_alarm | monitoring.tf | Alertes santé |
1.3 Configuration réseau
| Paramètre | Valeur | Justification |
| CIDR VPC | 10.0.0.0/16 | Isolation réseau HSM |
| CIDR Subnet HSM | 10.0.1.0/24 | Capacité suffisante, multi-AZ |
| Ports PKCS#11 | 2223-2225/TCP | Ports CloudHSM standard |
| VPN IKE | IKEv1 | Compatibilité OVH |
| VPN Encryption | AES-256 | R-36-02 (chiffrement fort) |
| VPN DH Group | 14 (2048-bit) | Sécurité recommandée |
1.4 Contrôles d'isolation réseau (R-36-02, TC-NEG-01)
L'accès PKCS#11 au HSM est exclusivement autorisé via le VPN IPSec. Les contrôles suivants garantissent cette isolation :
| Contrôle | Mécanisme | Fichier Terraform | Observable |
| Pas d'Internet Gateway | Le VPC HSM ne possède aucun Internet Gateway ni NAT Gateway. | vpc.tf | aws_internet_gateway absent du module |
| Security Group HSM | Inbound 2223-2225/TCP restreint au CIDR VPN OVH uniquement (10.x.x.x/xx ou CIDR OVH). Aucune règle 0.0.0.0/0. | security.tf | aws_security_group_rule.cidr_blocks ne contient que le CIDR VPN |
| Network ACL | NACL sur le subnet HSM : deny all sauf CIDR VPN sur ports 2223-2225. | security.tf | aws_network_acl_rule vérifié |
| Pas de peering/endpoint public | Aucun VPC peering, endpoint public ou Transit Gateway non autorisé. | Ensemble du module | Absence de aws_vpc_peering_connection, aws_vpc_endpoint (sauf CloudWatch si nécessaire) |
| Route table | Routes uniquement vers CIDR VPN via Virtual Private Gateway. Pas de route 0.0.0.0/0. | vpc.tf | aws_route_table vérifié |
Preuve pour TC-NEG-01 : Une tentative de connexion PKCS#11 depuis une IP publique (hors VPN) est physiquement impossible car le subnet HSM n'a aucune route vers Internet.
2. Mapping Invariants → Mécanismes
INV-01 — Non-exposition des clés privées
| Aspect | Détail |
| Mécanisme | Attribut PKCS#11 CKA_EXTRACTABLE=FALSE + CKA_SENSITIVE=TRUE sur toutes les clés privées |
| Configuration | Template de création de clé avec attributs non-exportables par défaut |
| Observable | C_GetAttributeValue(CKA_EXTRACTABLE) retourne FALSE |
| Tests associés | TC-NOM-01, TC-NOM-04, TC-ERR-02 |
| Preuve | Export attributs PKCS#11 dans inventaire trimestriel |
INV-02 — Non-exportabilité des clés privées
| Aspect | Détail |
| Mécanisme | Blocage natif CloudHSM + attributs PKCS#11 |
| Configuration | CKA_EXTRACTABLE=FALSE, CKA_WRAP=FALSE sur clés privées |
| Observable | C_WrapKey retourne CKR_KEY_UNEXTRACTABLE |
| Tests associés | TC-ERR-02, TC-INV-02 |
| Preuve | Log d'audit avec tentative d'export refusée |
INV-03 — Journalisation
| Aspect | Détail |
| Mécanisme | CloudHSM Audit Logs → CloudWatch Logs |
| Configuration | Log group /aws/cloudhsm/<cluster-id>, rétention 1825 jours (5 ans) |
| Observable | Présence d'événements pour chaque opération PKCS#11 (cf. §7.1.2 spec) |
| Tests associés | TC-NOM-01..04, TC-ERR-02..04 |
| Preuve | Export CloudWatch Logs, corrélation par session_id |
Événements minimum journalisés (cf. Spec §7.1.2) :
| Catégorie | Opération PKCS#11 | Données journalisées |
| Session | C_OpenSession, C_CloseSession | Timestamp, slot, user type, résultat |
| Authentification | C_Login, C_Logout | Timestamp, user type, résultat (succès/échec) |
| Génération de clé | C_GenerateKeyPair, C_GenerateKey | Timestamp, key handle, type, label, résultat |
| Signature | C_Sign, C_SignInit | Timestamp, key handle, mécanisme, résultat |
| Tentative d'export | C_WrapKey, C_GetAttributeValue (sensible) | Timestamp, key handle, résultat (refus attendu) |
| Suppression | C_DestroyObject | Timestamp, object handle, résultat |
Garanties de journalisation :
| Garantie | Mécanisme d'implémentation | Observable |
| Intégrité | CloudWatch Logs immuables (pas de suppression sans trace). Resource policy interdisant logs:DeleteLogGroup et logs:DeleteLogStream sauf rôle audit. | Resource policy CloudWatch Logs vérifiable |
| Horodatage UTC | Timestamps CloudHSM natifs synchronisés NTP. Configuration NTP vérifiée sur les instances HSM. | Format timestamp UTC dans chaque événement |
| Corrélation session_id | Chaque événement CloudHSM inclut un identifiant de session permettant le chaînage des opérations. | Champ session_id présent dans chaque log entry |
| Non-répudiation | Logs signés par AWS (attestation fournisseur CloudWatch). Digest CloudTrail pour intégrité des trails. | CloudTrail log file validation activé |
Granularité : Journalisation par opération PKCS#11 individuelle (non agrégée). Critère d'audit : Toute opération PKCS#11 listée ci-dessus DOIT être retrouvable dans les logs dans un délai de 24h (cf. Spec §7.1.2).
INV-04 — Séparation des clés
| Aspect | Détail |
| Mécanisme | Convention de nommage + validation applicative + séparation des privilèges CU + audit périodique |
| Configuration | Labels autorisés : pv-master-sign-*, pv-master-wrap-*, pv-tsa-*, pv-rotation-*, pv-*-expired-YYYY |
| Observable | Inventaire HSM ne contient que des labels conformes aux patterns |
| Tests associés | TC-NOM-03 |
| Preuve | Script d'audit vérifiant les labels vs patterns autorisés |
Contrôles de conformité INV-04 (défense en profondeur — 7 couches) :
| # | Couche | Contrôle | Mécanisme | Contournement résiduel |
| 1 | Séparation stricte des CU | Seul pv-crypto-user peut exécuter C_GenerateKeyPair / C_GenerateKey. Le CU pv-backend-svc est créé avec des droits restreints : C_Sign, C_Verify, C_OpenSession uniquement. Il ne possède pas le droit de créer, modifier ou supprimer des objets HSM. | Configuration CloudHSM : pv-backend-svc créé comme CU avec sharing restreint (le CO ne partage aucune clé avec droit de création vers ce CU). | Seul pv-crypto-user peut créer des clés. |
| 2 | Credentials isolés | Les credentials du CU pv-crypto-user ne sont jamais déployés sur le backend applicatif ni dans les variables d'environnement du runtime. Ils sont stockés exclusivement dans AWS Secrets Manager et accessibles uniquement via le rôle IAM HSM-CU-Role, distinct du rôle backend HSM-Backend-Role. | IAM policy : HSM-Backend-Role n'a pas secretsmanager:GetSecretValue sur le secret pv-crypto-user. | Le backend ne peut pas obtenir les credentials de création. |
| 3 | Validation applicative | Le Crypto Service (wrapper NestJS) valide le label contre les patterns autorisés avant tout appel C_GenerateKeyPair / C_GenerateKey. Tout label non conforme est rejeté côté applicatif avec log d'erreur. | Code du module src/modules/crypto/hsm/ | Protège contre erreur humaine lors des opérations de rotation. |
| 4 | Procédure de création sous quorum | Toute création de clé maître requiert une procédure formelle à 2 personnes : (1) le Crypto User prépare la demande (label, type, attributs), (2) un second opérateur (CO ou second CU désigné) valide visuellement la conformité du label avant exécution. La procédure est documentée dans docs/hsm-operations.md. | Procédure opérationnelle + checklist signée | Protège contre un CU unique malveillant ou négligent. |
| 5 | Détection temps réel | CloudWatch Logs metric filter sur tous les événements C_GenerateKeyPair / C_GenerateKey / C_CreateObject. Deux alarmes : (a) KeyCreation_Unexpected : toute création de clé déclenche une notification pour vérification. (b) KeyLabel_NonCompliant : si le label extrait du log ne match pas les patterns autorisés → alerte CRITICAL immédiate. | monitoring.tf (metric filter + alarm + SNS) | Détection en minutes, pas en trimestres. |
| 6 | Audit périodique | Job planifié (cron/Lambda) exécute mensuellement (et non trimestriellement) un inventaire complet des objets HSM (C_FindObjects + C_GetAttributeValue sur CKA_LABEL) et vérifie la conformité de chaque label. Tout objet non conforme déclenche une alerte CRITICAL et un incident de sécurité. | Script d'audit scripts/hsm-audit-inventory.sh | Filet de sécurité systématique. |
| 7 | Inventaire de référence | Un inventaire HSM de référence (baseline) est établi après chaque opération de création/rotation et stocké de façon immuable (S3 versionné eu-west-3). L'audit mensuel compare l'inventaire courant au dernier baseline : tout delta non autorisé = alerte CRITICAL. | Script d'audit + S3 bucket versionné | Détecte toute création non tracée. |
Synthèse de la chaîne de contrôle INV-04 :
Création de clé tentée
│
├── CU = pv-backend-svc ? → BLOQUÉ (pas de droit C_GenerateKeyPair)
│
├── CU = pv-crypto-user
│ │
│ ├── Procédure quorum 2 personnes respectée ?
│ │ │
│ │ ├── Label conforme aux patterns ? → OK (création autorisée)
│ │ └── Label non conforme → Rejeté par validation applicative
│ │
│ └── Accès PKCS#11 direct (hors applicatif) ?
│ │
│ ├── Alarme KeyCreation_Unexpected déclenchée (minutes)
│ ├── Alarme KeyLabel_NonCompliant si label invalide (minutes)
│ └── Audit mensuel détecte le delta vs baseline
│
└── CU inconnu ? → BLOQUÉ (pas de credential PKCS#11, cf. ACC-04)
Risque résiduel accepté (H-07) : Un CU pv-crypto-user agissant en dehors de la procédure et disposant d'un accès PKCS#11 direct pourrait théoriquement créer un objet hors taxonomie. Ce risque est mitigé par : (a) isolation des credentials (pas sur le backend), (b) quorum 2 personnes, © détection temps réel (alarme en minutes), (d) audit mensuel avec baseline. Le délai de détection maximal est de quelques minutes (alarme CloudWatch) et non plus trimestriel. La probabilité combinée (credential volé + procédure contournée + alerte ignorée) est jugée résiduelle.
3. Mapping Critères d'acceptation → Mécanismes
CA-01 — Certification FIPS 140-2 Level 3
| Aspect | Détail |
| Mécanisme | AWS CloudHSM utilise des HSM Cavium/Marvell certifiés FIPS 140-2 L3 |
| Configuration | Aucune (certification fournisseur) |
| Observable | Certificat NIST #3254 (ou successeur) vérifiable |
| Tests associés | TC-NOM-03 |
| Preuve | Lien NIST CMVP + métadonnées CloudHSM |
CA-02 — Connexion PKCS#11 via VPN
| Aspect | Détail |
| Mécanisme | VPN IPSec site-to-site OVH ↔ AWS + client PKCS#11 |
| Configuration | cloudhsm-pkcs11.cfg pointant vers ENI privées du cluster |
| Observable | C_GetSlotList retourne les slots du cluster |
| Tests associés | TC-NOM-01, TC-ERR-01 |
| Preuve | Log de session PKCS#11 établie |
CA-03 — Génération RSA 4096
| Aspect | Détail |
| Mécanisme | C_GenerateKeyPair avec mécanisme CKM_RSA_PKCS_KEY_PAIR_GEN |
| Configuration | Modulus bits = 4096, attributs template conformes |
| Observable | Handle de clé retourné, CKA_KEY_TYPE=CKK_RSA, CKA_MODULUS_BITS=4096 |
| Tests associés | TC-NOM-02 |
| Preuve | Log de génération + inventaire HSM |
CA-04 — Signature SHA-256 vérifiable
| Aspect | Détail |
| Mécanisme | C_Sign avec mécanisme CKM_SHA256_RSA_PKCS |
| Configuration | Clé de signature avec CKA_SIGN=TRUE |
| Observable | Signature produite, vérifiable avec clé publique exportée |
| Tests associés | TC-NOM-04 |
| Preuve | Signature + vérification hors HSM |
CA-05 — Latence P99 < 50 ms
| Aspect | Détail |
| Mécanisme | Mesure côté backend entre appel C_Sign et réception de la signature |
| Configuration | Instrumentation backend (métriques CloudWatch custom) |
| Observable | Percentile 99 sur N ≥ 1000 opérations < 50 ms |
| Tests associés | TC-PERF-01 |
| Preuve | Rapport de benchmark horodaté |
Conditions de mesure (cf. Spec §5.1 RNF-36-01) :
| Paramètre | Valeur |
| Opération cible | Signature RSA-4096 / SHA-256 via PKCS#11 (C_Sign) |
| Point de mesure | Temps écoulé entre l'appel C_Sign côté backend et la réception de la signature (timestamp_end - timestamp_start dans le wrapper Crypto Service) |
| Contexte réseau | Backend OVH (Paris) → VPN IPSec → AWS CloudHSM (eu-west-3 Paris) |
| Charge | Conditions nominales (< 100 opérations/seconde) |
| Échantillon | N ≥ 1000 opérations par run de benchmark |
| Métrique CloudWatch | SignLatencyP99 dans namespace Custom/HSM, calculée comme P99 sur la fenêtre de mesure |
| Reproductibilité | Mesures horodatées, conditions stables (pas de failover en cours, VPN établi) |
CA-06 — Failover automatique
| Aspect | Détail |
| Mécanisme | CloudHSM client library avec load balancing natif |
| Configuration | Cluster avec 2+ HSM, client configuré avec toutes les ENI |
| Observable | Opérations continuent lors de perte d'une instance |
| Tests associés | TC-ERR-03, TC-HA-01 |
| Preuve | Log de failover + métriques continuité |
CA-07 — Monitoring CloudWatch
| Aspect | Détail |
| Mécanisme | CloudWatch Metrics + Alarms pour cluster HSM |
| Configuration | Alarmes : HSMsHealth, HSMsAvailable, HSMsDegraded |
| Observable | Dashboard CloudWatch, alertes SNS configurées |
| Tests associés | TC-OBS-01 |
| Preuve | Screenshot dashboard + configuration alarmes |
CA-08 — Région EU exclusivement
| Aspect | Détail |
| Mécanisme | Déploiement Terraform restreint à eu-west-3 pour toutes les ressources |
| Configuration | provider "aws" { region = "eu-west-3" }, SCP IAM si multi-compte. Aucun provider alias vers une autre région. |
| Observable | aws cloudhsmv2 describe-clusters, aws logs describe-log-groups, aws cloudwatch describe-alarms, aws cloudtrail describe-trails, aws s3api get-bucket-location retournent eu-west-3 uniquement |
| Tests associés | TC-LOC-01 |
| Preuve | Configuration Terraform + métadonnées cluster + localisation vérifiée pour chaque ressource |
Périmètre de localisation (cf. Spec §5.3 RNF-36-03) :
| Ressource | Service AWS | Région imposée | Vérification Terraform |
| Cluster CloudHSM | CloudHSM | eu-west-3 | aws_cloudhsm_v2_cluster.availability_zones |
| Log group audit HSM | CloudWatch Logs | eu-west-3 | aws_cloudwatch_log_group dans provider eu-west-3 |
| Métriques custom | CloudWatch Metrics | eu-west-3 | aws_cloudwatch_metric_alarm dans provider eu-west-3 |
| CloudTrail logs | S3 | eu-west-3 | aws_s3_bucket avec bucket_regional_domain_name eu-west-3 |
| Sauvegardes HSM | CloudHSM (interne) | eu-west-3 | Géré nativement par CloudHSM dans la même région |
| Secrets Manager | Secrets Manager | eu-west-3 | aws_secretsmanager_secret dans provider eu-west-3 |
Contrainte : Un SCP (Service Control Policy) DOIT interdire la création de ressources CloudHSM, CloudWatch, S3 (buckets audit) et Secrets Manager hors eu-west-3 sur le compte AWS dédié.
4. Mapping Règles d'accès → Mécanismes
ACC-01 — Infra Admin sans credential PKCS#11
| Aspect | Détail |
| Mécanisme | Séparation stricte des users CloudHSM |
| Configuration | Aucun CU (Crypto User) créé pour les Infra Admins |
| Observable | listUsers CloudHSM ne contient pas d'entrée Infra Admin |
| Tests associés | TC-ERR-04 |
| Preuve | Inventaire users CloudHSM corrélé aux rôles |
ACC-02 — Backend via service account
| Aspect | Détail |
| Mécanisme | CU dédié pour le backend (pv-backend-svc) |
| Configuration | User CU avec credentials stockés en secret manager |
| Observable | Sessions PKCS#11 authentifiées avec ce user uniquement |
| Tests associés | Audit sessions |
| Preuve | Logs d'audit avec user_id = pv-backend-svc |
ACC-03 — Credentials PKCS#11 ≠ AWS IAM
| Aspect | Détail |
| Mécanisme | Users CloudHSM gérés séparément d'IAM |
| Configuration | Credentials CU dans AWS Secrets Manager (rotation) |
| Observable | Aucun chevauchement entre IAM users et CU users |
| Tests associés | Audit configuration |
| Preuve | Documentation des credentials |
ACC-04 — Échec sans credential valide
| Aspect | Détail |
| Mécanisme | Authentification PKCS#11 obligatoire |
| Configuration | Pas de session anonyme autorisée |
| Observable | C_Login échoue avec CKR_PIN_INCORRECT |
| Tests associés | TC-ERR-04, TC-NEG-02 |
| Preuve | Log d'audit avec échec authentification |
5. Mapping Cycle de vie → Mécanismes
KL-01 — Génération locale
| Aspect | Détail |
| Mécanisme | C_GenerateKeyPair / C_GenerateKey exécuté dans le HSM |
| Configuration | (1) Aucune importation de clé autorisée : C_CreateObject avec CKA_LOCAL=FALSE est interdit par politique. Le CU pv-backend-svc ne dispose pas de la capacité d'importer des clés. (2) Template de création exige CKA_TOKEN=TRUE (clé persistante). |
| Observable | C_GetAttributeValue(CKA_LOCAL) retourne TRUE et C_GetAttributeValue(CKA_TOKEN) retourne TRUE sur toutes les clés maîtres |
| Vérification | Le script d'audit trimestriel (cf. INV-04) vérifie systématiquement CKA_LOCAL=TRUE et CKA_TOKEN=TRUE sur chaque clé de l'inventaire HSM |
| Tests associés | TC-KL-01 |
| Preuve | Inventaire HSM horodaté avec attributs CKA_LOCAL, CKA_TOKEN exportés pour chaque clé |
KL-02 — Rotation annuelle
| Aspect | Détail |
| Mécanisme | Job planifié (cron/Lambda) vérifiant l'âge des clés |
| Configuration | Alerte si clé active > 365 jours, rotation manuelle assistée |
| Observable | Clés actives < 365 jours, anciennes marquées -expired-YYYY |
| Tests associés | TC-KL-02 |
| Preuve | Log de rotation + inventaire |
KL-03 — Conservation clés expirées
| Aspect | Détail |
| Mécanisme | Renommage de label avec suffixe -expired-YYYY |
| Configuration | Script de rotation préservant les clés |
| Observable | Clés expirées présentes dans inventaire |
| Tests associés | TC-KL-03 |
| Preuve | Inventaire HSM |
KL-04 — Blocage suppression
| Aspect | Détail |
| Mécanisme | Politique CloudHSM + vérification avant C_DestroyObject |
| Configuration | Aucune suppression autorisée sur clés ayant signé |
| Observable | C_DestroyObject échoue ou est bloqué |
| Tests associés | TC-KL-04 |
| Preuve | Log d'audit avec tentative bloquée |
6. Flux d'implémentation
Phase 1 : Infrastructure AWS (J1-J5)
┌─────────────────────────────────────────────────────────────────┐
│ 1.1 Création VPC et Subnets │
│ - VPC 10.0.0.0/16 │
│ - Subnet privé 10.0.1.0/24 (multi-AZ) │
│ - Route tables, Internet Gateway (pour NAT si besoin) │
├─────────────────────────────────────────────────────────────────┤
│ 1.2 Security Groups │
│ - SG HSM : inbound 2223-2225/TCP depuis CIDR VPN │
│ - SG Management : SSH restreint │
├─────────────────────────────────────────────────────────────────┤
│ 1.3 CloudHSM Cluster │
│ - Création cluster eu-west-3 │
│ - Association subnet │
│ - Génération CSR pour certificat cluster │
├─────────────────────────────────────────────────────────────────┤
│ 1.4 CloudHSM Instances │
│ - HSM #1 dans eu-west-3a │
│ - HSM #2 dans eu-west-3b │
│ - Vérification synchronisation │
└─────────────────────────────────────────────────────────────────┘
Dépendances : Aucune Critères de sortie : Cluster HSM actif avec 2 instances synchronisées
Phase 2 : VPN IPSec (J3-J7)
┌─────────────────────────────────────────────────────────────────┐
│ 2.1 Configuration côté AWS │
│ - Virtual Private Gateway attaché au VPC │
│ - Customer Gateway (IP publique OVH) │
│ - VPN Connection (2 tunnels pour HA) │
├─────────────────────────────────────────────────────────────────┤
│ 2.2 Configuration côté OVH │
│ - Import configuration VPN (fournie par AWS) │
│ - Configuration IPSec IKEv1/AES-256 │
│ - Routes vers CIDR AWS │
├─────────────────────────────────────────────────────────────────┤
│ 2.3 Validation connectivité │
│ - Test ping ENI HSM depuis OVH │
│ - Vérification tunnels UP │
│ - Test telnet ports 2223-2225 │
└─────────────────────────────────────────────────────────────────┘
Dépendances : Phase 1.1, 1.2 Critères de sortie : Connectivité réseau OVH ↔ HSM validée
Phase 3 : Initialisation HSM (J6-J8)
┌─────────────────────────────────────────────────────────────────┐
│ 3.1 Installation client CloudHSM │
│ - Package cloudhsm-client sur serveur OVH │
│ - Configuration cloudhsm.cfg (ENI addresses) │
│ - Certificat cluster importé │
├─────────────────────────────────────────────────────────────────┤
│ 3.2 Initialisation cluster (Crypto Officer) │
│ - Activation cluster │
│ - Création PRECO (Precrypto Officer) │
│ - Création CO (Crypto Officer) │
│ - Changement mot de passe PRECO │
├─────────────────────────────────────────────────────────────────┤
│ 3.3 Création users applicatifs │
│ - CU pv-backend-svc (service account backend, cf. ACC-02) │
│ - CU pv-crypto-user (opérations privilégiées : génération │
│ clés, rotation — correspond au rôle Crypto User §7.2) │
│ - Stockage credentials dans Secrets Manager │
└─────────────────────────────────────────────────────────────────┘
Dépendances : Phase 1.4, Phase 2.3 Critères de sortie : Cluster initialisé, users créés, credentials sécurisés
Phase 4 : Création des clés maîtres (J8-J10)
┌─────────────────────────────────────────────────────────────────┐
│ 4.1 Clé maître de signature probatoire │
│ - Label: pv-master-sign-2026 │
│ - Type: RSA 4096 │
│ - Attributs: SIGN=TRUE, EXTRACTABLE=FALSE │
├─────────────────────────────────────────────────────────────────┤
│ 4.2 Clé maître d'enveloppement │
│ - Label: pv-master-wrap-2026 │
│ - Type: AES 256 │
│ - Attributs: WRAP=TRUE, UNWRAP=TRUE, EXTRACTABLE=FALSE │
├─────────────────────────────────────────────────────────────────┤
│ 4.3 Clé d'horodatage TSA │
│ - Label: pv-tsa-2026 │
│ - Type: RSA 4096 │
│ - Attributs: SIGN=TRUE (RFC 3161) │
├─────────────────────────────────────────────────────────────────┤
│ 4.4 Export clés publiques │
│ - Export PEM des clés publiques │
│ - Stockage pour vérification tierce │
└─────────────────────────────────────────────────────────────────┘
Dépendances : Phase 3.2, 3.3 Critères de sortie : Clés maîtres créées avec attributs conformes, clés publiques exportées
Phase 5 : Intégration backend (J9-J14)
┌─────────────────────────────────────────────────────────────────┐
│ 5.1 Configuration PKCS#11 backend │
│ - Installation lib PKCS#11 CloudHSM │
│ - Configuration chemin lib dans application │
│ - Variables d'environnement (HSM_USER, HSM_PASSWORD) │
├─────────────────────────────────────────────────────────────────┤
│ 5.2 Service Crypto ProbatioVault │
│ - Module NestJS HSM/PKCS#11 │
│ - Wrapper sign(), verify(), wrapKey() │
│ - Gestion pool de sessions │
├─────────────────────────────────────────────────────────────────┤
│ 5.3 Tests d'intégration │
│ - TC-NOM-01 : Connexion PKCS#11 │
│ - TC-NOM-02 : Génération clé test │
│ - TC-NOM-04 : Signature/vérification │
└─────────────────────────────────────────────────────────────────┘
Dépendances : Phase 4 Critères de sortie : Backend capable de signer via HSM
Phase 6 : Monitoring CloudWatch (J10-J12)
┌─────────────────────────────────────────────────────────────────┐
│ 6.1 Configuration logs │
│ - Log group /aws/cloudhsm/<cluster-id> │
│ - Rétention : 1825 jours (5 ans) │
│ - Export vers SIEM si configuré │
├─────────────────────────────────────────────────────────────────┤
│ 6.2 Configuration métriques │
│ - Dashboard HSM santé │
│ - Métriques custom latence backend │
├─────────────────────────────────────────────────────────────────┤
│ 6.3 Configuration alarmes │
│ - HSMsDegraded > 0 → WARNING │
│ - HSMsAvailable < 2 → CRITICAL │
│ - Notification SNS │
└─────────────────────────────────────────────────────────────────┘
Dépendances : Phase 1.4 Critères de sortie : Dashboard fonctionnel, alarmes configurées
Phase 7 : Tests de validation (J13-J17)
┌─────────────────────────────────────────────────────────────────┐
│ 7.1 Tests nominaux │
│ - TC-NOM-01 à TC-NOM-04 │
│ - TC-LOC-01, TC-OBS-01 │
├─────────────────────────────────────────────────────────────────┤
│ 7.2 Tests d'erreur │
│ - TC-ERR-01 à TC-ERR-04 │
│ - TC-NEG-01 à TC-NEG-03 │
├─────────────────────────────────────────────────────────────────┤
│ 7.3 Tests de performance │
│ - TC-PERF-01 : Latence P99 │
│ - Benchmark 1000+ opérations │
├─────────────────────────────────────────────────────────────────┤
│ 7.4 Tests HA │
│ - TC-HA-01, TC-ERR-03 : Failover │
│ - Arrêt contrôlé HSM #1, vérification continuité │
├─────────────────────────────────────────────────────────────────┤
│ 7.5 Tests cycle de vie │
│ - TC-KL-01 à TC-KL-04 │
└─────────────────────────────────────────────────────────────────┘
Dépendances : Phase 5, Phase 6 Critères de sortie : Tous les TC passent, rapport de test généré
7. Gestion des erreurs
TC-ERR-01 — VPN indisponible
| Aspect | Détail |
| Condition | Tunnel VPN IPSec DOWN |
| Comportement attendu | C_OpenSession échoue avec timeout/erreur réseau |
| Code erreur | CKR_DEVICE_ERROR ou timeout socket |
| Observable | Log backend avec erreur connexion, métrique VPN DOWN |
| Mitigation | Retry avec backoff, alerte ops |
TC-ERR-02 — Tentative export clé privée
| Aspect | Détail |
| Condition | Appel C_WrapKey ou C_GetAttributeValue sur attribut sensible |
| Comportement attendu | Refus de l'opération |
| Code erreur | CKR_KEY_UNEXTRACTABLE, CKR_ATTRIBUTE_SENSITIVE |
| Observable | Log d'audit avec tentative refusée |
| Mitigation | Aucune (comportement normal de sécurité) |
TC-ERR-03 — Failover HSM
| Aspect | Détail |
| Condition | Perte d'une instance HSM |
| Comportement attendu | Opérations continuent sur l'autre instance |
| Code erreur | Aucun (transparent pour l'application) |
| Observable | Alarme CloudWatch, log de failover |
| Mitigation | Automatique via client library |
TC-ERR-04 — Accès non autorisé
| Aspect | Détail |
| Condition | Tentative d'opération sans credential valide |
| Comportement attendu | Authentification échoue |
| Code erreur | CKR_PIN_INCORRECT, CKR_USER_NOT_LOGGED_IN |
| Observable | Log d'audit avec échec authentification |
| Mitigation | Alerte sécurité si répétition |
TC-NEG-03 — Explosion d'erreurs PKCS#11 (throttling)
| Aspect | Détail |
| Condition | Répétition rapide de tentatives d'authentification échouées (mauvais PIN/credentials) |
| Mécanisme | CloudHSM applique un verrouillage natif du compte CU après un nombre configurable de tentatives échouées (par défaut : 5 tentatives consécutives). Après verrouillage, le compte CU est désactivé et doit être réactivé par le CO. |
| Comportement attendu | Les premières tentatives retournent CKR_PIN_INCORRECT ; après le seuil, le compte est verrouillé (CKR_USER_PIN_LOCKED ou équivalent). |
| Observable | (1) Métrique CloudWatch AuthFailures incrémentée à chaque échec. (2) Alarme Auth_Failure_Spike déclenchée si > 10 échecs en 5 min. (3) Log d'audit avec chaque tentative échouée (INV-03). (4) État du compte CU vérifié via listUsers (locked/unlocked). |
| Tests associés | TC-NEG-03 |
| Preuve | Logs d'audit + état du compte + notification d'alarme |
8. Sécurité
8.1 Gestion des credentials
| Secret | Stockage | Rotation | Accès |
| CO password | AWS Secrets Manager | Manuel (changement responsable) | Crypto Officer uniquement |
| CU pv-backend-svc | AWS Secrets Manager | Annuelle | Backend via IAM role |
| CU pv-crypto-user | AWS Secrets Manager | Annuelle | Crypto User désigné |
| VPN PSK | AWS Secrets Manager | Annuelle | Infra Admin |
8.2 Séparation des rôles
| Rôle | AWS IAM | CloudHSM User | Opérations autorisées |
| Crypto Officer | HSM-CO-Role | CO | Initialisation, politique |
| Crypto User (cf. Spec §7.2.1) | HSM-CU-Role | CU pv-crypto-user | C_Sign, C_Verify, C_GenerateKeyPair, C_GenerateKey, C_OpenSession, C_Login. Credentials non déployés sur le backend. Accès Secrets Manager via IAM HSM-CU-Role uniquement. |
| Backend applicatif (cf. Spec §7.2.1) | HSM-Backend-Role | CU pv-backend-svc | C_Sign, C_Verify, C_OpenSession uniquement. Pas de C_GenerateKeyPair, C_GenerateKey, C_CreateObject, C_DestroyObject. IAM policy interdit l'accès au secret pv-crypto-user. |
| Infra Admin | HSM-Infra-Role | Aucun | Console AWS (monitoring). Pas d'accès Secrets Manager pour les credentials PKCS#11. |
8.3 Audit trail
| Événement | Source | Destination | Rétention |
| Opérations PKCS#11 | CloudHSM | CloudWatch Logs | 5 ans |
| Accès AWS Console | CloudTrail | S3 + CloudWatch | 5 ans |
| VPN status | VPN Gateway | CloudWatch Metrics | 1 an |
| Alertes | CloudWatch Alarms | SNS → PagerDuty/Slack | - |
9. Observabilité
9.1 Métriques CloudWatch
| Métrique | Namespace | Description | Seuil alarme |
HSMsAvailable | AWS/CloudHSM | Nombre de HSM actifs | < 2 → CRITICAL |
HSMsDegraded | AWS/CloudHSM | HSM en état dégradé | > 0 → WARNING |
SessionCount | Custom/HSM | Sessions PKCS#11 actives | > 100 → WARNING |
SignLatencyP99 | Custom/HSM | Latence signature P99 | > 50ms → WARNING |
PKCS11SuccessRate | Custom/HSM | SLI disponibilité : ratio opérations PKCS#11 réussies / tentées | < 99.95% sur fenêtre glissante → WARNING |
VPNTunnelState | AWS/VPN | État tunnel VPN | DOWN → CRITICAL |
Mesure de disponibilité (cf. Spec §5.2 RNF-36-02) :
| Paramètre | Valeur | Mécanisme |
| SLI | Ratio opérations PKCS#11 réussies / opérations tentées | Métrique custom PKCS11SuccessRate calculée côté backend |
| Fenêtre de mesure | Mois calendaire glissant | Agrégation CloudWatch sur 30 jours glissants |
| Cible SLO | 99,95 % | Alarme CloudWatch si SLI < 99,95 % |
| Périmètre | Cluster HSM PROD (2 instances minimum) | Métriques collectées sur le cluster, pas par instance |
| Exclusions | Maintenance planifiée annoncée ≥ 48h à l'avance | Annotation CloudWatch pour exclure les fenêtres de maintenance |
| Preuve | Rapport mensuel exporté avec SLI calculé | Export CloudWatch Metrics horodaté |
9.2 Dashboard CloudWatch
┌─────────────────────────────────────────────────────────────────┐
│ PD-7 HSM Dashboard │
├─────────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
│ │ HSM Status │ │ VPN Status │ │ Operations/min │ │
│ │ 2/2 │ │ UP │ │ ████████ 142 │ │
│ └─────────────┘ └─────────────┘ └─────────────────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ Latency P99 (ms) │
│ 50 ─────────────────────────────────────── threshold │
│ 40 ████████████████████ │
│ 30 ████████████████████████████ │
│ 20 ████████████████████████████████████ │
│ ───────────────────────────────────────────────────────── │
│ 00:00 04:00 08:00 12:00 16:00 20:00 24:00 │
├─────────────────────────────────────────────────────────────────┤
│ Recent Audit Events │
│ • 14:32:01 C_Sign SUCCESS user=pv-backend-svc │
│ • 14:31:58 C_Sign SUCCESS user=pv-backend-svc │
│ • 14:30:00 C_Login SUCCESS user=pv-backend-svc │
└─────────────────────────────────────────────────────────────────┘
9.3 Alertes
| Alarme | Condition | Sévérité | Action |
| HSM_Degraded | HSMsDegraded > 0 for 5min | WARNING | Notification Slack |
| HSM_Critical | HSMsAvailable < 2 for 1min | CRITICAL | PagerDuty + Slack |
| VPN_Down | VPNTunnelState = DOWN for 2min | CRITICAL | PagerDuty + Slack |
| Latency_High | SignLatencyP99 > 50ms for 10min | WARNING | Notification Slack |
| Auth_Failure_Spike | AuthFailures > 10 in 5min | WARNING | Notification sécurité |
10. Hypothèses
| ID | Hypothèse | Impact si invalide | Mitigation |
| H-01 | OVH supporte VPN IPSec IKEv1 avec AES-256 | Connectivité impossible | Vérifier doc OVH avant démarrage |
| H-02 | Latence réseau OVH↔AWS < 20ms | SLA P99 < 50ms compromis | Mesurer avant engagement |
| H-03 | CloudHSM client library compatible avec version OS backend | Intégration bloquée | Vérifier matrice compatibilité |
| H-04 | Budget 3500€/mois couvre 2 HSM 24/7 | Surcoût potentiel | Valider pricing AWS avant commit |
| H-05 | NestJS supporte chargement lib native PKCS#11 | Développement custom requis | POC préalable |
| H-06 | Rétention CloudWatch 5 ans disponible | Archivage SIEM requis | Configurer export S3 si limite |
| H-07 | CloudHSM ne supporte pas de politique ACL native de filtrage par label d'objet | INV-04 repose sur contrôles compensatoires | Défense en profondeur 7 couches : séparation CU, isolation credentials IAM, validation applicative, quorum 2 personnes, détection temps réel, audit mensuel, baseline immuable. Risque résiduel jugé acceptable (détection en minutes). |
11. Points de vigilance
11.1 Risques techniques
| Risque | Probabilité | Impact | Mitigation |
| Latence VPN variable | Moyenne | Moyen | Monitoring continu, optimisation MTU |
| Rotation credentials oubliée | Moyenne | Élevé | Alerte automatique 30j avant expiration |
| Perte des 2 HSM simultanée | Faible | Critique | Backup cluster, DR plan |
| Évolution API CloudHSM | Faible | Moyen | Veille versions, tests de non-régression |
11.2 Risques opérationnels
| Risque | Probabilité | Impact | Mitigation |
| Crypto Officer indisponible | Moyenne | Élevé | 2 CO désignés, procédure backup |
| Perte credentials CO | Faible | Critique | Procédure recovery documentée |
| Modification accidentelle politique HSM | Faible | Élevé | Revue à 4 yeux, audit trail |
11.3 Checklist pré-production
12. Artefacts de sortie
| Artefact | Description | Responsable |
terraform/cloudhsm/ | Code IaC complet | Infra |
docs/hsm-operations.md | Procédures opérationnelles | Infra + Sécurité |
docs/hsm-disaster-recovery.md | Plan de reprise | Sécurité |
src/modules/crypto/hsm/ | Module NestJS HSM | Backend |
tests/e2e/hsm/ | Tests E2E HSM | QA |
reports/pd7-acceptance-*.pdf | Rapport d'acceptation | QA |
13. Estimation effort
| Phase | Effort | Équipe |
| Phase 1 : Infrastructure AWS | 3j | Infra (1) |
| Phase 2 : VPN IPSec | 2j | Infra (1) + OVH |
| Phase 3 : Initialisation HSM | 1j | Sécurité (1) |
| Phase 4 : Création clés | 0.5j | Sécurité (1) |
| Phase 5 : Intégration backend | 4j | Backend (1) |
| Phase 6 : Monitoring | 1j | Infra (1) |
| Phase 7 : Tests validation | 3j | QA (1) + Backend (0.5) |
| Total | 14.5j | - |
Fin du plan d'implémentation PD-7