cyber / cybersecurite-fondamentale
Conformité RGPD
Explication
Ce que vous allez apprendre
- Appliquer le principe de minimisation des données dès la conception d'un formulaire
- Implémenter techniquement les droits d'accès, de portabilité et d'effacement des données
- Concevoir un mécanisme de consentement traçable, granulaire et facile à retirer
- Respecter le délai de 72 heures de notification à l'autorité de contrôle en cas de violation
- Tenir un registre des traitements et appliquer le privacy by design dès la conception
Dans quel contexte ?
Un utilisateur demande la suppression de son compte sur une plateforme e-learning, invoquant son droit à l'oubli. Si l'équipe technique se contente de marquer un champ is_deleted = true en base sans réellement supprimer ou anonymiser les données personnelles, l'entreprise reste en infraction : le RGPD exige une suppression ou une anonymisation réelle, pas une simple case cochée invisible pour l'utilisateur mais toujours exploitable en interne.
Quand la sécurité devient aussi une obligation légale
Jusqu'ici, le cours a traité la sécurité comme une discipline technique. Le RGPD (Règlement Général sur la Protection des Données) rappelle qu'elle est aussi une obligation légale envers les personnes dont on traite les données — et que les manquements techniques vus dans ce cours (fuite de données, absence de chiffrement, IDOR) peuvent avoir des conséquences juridiques directes pour l'entreprise.
Le principe de minimisation, une idée simple mais souvent négligée
Piège fréquent
Ne collecter QUE les données réellement nécessaires à une finalité précise, et ne les conserver que le temps nécessaire. C'est contre-intuitif pour beaucoup de développeurs habitués à "collecter au cas où ça serait utile un jour" — mais chaque donnée collectée est aussi une donnée qui peut fuiter, donc un risque en plus, pas seulement un actif.
Les droits des utilisateurs ne sont pas juste une page de mentions légales
| Droit | Ce qu'il exige techniquement |
|---|---|
| Accès et portabilité (Art. 15 & 20) | Un export réel de toutes les données de l'utilisateur |
| Effacement (Art. 17) | Une suppression ou anonymisation réelle, pas un simple flag |
| Consentement (Art. 7) | Traçable, granulaire, et aussi facile à retirer qu'à donner |
Le consentement, traçable et réversible
Un consentement obtenu par une case pré-cochée ou un bouton "accepter" disproportionnellement plus visible que "refuser" ne serait pas considéré comme valide.
La règle des 72 heures
En cas de violation de données, la notification à l'autorité de contrôle (la CNIL en France) doit intervenir sous 72 heures après la prise de connaissance de l'incident — un délai qui n'est possible à tenir que si l'entreprise avait déjà, en amont, une procédure de réponse à incident bien préparée (voir la leçon sur le forensics). Toute violation, même jugée à faible risque, doit être documentée avec une justification de l'analyse, pas seulement les incidents les plus graves.
Commandes & code
Conformité RGPD
Le RGPD (Règlement Général sur la Protection des Données) impose des obligations techniques et organisationnelles concrètes pour toute plateforme traitant des données de personnes situées dans l'UE.
# Principes clés du RGPD (Article 5)
Licéité, loyauté, transparence : base légale claire pour chaque traitement (consentement, contrat, obligation légale...)
Limitation des finalités : collecter une donnée pour un but précis, ne pas la réutiliser hors de ce but
Minimisation des données : ne collecter QUE les données strictement nécessaires
Exactitude : les données doivent être tenues à jour
Limitation de la conservation : durée de rétention définie, suppression après expiration
Intégrité et confidentialité : sécurité technique (chiffrement, contrôle d'accès - voir leçons précédentes)# Minimisation des données : ne demander que ce qui est réellement nécessaire au formulaire d'inscription
from pydantic import BaseModel, EmailStr
# VULNÉRABLE au sens RGPD : collecte excessive sans finalité claire
class RegisterRequestBad(BaseModel):
email: EmailStr
password: str
phone_number: str # nécessaire ? si non utilisé, ne pas le collecter
date_of_birth: str # nécessaire seulement si vérification d'âge légalement requise
home_address: str # clairement excessif pour une plateforme e-learning
# CORRECT : uniquement ce qui est nécessaire au fonctionnement du service
class RegisterRequestGood(BaseModel):
email: EmailStr
password: str
display_name: str# Droit d'accès et droit à la portabilité (Article 15 & 20) : export des données utilisateur
from fastapi import Depends
import json
@app.get("/account/export")
async def export_my_data(current_user=Depends(get_current_user), db=Depends(get_db)):
data = {
"profile": {"email": current_user.email, "display_name": current_user.display_name},
"courses_progress": [p.to_dict() for p in get_user_progress(current_user.id, db)],
"consents": [c.to_dict() for c in get_user_consents(current_user.id, db)],
}
return JSONResponse(content=data, headers={"Content-Disposition": "attachment; filename=mes_donnees.json"})# Droit à l'effacement (Article 17, "droit à l'oubli") : suppression réelle, pas seulement un flag "deleted"
@app.delete("/account")
async def delete_my_account(current_user=Depends(get_current_user), db=Depends(get_db)):
# Anonymisation/suppression en cascade de toutes les données personnelles liées
db.query(UserSession).filter(UserSession.user_id == current_user.id).delete()
db.query(UserConsent).filter(UserConsent.user_id == current_user.id).delete()
current_user.email = f"deleted-{current_user.id}@anonymized.local"
current_user.display_name = "Utilisateur supprimé"
current_user.is_deleted = True
# Certaines données peuvent devoir être conservées pour obligation légale (factures : 10 ans en France)
# -> les isoler et documenter la base légale de cette conservation dérogatoire
db.commit()# Gestion du consentement : traçable, granulaire, et révocable à tout moment
from datetime import datetime, timezone
from sqlalchemy import Column, Integer, String, DateTime, Boolean, ForeignKey
class UserConsent(Base):
__tablename__ = "user_consents"
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey("users.id"))
purpose = Column(String) # ex: "marketing_emails", "analytics_cookies"
granted = Column(Boolean)
granted_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
revoked_at = Column(DateTime(timezone=True), nullable=True)
consent_version = Column(String) # version du texte de consentement présenté (traçabilité)
# Le consentement doit être : donné librement, spécifique, informé, univoque (pas de case pré-cochée)# Registre des traitements (Article 30) - document obligatoire à tenir à jour
| Traitement | Finalité | Base légale | Données collectées | Durée de conservation | Destinataires |
|------------------------|-------------------------|-------------|---------------------------|--------------------------|---------------------|
| Création de compte | Fourniture du service | Contrat | email, mot de passe hashé | Durée du compte + 30j | Interne uniquement |
| Facturation | Obligation légale | Obligation légale | nom, adresse, montant | 10 ans | Comptable, fisc |
| Newsletter | Marketing | Consentement | email | Jusqu'à retrait du consentement | Prestataire d'emailing |# Notification de violation de données (Article 33 & 34)
- Notification à l'autorité de contrôle (CNIL en France) sous 72h après prise de connaissance de la violation
- Si risque élevé pour les personnes concernées : notification directe aux personnes affectées, sans délai excessif
- Documenter systématiquement TOUTE violation (même celles jugées à faible risque), avec justification de l'analyse# Privacy by design et by default (Article 25) - à appliquer dès la conception de toute nouvelle fonctionnalité
1. Chiffrement des données personnelles sensibles au repos (voir leçon chiffrement symétrique)
2. Pseudonymisation quand la finalité le permet (ex: analytics sans identifiant direct)
3. Paramètres de confidentialité les plus protecteurs activés PAR DÉFAUT (opt-in, pas opt-out)
4. Analyse d'impact relative à la protection des données (AIPD/DPIA) pour tout traitement à risque élevéRésumé
- Minimisation, limitation des finalités et durée de conservation définie sont les piliers opérationnels du RGPD.
- Les droits d'accès, de portabilité et d'effacement doivent être implémentés comme de vraies fonctionnalités techniques.
- Le consentement doit être traçable, granulaire et aussi facile à retirer qu'à donner.
- Une violation de données se notifie sous 72h à l'autorité de contrôle, et le registre des traitements se tient à jour en continu.
Exercices pratiques
Mission : la suppression de compte qui n'en est pas une
Objectif : Évaluer la conformité réelle d'une implémentation du droit à l'effacement et concevoir la procédure de notification en cas de violation.
Contexte
Un utilisateur de Technologik exerce son droit à l'oubli et demande la suppression de son compte. Le code actuel du endpoint DELETE /account exécute uniquement current_user.is_deleted = True puis db.commit(), sans toucher aux autres champs ni aux tables liées (sessions, consentements).