veylant/docs/runbooks/pii-breach.md
2026-02-23 13:35:04 +01:00

8.4 KiB
Raw Blame History

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

# 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.

# 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

# 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

# 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

# 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

# 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
# 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

# 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)

# 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)