Aller au contenu principal

RGPD et protection des données avec OpenAI

L’IA et le RGPD : un cadre incontournable

Le Règlement Général sur la Protection des Données (RGPD) s’applique à toute application qui traite des données personnelles de résidents européens — y compris les applications basées sur des LLM. En 2026, les sanctions pour non-conformité touchent de plus en plus les systèmes IA. Cette leçon vous donne les clés pour utiliser les APIs OpenAI en conformité avec le RGPD.

Principes RGPD appliqués aux LLM

Les 7 principes fondamentaux

Principe Application IA
Licéité Base légale pour envoyer des données à l'API (consentement, intérêt légitime, contrat)
Minimisation N'envoyer que les données strictement nécessaires au modèle
Limitation des finalités Les données envoyées ne doivent servir qu'à la finalité déclarée
Exactitude Les sorties du modèle peuvent être inexactes — informer l'utilisateur
Limitation de conservation Vérifier la politique de rétention d'OpenAI et supprimer côté client
Sécurité Chiffrement en transit, contrôle d'accès, audit des logs
Responsabilité Documenter les choix et pouvoir démontrer la conformité

Minimisation des données : le principe clé

import re

class MinimiseurDonnees:
    """Anonymise les données personnelles avant envoi à l'API."""

    def __init__(self):
        self.mappings: dict[str, str] = {}
        self.compteur = 0

    def anonymiser(self, texte: str) -> str:
        """Remplace les données personnelles par des placeholders."""
        # Emails
        texte = re.sub(
            r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}",
            lambda m: self._remplacer(m.group(), "EMAIL"),
            texte,
        )
        # Téléphones français
        texte = re.sub(
            r"(?:0|\+33)[1-9](?:[\s.-]?\d{2}){4}",
            lambda m: self._remplacer(m.group(), "TEL"),
            texte,
        )
        # Noms (pattern simplifié — en production, utilisez un NER)
        texte = re.sub(
            r"\b(M\.|Mme|Dr)\s+[A-Z][a-zéèêë]+\s+[A-Z][a-zéèêë]+\b",
            lambda m: self._remplacer(m.group(), "PERSONNE"),
            texte,
        )
        # IBAN
        texte = re.sub(
            r"\b[A-Z]{2}\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{0,4}\b",
            lambda m: self._remplacer(m.group(), "IBAN"),
            texte,
        )
        return texte

    def _remplacer(self, valeur: str, type_: str) -> str:
        if valeur not in self.mappings:
            self.compteur += 1
            self.mappings[valeur] = f"[{type_}_{self.compteur}]"
        return self.mappings[valeur]

    def desanonymiser(self, texte: str) -> str:
        """Restaure les données originales dans la réponse."""
        reverse = {v: k for k, v in self.mappings.items()}
        for placeholder, original in reverse.items():
            texte = texte.replace(placeholder, original)
        return texte

# Utilisation
minimiseur = MinimiseurDonnees()

message_original = "M. Dupont ([email protected], 06 12 34 56 78) demande un remboursement."
message_anonymise = minimiseur.anonymiser(message_original)
print(f"Envoyé à l'API : {message_anonymise}")
# "[PERSONNE_1] ([EMAIL_1], [TEL_1]) demande un remboursement."

# Après réponse du modèle
reponse_modele = "Le dossier de [PERSONNE_1] a été traité. Un email a été envoyé à [EMAIL_1]."
reponse_finale = minimiseur.desanonymiser(reponse_modele)
print(f"Réponse finale : {reponse_finale}")

Configuration OpenAI pour le RGPD

Désactiver l’entraînement sur vos données

from openai import OpenAI

# Avec l'API, vos données ne sont PAS utilisées pour l'entraînement par défaut
# Mais vérifiez votre organisation settings sur platform.openai.com

client = OpenAI()

# L'endpoint Responses API respecte la politique de rétention
response = client.chat.completions.create(
    model="gpt-5.4",
    messages=[{"role": "user", "content": "Bonjour"}],
    # store=False désactive le stockage côté OpenAI si disponible
)

Gestion du consentement

