Introduction
Le Privacy Engineering est l'ensemble des pratiques qui intègrent la protection des données personnelles dès la conception d'un système, suivant les principes de Privacy by Design. En 2026, avec l'essor de l'IA et des régulations comme le RGPD (GDPR en Europe) et la CNIL renforcée, ignorer la privacy expose à des amendes massives (jusqu'à 4% du CA mondial). Ce tutoriel beginner vous guide pas à pas pour implémenter des techniques essentielles : identification des PII (Personally Identifiable Information), pseudonymisation via hashing, anonymisation, et gestion du consentement.
Pourquoi c'est crucial ? Imaginez un e-commerce : sans privacy engineering, un leak d'emails ruine la confiance. Ici, on part des bases avec Node.js pour créer un outil concret qui traite 1000 entrées de données users, les protège, et vérifie le consentement. À la fin, vous aurez un script fonctionnel, prêt à scaler. (128 mots)
Prérequis
- Node.js 20+ installé
- Connaissances basiques en JavaScript/TypeScript
- Un éditeur comme VS Code
- Terminal (bash ou PowerShell)
Initialiser le projet
mkdir privacy-engineer-demo
cd privacy-engineer-demo
npm init -y
npm install typescript @types/node crypto-js ts-node
npm install -D @types/crypto-js
npx tsc --init
mkdir src
data/users.jsonCette commande crée un projet Node.js TypeScript et installe CryptoJS pour le hashing sécurisé. Le fichier users.json sera créé manuellement pour simuler des données PII. Évitez npm install sans lockfile pour la reproductibilité.
Identifier les PII dans vos données
Les PII incluent email, IP, nom, etc. Utilisez une regex simple pour les détecter. Analogie : comme un scanner anti-virus pour virus, scannez vos datasets pour PII avant traitement. Exemple concret : dans data/users.json, ajoutez :
``json``
[
{"id":1, "email":"user@example.com", "ip":"192.168.1.1", "name":"Jean Dupont"},
{"id":2, "email":"test@privacy.fr", "ip":"10.0.0.1", "name":"Marie Curie"}
]
Toujours logger les PII trouvés pour audit.
Script de détection et hashing PII
import CryptoJS from 'crypto-js';
import fs from 'fs';
type User = { id: number; email: string; ip: string; name: string };
const users: User[] = JSON.parse(fs.readFileSync('./data/users.json', 'utf-8'));
const isPII = (value: string): boolean => {
const emailRegex = /[^@\s]+@[^@\s\.]+\.[^@\s\.]+/;
const ipRegex = /\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/;
return emailRegex.test(value) || ipRegex.test(value) || value.length > 3;
};
const pseudonymize = (value: string, salt: string = 'privacy-salt-2026'): string => {
return CryptoJS.SHA256(value + salt).toString();
};
const processUsers = () => {
const processed = users.map(user => {
const emailHash = isPII(user.email) ? pseudonymize(user.email) : user.email;
const ipHash = isPII(user.ip) ? pseudonymize(user.ip) : user.ip;
const nameHash = isPII(user.name) ? pseudonymize(user.name) : user.name;
return { ...user, email: emailHash, ip: ipHash, name: nameHash };
});
fs.writeFileSync('./data/users-pseudonymized.json', JSON.stringify(processed, null, 2));
console.log('PII pseudonymisés avec succès !');
};
processUsers();Ce script lit users.json, détecte PII via regex (email/IP/nom long), et applique SHA256 avec salt pour pseudonymisation (RGPD Article 4). Résultat écrit en users-pseudonymized.json. Piège : sans salt unique par env, risque de rainbow table attacks ; changez-le en prod.
Différence pseudonymisation vs anonymisation
- Pseudonymisation : Remplacer PII par hash réversible avec clé (ex: votre code ci-dessus). Utile pour analytics.
- Anonymisation : Irreversible, supprime tout lien (ex: remplacer email par 'user_123').
node -r ts-node/register src/pii-handler.ts → Vérifiez le JSON output, hashes ne révèlent rien sans salt.Implémenter l'anonymisation irréversible
import fs from 'fs';
import type { User } from './pii-handler';
const users: User[] = JSON.parse(fs.readFileSync('./data/users-pseudonymized.json', 'utf-8'));
const anonymize = (user: User): any => {
return {
userId: user.id,
email: `user_${user.id}@anon.com`, // Remplace par faux email
ip: '0.0.0.0', // IP neutre
name: `User_${user.id}`, // ID générique
timestamp: new Date().toISOString()
};
};
const anonymizedData = users.map(anonymize);
fs.writeFileSync('./data/users-anonymized.json', JSON.stringify(anonymizedData, null, 2));
console.log('Données anonymisées pour analytics !');Partant du JSON pseudonymisé, ce script remplace PII par placeholders génériques (ex: 'user_1@anon.com'). Idéal pour BigQuery ou logs publics. Piège : Ne pas oublier timestamp pour traçabilité sans PII ; testez avec ts-node src/anonymizer.ts.
Gestion du consentement utilisateur
class ConsentManager {
private consents: { [key: string]: boolean } = JSON.parse(localStorage.getItem('privacy-consents') || '{}');
requestConsent(type: 'analytics' | 'marketing' | 'cookies'): Promise<boolean> {
return new Promise((resolve) => {
if (this.consents[type] !== undefined) {
resolve(this.consents[type]);
return;
}
const banner = document.createElement('div');
banner.innerHTML = `
<div style="position:fixed;bottom:0;width:100%;background:#000;color:#fff;padding:20px;z-index:9999;">
Autoriser <strong>${type}</strong> ? <button id="accept-${type}">Oui</button> <button id="reject-${type}">Non</button>
</div>`;
document.body.appendChild(banner);
document.getElementById(`accept-${type}`)?.addEventListener('click', () => {
this.setConsent(type, true);
document.body.removeChild(banner);
resolve(true);
});
document.getElementById(`reject-${type}`)?.addEventListener('click', () => {
this.setConsent(type, false);
document.body.removeChild(banner);
resolve(false);
});
});
}
private setConsent(type: string, value: boolean): void {
this.consents[type] = value;
localStorage.setItem('privacy-consents', JSON.stringify(this.consents));
}
hasConsent(type: string): boolean {
return this.consents[type] === true;
}
}
// Usage exemple (à caller avant traitement)
const manager = new ConsentManager();
manager.requestConsent('analytics').then(hasConsent => {
if (hasConsent) {
console.log('Analytics OK, process data');
} else {
console.log('Pas de consent, skip');
}
});Cette classe gère le consentement granulaire (IAB TCF-like) avec localStorage et bannière HTML simple. Bloque le traitement sans OK. Piège : En SSR (Next.js), sync avec cookies serveur ; testez en ouvrant index.html avec ce script.
Intégrer dans un workflow complet
Workflow Privacy : 1. Consent → 2. Détecter PII → 3. Pseudonymiser → 4. Anonymiser si besoin.
Créez package.json scripts : "process":"ts-node src/pii-handler.ts && ts-node src/anonymizer.ts". Lancez npm run process. Résultat : données safe pour ML ou dashboards.
Configuration Privacy Policy en YAML
version: '1.0'
salt: 'unique-salt-change-in-prod-2026'
pii_fields:
- email
- ip
- name
- phone
consent_types:
analytics:
description: 'Pour Google Analytics'
required: false
marketing:
description: 'Newsletters'
required: true
anonymization_rules:
ip: '0.0.0.0'
email: 'user_{id}@anon.com'
retention_days:
logs: 30
pii: 365Ce YAML centralise config (salt, règles). Chargez-le avec js-yaml en prod pour dynamiser. Piège : Versionnez et chiffrez en Git ; intégrez via YAML.parse() dans vos scripts.
Package.json avec scripts workflow
{
"name": "privacy-engineer-demo",
"version": "1.0.0",
"scripts": {
"detect": "ts-node src/pii-handler.ts",
"anonymize": "ts-node src/anonymizer.ts",
"full-privacy": "npm run detect && npm run anonymize",
"consent-test": "ts-node src/consent-manager.ts"
},
"dependencies": {
"typescript": "^5.0.0",
"crypto-js": "^4.2.0",
"@types/node": "^20.0.0",
"ts-node": "^10.9.0",
"@types/crypto-js": "^4.2.0"
}
}Scripts prêts : npm run full-privacy chain tout. Ajoutez js-yaml pour YAML si besoin. Piège : Dépendances pinned pour CI/CD stable.
Bonnes pratiques
- Privacy by Design : Intégrez checks consent/PII dans CI/CD (ex: pre-commit hooks).
- Salt unique par env (dev/prod) et rotatez tous 90 jours.
- Auditez logs : jamais de PII en clair.
- Utilisez libs battle-tested (CryptoJS → WebCrypto en browser).
- Documentez DPIA (Data Protection Impact Assessment) pour >10k users.
Erreurs courantes à éviter
- Hasher sans salt : Attaques rainbow tables faciles.
- Consent non-granulaire : Un 'Tout accepter' viole RGPD.
- Oublier localStorage en mode privé/incognito : Fallback à cookies.
- Anonymiser partiellement : Un ID + hash = re-identification possible.
Pour aller plus loin
- Doc RGPD CNIL
- Libs avancées : Pino pour logs privacy, Differential Privacy avec Opacus (PyTorch)
- Formations : Découvrez nos formations Learni sur la sécurité
- Repo GitHub : Forkez ce demo et PR vos améliorations !