Problema: registres del servidor contenen PII
Logs del servidor típics contenen:
- Direccions IP: 192.168.1.100, 2001:db8::1
- ID de sessió: UUID, JWT tokens, cookies
- Paràmetres de demanda: email, números de compte, noms
- Capçaleres HTTP: User-Agent, Authorization, X-Forwarded-For
- Respostes d'API: JSON amb dades de usuari
Problema GDPR: Si un operador de servidors pot accedir als logs, pot veure les adreços IP, IDs de sessió, emails dels usuaris — violació d'Article 32 (mesures de seguretat).
Arquitectura de 3 capes de anonimització de logs
Capa 1: Anonimització en el origen (aplicació)
- Aplicació anonimitza dades sensibles als logs antes d'escriure
- Exemple:
user_id = hash(user_id),ip = hash(ip),email = <redacted>
Capa 2: Anonimització en transit (recopilador de logs)
- Recopilador de logs (Filebeat, Logstash, Fluentd) anonimitza logs entre servidor i sistema central
- Exemple: regex per redactar adreces emails, números de compte
Capa 3: Anonimització en repòs (central de logs)
- Sistema central (Elasticsearch, Splunk, CloudWatch) anonimitza logs al emmagatzemament
- Exemple: eliminar logs més vells de 30 dies (retenció)
Implementació pràctica: Anonimització de logs JSON
Exemple de log original en JSON:
{
"timestamp": "2025-01-15T10:30:45Z",
"level": "INFO",
"service": "api-gateway",
"user_id": "12345",
"user_email": "john.smith@company.com",
"ip_address": "192.168.1.100",
"http_method": "POST",
"http_path": "/api/users/12345",
"http_status": 200,
"request_body": {"email": "john.smith@company.com", "account_number": "ACC-98765"},
"response_time_ms": 250
}
Capa 1: Anonimització en origen (Node.js):
const crypto = require('crypto');
function hashPII(value) {
return crypto.createHash('sha256').update(value).digest('hex').substring(0, 12);
}
function anonymizeLog(logEntry) {
return {
timestamp: logEntry.timestamp,
level: logEntry.level,
service: logEntry.service,
user_id: hashPII(logEntry.user_id),
user_email: '<REDACTED>',
ip_address: '<IP>',
http_method: logEntry.http_method,
http_path: logEntry.http_path.replace(/\/\d+/, '/:id'), // /api/users/12345 -> /api/users/:id
http_status: logEntry.http_status,
request_body: '<REDACTED>', // no loguejis request body que conté PII
response_time_ms: logEntry.response_time_ms
};
}
const anonLog = anonymizeLog(logEntry);
console.log(JSON.stringify(anonLog));
Resultat anonimitzat:
{
"timestamp": "2025-01-15T10:30:45Z",
"level": "INFO",
"service": "api-gateway",
"user_id": "a3b2c1d4e5f6",
"user_email": "<REDACTED>",
"ip_address": "<IP>",
"http_method": "POST",
"http_path": "/api/users/:id",
"http_status": 200,
"request_body": "<REDACTED>",
"response_time_ms": 250
}
Capa 2: Anonimització en transit (Logstash)
filter {
# Redactar adreces email
mutate {
gsub => [ "message", "([\w\.-]+@[\w\.-]+\.\w+)", "<EMAIL>" ]
}
# Redactar adreces IP (except loopback)
mutate {
gsub => [ "message", "(?<!127\.)\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", "<IP>" ]
}
# Redactar números de compte (format ACC-XXXXX)
mutate {
gsub => [ "message", "ACC-\d{5}", "<ACCOUNT>" ]
}
# Eliminar query parameters que podrien contenir PII
if [http_query] {
mutate {
replace => { "http_query" => "<REDACTED>" }
}
}
}
Capa 3: Anonimització en repòs (Elasticsearch + Retenció)
// Política de retenció Elasticsearch
{
"policy": "gdpr-log-retention",
"phases": {
"hot": {
"min_age": "0d",
"actions": {
"set_priority": {
"priority": 100
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"set_priority": {
"priority": 50
}
}
},
"delete": {
"min_age": "30d",
"actions": {
"delete": {}
}
}
}
}
Validació de conformitat GDPR
Checklist per a logs anonimitzatos:
- Sense adreces IP: Cercar pattern
\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}— s'espera 0 coincidències (excepte 127.0.0.1) - Sense emails: Cercar pattern
[\w\.-]+@[\w\.-]+\.\w+— s'espera 0 coincidències - Sense números de compte: Cercar pattern
ACC-\d{5}— s'espera 0 coincidències - Sense user IDs de text pla: Cercar paterns de user ID originals (p. ex. noms, emails) — s'espera 0 coincidències
- Sense paràmetres de consulta: Cercar URLs amb query strings que continguin paràmetres — s'espera 0 coincidències
- Retenció limitada: Verificar que els logs més vells de 30 dies es eliminen automàticament
- Accés restringit: Verificar que els operadors requereixen autenticació MFA per accedir a logs, i els accessos estan auditados
Fonts: