263 lines
8.4 KiB
Markdown
263 lines
8.4 KiB
Markdown
# Runbook — Fuite de Données PII / Incident de Sécurité
|
||
|
||
**Alerte :** `VeylantPIIVolumeAnomaly` ou signalement client / équipe
|
||
**Réglementation :** RGPD Art. 33 — notification CNIL sous 72 heures si risque pour les personnes
|
||
**Commandement :** Ce runbook déclenche le plan de réponse aux incidents (IRP). Impliquer le DPO immédiatement.
|
||
|
||
---
|
||
|
||
## Symptômes
|
||
|
||
- Alerte `VeylantPIIVolumeAnomaly` : taux PII > 3× baseline
|
||
- Signalement client d'une exposition de données personnelles
|
||
- Audit log montrant des requêtes atypiques (volume anormal, tenant inconnu)
|
||
- Logs PII service : erreur de pseudonymisation, données non anonymisées retournées
|
||
- Accès non autorisé détecté via gitleaks ou SIEM
|
||
|
||
---
|
||
|
||
## Phase 1 — Détection et Triage (0-15 min)
|
||
|
||
### 1.1 Identifier la nature de l'incident
|
||
|
||
```bash
|
||
# Logs PII service (dernière heure)
|
||
kubectl logs -n veylant deploy/pii-service --since=1h | \
|
||
grep -E "(error|bypass|unmasked|pseudonym)" | tail -50
|
||
|
||
# Audit logs — requêtes suspectes
|
||
curl -sf -H "Authorization: Bearer $ADMIN_TOKEN" \
|
||
"https://api.veylant.ai/v1/admin/logs?limit=100&sort=desc" | \
|
||
jq '.[] | select(.pii_entities_count > 50) | {request_id, tenant_id, user_id, pii_count: .pii_entities_count, timestamp}'
|
||
|
||
# Vérifier les métriques PII anormales
|
||
curl -s "http://prometheus:9090/api/v1/query_range" \
|
||
--data-urlencode 'query=rate(veylant_pii_entities_detected_total[5m])' \
|
||
--data-urlencode 'start=1h ago' \
|
||
--data-urlencode 'end=now' \
|
||
--data-urlencode 'step=1m' | jq '.data.result[0].values[-10:]'
|
||
```
|
||
|
||
### 1.2 Classifier l'incident
|
||
|
||
| Niveau | Description | Action immédiate |
|
||
|--------|-------------|------------------|
|
||
| **P1 — Critique** | Données PII retournées en clair dans les réponses API | Isolation immédiate |
|
||
| **P2 — Élevé** | Anomalie volume PII, cause inconnue | Investigation + monitoring renforcé |
|
||
| **P3 — Moyen** | Pseudo non réversible exposé, pas de données réelles | Logging + rapport |
|
||
| **P4 — Info** | Alerte technique sans impact sur les données | Analyse, pas d'action urgente |
|
||
|
||
---
|
||
|
||
## Phase 2 — Isolation Immédiate (si P1)
|
||
|
||
**ARRÊTER le flux de données avant toute investigation.**
|
||
|
||
```bash
|
||
# Option A — Mode maintenance (impact utilisateurs, mais sécurisé)
|
||
curl -sf -X PATCH \
|
||
-H "Authorization: Bearer $ADMIN_TOKEN" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"enabled": true, "message": "Maintenance de sécurité en cours."}' \
|
||
https://api.veylant.ai/v1/admin/flags/maintenance-mode
|
||
|
||
echo "Maintenance mode ACTIVÉ — toutes les requêtes bloquées"
|
||
|
||
# Option B — Isoler un tenant spécifique seulement (si périmètre connu)
|
||
curl -sf -X PATCH \
|
||
-H "Authorization: Bearer $ADMIN_TOKEN" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"suspended": true, "reason": "security_incident"}' \
|
||
"https://api.veylant.ai/v1/admin/tenants/$AFFECTED_TENANT_ID"
|
||
|
||
echo "Tenant $AFFECTED_TENANT_ID suspendu"
|
||
```
|
||
|
||
### 2.2 Désactiver le service PII si compromis
|
||
|
||
```bash
|
||
# Désactiver le PII service (stoppe l'anonymisation — plus sécuritaire qu'un bypass)
|
||
kubectl scale deploy/pii-service -n veylant --replicas=0
|
||
|
||
echo "PII service arrêté — toutes les requêtes avec PII rejetées (fail_open=false)"
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 3 — Investigation (15-60 min)
|
||
|
||
### 3.1 Collecter les preuves
|
||
|
||
```bash
|
||
# Snapshot des logs d'audit (immuables dans ClickHouse)
|
||
curl -sf -H "Authorization: Bearer $ADMIN_TOKEN" \
|
||
"https://api.veylant.ai/v1/admin/logs?tenant_id=$TENANT_ID&limit=1000&format=csv" \
|
||
> incident_audit_$(date +%Y%m%d_%H%M%S).csv
|
||
|
||
# Export des métriques Prometheus au moment de l'incident
|
||
curl -s "http://prometheus:9090/api/v1/query_range" \
|
||
--data-urlencode "query=rate(veylant_pii_entities_detected_total[1m])" \
|
||
--data-urlencode "start=$(date -u -d '2 hours ago' +%s)" \
|
||
--data-urlencode "end=$(date -u +%s)" \
|
||
--data-urlencode "step=60" > pii_metrics_$(date +%Y%m%d).json
|
||
|
||
# Capture des logs système
|
||
kubectl logs -n veylant deploy/veylant-proxy-blue --since=2h > proxy_logs_$(date +%Y%m%d_%H%M%S).log
|
||
kubectl logs -n veylant deploy/pii-service --since=2h > pii_logs_$(date +%Y%m%d_%H%M%S).log
|
||
```
|
||
|
||
### 3.2 Analyser les données exposées
|
||
|
||
```bash
|
||
# Identifier quels types de PII ont été détectés
|
||
grep "entity_type" incident_audit_*.csv | \
|
||
awk -F',' '{print $NF}' | sort | uniq -c | sort -rn
|
||
|
||
# Identifier les utilisateurs concernés
|
||
grep "pii" incident_audit_*.csv | \
|
||
awk -F',' '{print $3}' | sort -u # colonne user_id
|
||
```
|
||
|
||
### 3.3 Vérifier la réversibilité des pseudonymes
|
||
|
||
```bash
|
||
# Les pseudonymes Redis sont-ils accessibles sans contexte tenant ?
|
||
# Tester depuis un tenant différent (devrait échouer)
|
||
curl -sf -X POST \
|
||
-H "Authorization: Bearer $OTHER_TENANT_TOKEN" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"text": "[PSEUDONYM_XXX]"}' \
|
||
https://api.veylant.ai/v1/pii/analyze
|
||
|
||
# Si le pseudonyme est résolu depuis un autre tenant → fuite critique (CVSS 9.0+)
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 4 — Notification RGPD (si données réelles exposées)
|
||
|
||
### Délai légal : 72 heures après prise de connaissance (RGPD Art. 33)
|
||
|
||
### 4.1 Notifier le DPO immédiatement
|
||
|
||
```
|
||
Contact DPO : [nom] — [email] — [téléphone]
|
||
Message type :
|
||
"Incident de sécurité potentiel détecté sur Veylant IA à [HH:MM].
|
||
Type : [description].
|
||
Données possiblement affectées : [types PII].
|
||
Utilisateurs potentiellement impactés : [N].
|
||
Investigation en cours. Présence requise immédiatement."
|
||
```
|
||
|
||
### 4.2 Préparer la notification CNIL
|
||
|
||
La notification doit inclure (RGPD Art. 33§3) :
|
||
- Nature de la violation
|
||
- Catégories et nombre approximatif de personnes concernées
|
||
- Catégories et nombre approximatif d'enregistrements concernés
|
||
- Nom et coordonnées du DPO
|
||
- Description des conséquences probables
|
||
- Mesures prises ou envisagées pour remédier
|
||
|
||
```bash
|
||
# Template notification CNIL (à compléter)
|
||
cat > cnil_notification_$(date +%Y%m%d).md << 'EOF'
|
||
# Notification de violation de données — RGPD Art. 33
|
||
|
||
**Date de la violation :** [DATE]
|
||
**Date de détection :** [DATE]
|
||
**Date de notification :** [DATE] (dans les 72h)
|
||
|
||
## Nature de la violation
|
||
[Description précise]
|
||
|
||
## Catégories de données affectées
|
||
- [ ] Noms/prénoms
|
||
- [ ] Emails
|
||
- [ ] Numéros de téléphone
|
||
- [ ] Données financières (IBAN, etc.)
|
||
- [ ] Données de santé
|
||
- [ ] Autres : [préciser]
|
||
|
||
## Personnes affectées
|
||
- Nombre approximatif : [N]
|
||
- Catégories : [employés, clients, etc.]
|
||
|
||
## Mesures prises
|
||
1. Isolation des systèmes affectés : [HH:MM]
|
||
2. Investigation en cours
|
||
3. [Autres mesures]
|
||
|
||
## Contact DPO
|
||
[Nom, email, téléphone]
|
||
EOF
|
||
```
|
||
|
||
### 4.3 Notifier les clients affectés (si données réelles exposées)
|
||
|
||
Délai recommandé : sans retard injustifié (RGPD Art. 34 si risque élevé pour les personnes)
|
||
|
||
```
|
||
Template email client :
|
||
Objet : [Important] Notification de sécurité — Veylant IA
|
||
|
||
Madame, Monsieur,
|
||
|
||
Nous vous informons d'un incident de sécurité détecté le [DATE] à [HH:MM]...
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 5 — Restauration et Post-mortem
|
||
|
||
### 5.1 Restaurer le service
|
||
|
||
```bash
|
||
# Redémarrer le PII service
|
||
kubectl scale deploy/pii-service -n veylant --replicas=1
|
||
kubectl rollout status deploy/pii-service -n veylant
|
||
|
||
# Désactiver le mode maintenance
|
||
curl -sf -X PATCH \
|
||
-H "Authorization: Bearer $ADMIN_TOKEN" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"enabled": false}' \
|
||
https://api.veylant.ai/v1/admin/flags/maintenance-mode
|
||
|
||
# Réactiver le tenant (si applicable)
|
||
curl -sf -X PATCH \
|
||
-H "Authorization: Bearer $ADMIN_TOKEN" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"suspended": false}' \
|
||
"https://api.veylant.ai/v1/admin/tenants/$AFFECTED_TENANT_ID"
|
||
|
||
# Smoke test post-restauration
|
||
curl -sf https://api.veylant.ai/healthz | jq .
|
||
```
|
||
|
||
### 5.2 Invalider les pseudonymes compromis (si applicable)
|
||
|
||
```bash
|
||
# Forcer la rotation des clés Redis de pseudonymisation
|
||
# ATTENTION : invalide TOUS les pseudonymes actifs → les mappings PII seront recréés
|
||
kubectl exec -n veylant deploy/redis -- redis-cli FLUSHDB
|
||
|
||
echo "Pseudonymes invalidés — nouveaux pseudonymes générés au prochain appel PII"
|
||
```
|
||
|
||
---
|
||
|
||
## Checklist Incident
|
||
|
||
- [ ] Incident détecté à [HH:MM]
|
||
- [ ] DPO notifié à [HH:MM] (< 15 min après détection)
|
||
- [ ] Isolation effectuée à [HH:MM]
|
||
- [ ] Preuves collectées (logs, métriques)
|
||
- [ ] Évaluation RGPD : notification CNIL requise ? [Oui/Non]
|
||
- [ ] Si oui : notification CNIL < 72h (deadline : [DATE HH:MM])
|
||
- [ ] Notification clients si risque élevé
|
||
- [ ] Service restauré à [HH:MM]
|
||
- [ ] Post-mortem planifié (J+3)
|
||
- [ ] Rapport de remédiation livré (J+7)
|