Procedure de reprise wallet Ethereum — PD-177¶
Version : 1.0 Date : 2026-02-23 INV-177-18 : Procedure de reprise testee INV-177-19 : Rotation preserve auditabilite
1. Objectif¶
Procedure de reprise du wallet Ethereum ProbatioVault apres incident custody (strategie S2 — AWS KMS secp256k1).
2. Prerequis¶
| Prerequis | Responsable | Verification |
|---|---|---|
| Acces AWS Console avec IAM role KMS | SRE on-call | aws kms describe-key --key-id <KEY_ARN> |
| Identifiants S2 de secours (backup KMS key ARN) | Security lead | Stockes dans Vault kv/app/kms-backup |
| Acces au serveur applicatif (SSH ou console) | SRE on-call | Verification du service NestJS |
| Acces au dashboard monitoring (Grafana/Datadog) | SRE on-call | Dashboard blockchain-anchor actif |
3. Scenarios couverts¶
Scenario A — Indisponibilite temporaire du service KMS¶
Symptome : Erreur SIGNATURE_FAILED dans les logs du worker d'ancrage. Cause probable : Incident AWS KMS regional, maintenance planifiee, ou throttling. Gravite : MOYENNE (les batches s'accumulent mais aucune donnee n'est perdue).
Scenario B — Rotation d'urgence de la cle KMS¶
Symptome : Alerte securite ou suspicion de compromission de la cle. Cause probable : Detection d'activite anormale sur la cle KMS, alerte CloudTrail. Gravite : HAUTE (risque de signature frauduleuse).
Scenario C — Compromission suspectee du serveur applicatif¶
Symptome : Transactions non autorisees, logs alteres, intrusion detectee. Cause probable : Exploitation de vulnerabilite, credentials compromis. Gravite : CRITIQUE (risque d'integrite des preuves).
4. Etapes de reprise¶
Etape 1 — Isolation du service¶
| Action | Commande | Verification |
|---|---|---|
| Arreter le worker d'ancrage BullMQ | systemctl stop probatiovault-anchor-worker | Verifier STOPPED dans les logs |
| Desactiver le cron/scheduler | Commenter le job dans la config | Pas de nouveau batch cree |
| Notifier l'equipe | Canal Slack #incident-blockchain | Accusé de réception |
Temps estime : 5 minutes
Etape 2 — Diagnostic¶
| Verification | Commande / Outil | Resultat attendu |
|---|---|---|
| Etat de la cle KMS | aws kms describe-key --key-id <KEY_ARN> | KeyState: Enabled |
| Derniere transaction signee | Query SELECT * FROM vault_blockchain.anchor_batches ORDER BY submitted_at DESC LIMIT 1 | Batch coherent |
| Logs du service (30 derniers min) | journalctl -u probatiovault-api --since "30 min ago" \| grep blockchain | Identifier les erreurs |
| Etat du wallet | Appel WalletOperationalService.getOperationalState() | operational: true/false |
Temps estime : 10 minutes
Etape 3 — Decision¶
| Condition | Decision | Suite |
|---|---|---|
| KMS temporairement indisponible, pas de compromission | Reprise en l'etat | Etape 5 (verification) → Etape 6 (retour) |
| Compromission suspectee OU rotation planifiee | Rotation | Etape 4 (rotation) → Etape 5 → Etape 6 |
| Compromission confirmee du serveur | Rotation + audit forensique | Etape 4 + investigation parallele |
Etape 4 — Rotation (si necessaire)¶
IMPORTANT : La rotation preserve l'auditabilite (INV-177-19).
| # | Action | Detail |
|---|---|---|
| 4.1 | Creer une nouvelle cle KMS | aws kms create-key --key-spec ECC_SECG_P256K1 --key-usage SIGN_VERIFY --description "pv-master-signing-YYYY" |
| 4.2 | Generer l'adresse Ethereum | Via WalletOperationalService.initialize() avec la nouvelle cle |
| 4.3 | Consigner la rotation | Remplir wallet-rotation-log-template.md |
| 4.4 | Mettre a jour la configuration | Variable d'env KMS_KEY_ARN ou secret Vault |
| 4.5 | Desactiver l'ancienne cle (ne PAS supprimer) | aws kms disable-key --key-id <OLD_KEY_ARN> |
INTERDIT : Supprimer l'ancienne cle KMS. Elle est necessaire pour verifier les signatures des batches historiques.
Temps estime : 20 minutes
Etape 5 — Verification¶
| # | Verification | Commande | Critere de succes |
|---|---|---|---|
| 5.1 | Test de signature | WalletOperationalService.getOfficialAddress() | Adresse resolue sans erreur |
| 5.2 | Verification adresse | Comparer avec l'adresse attendue (rotation: nouvelle adresse) | Match exact |
| 5.3 | Transactions historiques | SELECT COUNT(*) FROM vault_blockchain.anchor_batches WHERE status = 'FINALIZED' | Comptage identique a avant l'incident |
| 5.4 | Verification de preuve | AnchorProofValidator.validateProofChain() sur le dernier batch FINALIZED | Chaine complete |
Temps estime : 10 minutes
Etape 6 — Retour en service¶
| # | Action | Verification |
|---|---|---|
| 6.1 | Redemarrer le worker d'ancrage | systemctl start probatiovault-anchor-worker |
| 6.2 | Reactiver le scheduler | Decommenter le job |
| 6.3 | Monitoring actif (30 min) | Dashboard Grafana, alertes Slack |
| 6.4 | Verifier le premier batch post-reprise | Query + verification signer_address |
| 6.5 | Clore l'incident | Mise a jour du canal Slack, rapport post-mortem |
Temps estime : 35 minutes (dont 30 min monitoring)
5. Template de rapport d'exercice¶
exercise_id: "<crypto.randomUUID()>"
scenario_id: "A|B|C"
started_at: "2026-XX-XXTXX:XX:XX.XXXZ"
completed_at: "2026-XX-XXTXX:XX:XX.XXXZ"
status: "success|failure"
steps:
- step: 1
name: "Isolation du service"
status: "success|failure|skipped"
duration_seconds: 0
notes: ""
- step: 2
name: "Diagnostic"
status: "success|failure|skipped"
duration_seconds: 0
notes: ""
- step: 3
name: "Decision"
status: "success|failure|skipped"
duration_seconds: 0
notes: ""
- step: 4
name: "Rotation"
status: "success|failure|skipped"
duration_seconds: 0
notes: ""
- step: 5
name: "Verification"
status: "success|failure|skipped"
duration_seconds: 0
notes: ""
- step: 6
name: "Retour en service"
status: "success|failure|skipped"
duration_seconds: 0
notes: ""
audit_trail: "<reference audit log entry>"
responsible: "<nom du SRE>"
6. Historique des exercices¶
| Date | Scenario | Resultat | Responsable | Duree totale | Notes |
|---|---|---|---|---|---|
| A remplir lors du premier exercice |