class GestionConsentement:
    """Gère le consentement utilisateur pour le traitement IA."""

    def __init__(self):
        self.consentements: dict[str, dict] = {}

    def enregistrer_consentement(self, user_id: str, finalites: list[str]):
        """Enregistre le consentement explicite de l'utilisateur."""
        from datetime import datetime
        self.consentements[user_id] = {
            "finalites": finalites,
            "date": datetime.now().isoformat(),
            "version_politique": "v2.1",
            "moyen": "checkbox_explicite",
        }

    def verifier_consentement(self, user_id: str, finalite: str) -> bool:
        """Vérifie si l'utilisateur a consenti à une finalité spécifique."""
        if user_id not in self.consentements:
            return False
        return finalite in self.consentements[user_id]["finalites"]

    def retirer_consentement(self, user_id: str):
        """Retire le consentement et déclenche la suppression des données."""
        if user_id in self.consentements:
            del self.consentements[user_id]
            self._supprimer_donnees(user_id)

    def _supprimer_donnees(self, user_id: str):
        """Supprime toutes les données associées à l'utilisateur."""
        # Supprimer l'historique de conversation
        # Supprimer les logs contenant des données personnelles
        # Notifier les sous-traitants (OpenAI) si applicable
        print(f"Données supprimées pour {user_id}")

Droits des personnes concernées

Droit d’accès et portabilité

class DroitsPersonnesConcernees:
    """Implémente les droits RGPD des utilisateurs."""

    def droit_acces(self, user_id: str) -> dict:
        """Retourne toutes les données détenues sur l'utilisateur."""
        return {
            "donnees_personnelles": self._collecter_donnees(user_id),
            "finalites_traitement": ["assistance_client", "amelioration_service"],
            "sous_traitants": ["OpenAI (API LLM)", "PostgreSQL (stockage)"],
            "duree_conservation": "12 mois après dernière activité",
            "source": "Saisie directe par l'utilisateur",
        }

    def droit_effacement(self, user_id: str) -> dict:
        """Supprime toutes les données de l'utilisateur."""
        # Supprimer de la base locale
        donnees_supprimees = self._supprimer_local(user_id)
        # Les données envoyées à l'API OpenAI sont soumises
        # à leur politique de rétention (30 jours max via API)
        return {
            "statut": "supprime",
            "donnees_locales": "supprimées",
            "donnees_openai": "soumises à la rétention de 30 jours",
            "date": datetime.now().isoformat(),
        }

    def droit_portabilite(self, user_id: str) -> dict:
        """Exporte les données dans un format structuré."""
        donnees = self._collecter_donnees(user_id)
        return {
            "format": "JSON",
            "donnees": donnees,
            "date_export": datetime.now().isoformat(),
        }

    def _collecter_donnees(self, user_id: str) -> dict:
        return {"user_id": user_id, "conversations": [], "profil": {}}

    def _supprimer_local(self, user_id: str) -> int:
        return 0

Analyse d’Impact (AIPD/DPIA)

Pour toute application IA traitant des données personnelles à grande échelle, une Analyse d’Impact relative à la Protection des Données est obligatoire :

@dataclass
class AnalyseImpact:
    """Structure d'une AIPD pour un système IA."""
    nom_traitement: str
    description: str
    base_legale: str
    donnees_traitees: list[str]
    destinataires: list[str]
    transferts_hors_ue: list[dict]
    mesures_securite: list[str]
    risques: list[dict]
    avis_dpo: str = ""

aipd_chatbot = AnalyseImpact(
    nom_traitement="Chatbot service client avec IA",
    description="Assistant conversationnel utilisant GPT-5.4 via API OpenAI",
    base_legale="Intérêt légitime (assistance client)",
    donnees_traitees=["prénom", "email", "historique commandes", "messages chat"],
    destinataires=["Équipe support", "OpenAI (sous-traitant API)"],
    transferts_hors_ue=[{
        "destinataire": "OpenAI Inc.",
        "pays": "États-Unis",
        "garantie": "Clauses contractuelles types (CCT) + DPA OpenAI",
    }],
    mesures_securite=[
        "Anonymisation avant envoi à l'API",
        "Chiffrement TLS en transit",
        "Logs d'accès avec rétention 90 jours",
        "Droit d'effacement implémenté",
    ],
    risques=[{
        "description": "Fuite de données personnelles via prompt injection",
        "probabilite": "moyenne",
        "gravite": "elevee",
        "mesure_attenuation": "Guardrails anti-exfiltration + modération",
    }],
)

Points clés à retenir

  • Le RGPD s’applique dès qu’un système IA traite des données de résidents européens
  • La minimisation des données (anonymisation avant envoi à l’API) est le premier réflexe
  • Les droits des personnes (accès, effacement, portabilité) doivent être implémentés
  • L’AIPD est obligatoire pour les traitements IA à grande échelle
  • OpenAI fournit un DPA (Data Processing Agreement) pour encadrer le sous-traitance
  • Le transfert hors UE nécessite des garanties (CCT, évaluation d’impact du transfert)