PII et data masking : arrêter de disséminer les données personnelles partout
Les données personnelles se répandent dans les logs, la staging, l'analytics et les exports, bien au-delà de la table users. Un guide pratique du masking, de la pseudonymisation et de l'anonymisation, et savoir laquelle vous avez vraiment faite.
Le difficile, pour protéger les données personnelles, ce n’est pas la table users. Tout le monde sait qu’elle contient de la PII. Le problème, c’est partout ailleurs où elle finit discrètement : une adresse email dans un log d’erreur, une copie complète de la base de prod dans la staging, un nom de client dans un événement analytics, un numéro de téléphone dans un export de support, un corps de requête collé dans un prompt LLM.
La PII (information personnellement identifiable) fuit par défaut, parce que copier des données est pratique et que personne ne s’arrête pour demander si la copie a encore besoin d’être personnelle. Voici un guide pratique pour la masquer : les techniques, où appliquer chacune, et la distinction qui décide si vous avez vraiment réduit votre risque ou seulement déplacé.
Ça complète le guide sur la rétention et la suppression des données RGPD. Celui-là parle de combien de temps vous gardez la donnée et comment la supprimer. Celui-ci parle de faire en sorte que les copies que vous gardez cessent d’être des données personnelles au départ.
Avertissement habituel : je suis développeur, pas juriste. Ceci est un guide d’implémentation, pas un conseil juridique.
La distinction qui compte vraiment
Trois mots sont utilisés de façon interchangeable et ne sont pas la même chose. Les clarifier, c’est tout le jeu, parce qu’ils ont des conséquences légales différentes sous RGPD.
- Masking / redaction : remplacer la valeur par quelque chose de non sensible, en général de façon irréversible, pour l’affichage ou le stockage.
john@acme.comdevientj***@acme.comou[REDACTED]. L’original a disparu de cette copie. - Pseudonymisation : remplacer les identifiants par un token réversible, où une clé séparée peut remonter à la vraie valeur.
john@acme.comdevientuser_8f3a, et une table de correspondance ou une clé peut l’inverser. Le RGPD l’encourage, mais il est crucial de comprendre : la donnée pseudonymisée reste une donnée personnelle. Vous détenez encore la correspondance, donc elle reste dans le périmètre de la rétention, de l’effacement et des règles de violation. - Anonymisation : transformer la donnée pour que personne, vous compris, ne puisse la relier à une personne, même en la combinant avec d’autres données. Une donnée vraiment anonymisée n’est plus une donnée personnelle et sort du RGPD. C’est bien plus dur qu’il n’y paraît, parce que la ré-identification à partir de jeux “anonymes” est une attaque bien documentée.
Le piège, c’est de faire de la pseudonymisation, de l’appeler anonymisation, et de se croire hors périmètre. Vous ne l’êtes pas. Si vous avez gardé un chemin de retour, c’est de la pseudonymisation, et la donnée reste régulée. Ne dites “anonymisé” que quand vous avez réellement jeté la capacité de ré-identifier.
Où masquer : statique vs dynamique
Il y a deux moments où masquer, et ils résolvent des problèmes différents.
Le masking statique transforme la donnée au repos, produisant une copie assainie. C’est celui pour les environnements hors production. L’échec RGPD classique, c’est de cloner la base de prod dans la staging pour que les développeurs aient des “données réalistes”, ce qui veut dire que chaque ingénieur, chaque run de CI, et chaque machine de staging moins sécurisée détient maintenant de la vraie PII client. À la place, masquez à la sortie :
-- construire un dump de staging avec noms et emails masqués
UPDATE users SET
email = 'user' || id || '@example.com',
full_name = 'User ' || id,
phone = NULL;
Mieux encore, générez un seed synthétique qui a l’air réel mais ne décrit aucune personne réelle, pour que la staging ne contienne jamais de PII de prod. Dans tous les cas, de vraies données de production dans un environnement hors production sont l’exposition évitable la plus courante.
Le masking dynamique transforme la donnée à la lecture, selon qui demande. Un agent de support voit **** 4242, un service de paiement voit le numéro complet. La valeur stockée est intacte ; le masquage se fait dans la couche de requête ou la réponse d’API. Utilisez-le quand des rôles différents ont légitimement besoin de vues différentes du même enregistrement, et ne comptez jamais sur le frontend pour le faire : masquez côté serveur, parce que tout ce que le client cache, le client peut aussi le révéler.
Techniques de masking, et leurs pièges
Tout masking ne se vaut pas, et la version naïve casse des choses :
- Le masking aléatoire remplace chaque valeur par une valeur aléatoire. Sûr, mais il détruit les relations : le même utilisateur reçoit des valeurs masquées différentes dans deux tables, donc vos données de staging ne se joignent plus.
- Le masking déterministe mappe chaque entrée vers la même sortie à chaque fois (en général un hash à clé).
john@acme.comdevient toujoursuser_8f3a, partout. Ça préserve les jointures et l’unicité, ce qui rend la donnée masquée réellement utilisable. Le hic : le masking déterministe est de la pseudonymisation, pas de l’anonymisation, et il est vulnérable à la corrélation, donc gardez la clé secrète et traitez la sortie comme encore personnelle. - Le masking préservant le format garde la forme pour que les validateurs et les types de colonnes passent encore : une carte masquée fait toujours 16 chiffres, un email masqué a toujours un
@. Nécessaire quand du code en aval vérifie le format.
Ne loggez pas de PII au départ
Les logs méritent leur propre section parce qu’ils sont la fuite que personne ne remarque avant une violation. Un email dans une stack trace, une IP dans un log d’accès, un corps de requête complet capturé “temporairement” pour du débogage : tout ça est de la donnée personnelle, dans un système conçu pour être append-only et largement lisible.
Vous ne ferez pas de suppressions par utilisateur sur un firehose de logs, donc le contrôle doit être à l’écriture :
- Logging structuré avec une allowlist. Loggez des champs explicites, jamais des objets entiers.
logger.info({ userId, action }), paslogger.info(user), qui déverse l’email, le nom et tout le reste dès que quelqu’un logge l’objet. - Une couche de redaction. La plupart des libs de logging supportent des chemins de redaction qui retirent les clés connues comme sensibles (
password,email,authorization,token) avant toute écriture. Configurez-la une fois, au centre. - De la détection pour le texte libre. La redaction structurée rate la PII noyée dans des chaînes libres (un email tapé dans un corps de message). Pour ça, une lib de détection comme Microsoft Presidio peut trouver et masquer les motifs de PII courants (emails, numéros, noms) avant le log ou avant que la donnée quitte votre système.
Le contrôle le moins cher de loin, c’est de ne pas écrire la PII. La redaction après coup est toujours plus chère et jamais complète.
Une approche pratique
Vous n’avez pas besoin d’une plateforme de data masking pour commencer. Par ordre d’impact :
- Arrêtez de cloner la prod dans le hors-prod. Masquez le dump, ou générez un seed synthétique. Ça tue l’exposition la plus grande immédiatement.
- Redactez la PII dans la couche de logging. Allowlist de champs, retrait des clés sensibles, détection en texte libre là où vous loggez du contenu utilisateur.
- Utilisez le masking déterministe quand la donnée masquée doit rester joignable, et rappelez-vous que c’est encore pseudonymisé (gardez la clé au chaud).
- Masquez dynamiquement pour les vues par rôle, toujours côté serveur.
- Soyez honnête sur anonymisé vs pseudonymisé. Si vous avez gardé un chemin de retour, c’est encore une donnée personnelle, avec toutes les obligations de rétention et d’effacement que ça implique.
Rien de tout ça n’est exotique. C’est surtout décider, par copie de la donnée, si cette copie a besoin d’identifier une personne réelle, et sinon, retirer sa capacité à le faire. Les systèmes qui se font violer le sont rarement par la table users. Ils le sont par la quatrième machine de staging et l’archive de logs de deux ans que tout le monde avait oublié pleine de vraies personnes.