GDPR per Sviluppatori Software | Cosa Devi Effettivamente Implementare
Una guida al GDPR focalizzata sugli sviluppatori. Copre i requisiti tecnici, i pattern di gestione dati e le decisioni a livello di codice che devi prendere.
Il GDPR e’ in vigore dal 2018, ma la maggior parte delle guide per sviluppatori si concentra ancora sulla teoria legale. Questa guida e’ diversa. Copre i requisiti tecnici, il codice che devi scrivere e le decisioni architetturali che rendono la conformita’ pratica invece che dolorosa.
Se il tuo software archivia, elabora o tocca dati personali di persone nell’UE, questo si applica a te. Non importa dove ha sede la tua azienda.
Panoramica GDPR per Sviluppatori
Salta i 99 articoli. Ecco cosa significa il GDPR per il tuo codebase:
- Raccogli solo cio’ che ti serve. Non archiviare dati “per sicurezza”.
- Informa gli utenti su cosa fai con i loro dati. E ottieni il loro permesso quando richiesto.
- Permetti agli utenti di accedere, esportare e cancellare i loro dati. Hai bisogno di endpoint API per questo.
- Mantieni i dati al sicuro. Crittografia, controlli di accesso, log di audit.
- Segnala le violazioni rapidamente. Hai 72 ore per notificare le autorita’ dopo aver scoperto una violazione.
- Documenta tutto. Le tue attivita’ di elaborazione, le tue misure di sicurezza, i tuoi flussi di dati.
Questo e’ il riassunto pratico. Il resto di questa guida ti mostra come implementare ogni requisito.
I 7 Requisiti Tecnici Chiave
1. Gestione del Consenso
Il consenso deve essere dato liberamente, specifico, informato e inequivocabile. Le caselle pre-selezionate non contano. Il consenso cumulativo (“accetta tutto”) non conta. La revoca deve essere facile quanto la concessione del consenso.
Cosa Costruire
Un sistema di consenso ha bisogno di tre componenti:
- Un archivio dei record di consenso. Per ogni utente, traccia a cosa ha acconsentito, quando e come.
- Un meccanismo di verifica del consenso. Prima di elaborare i dati per uno scopo specifico, verifica che l’utente abbia un consenso attivo.
- Un meccanismo di revoca. Permetti agli utenti di revocare il consenso attraverso la tua UI, e interrompi l’elaborazione immediatamente.
Schema Database
CREATE TABLE user_consents (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id),
consent_type VARCHAR(100) NOT NULL,
granted BOOLEAN NOT NULL,
granted_at TIMESTAMPTZ,
revoked_at TIMESTAMPTZ,
ip_address INET,
user_agent TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_user_consents_lookup
ON user_consents (user_id, consent_type, granted);
Archivia l’intera cronologia. Non eliminare o sovrascrivere mai i record di consenso. Quando un utente revoca il consenso, inserisci una nuova riga con granted = false e imposta revoked_at. Questo ti da’ una traccia di audit.
Middleware di Verifica del Consenso
Ecco un middleware Express che verifica il consenso prima di elaborare una richiesta:
import { Request, Response, NextFunction } from "express";
import { db } from "./database";
interface ConsentRequirement {
type: string;
required: boolean;
}
function requireConsent(consentType: string) {
return async (req: Request, res: Response, next: NextFunction) => {
const userId = req.user?.id;
if (!userId) {
return res.status(401).json({ error: "Authentication required" });
}
const consent = await db.query(
`SELECT granted FROM user_consents
WHERE user_id = $1 AND consent_type = $2
ORDER BY created_at DESC
LIMIT 1`,
[userId, consentType]
);
if (!consent.rows[0]?.granted) {
return res.status(403).json({
error: "Consent required",
consentType,
message: `You must grant "${consentType}" consent to use this feature.`,
consentUrl: `/settings/privacy`,
});
}
next();
};
}
// Usage
app.post(
"/api/newsletter/subscribe",
requireConsent("marketing_emails"),
subscribeHandler
);
app.post(
"/api/analytics/track",
requireConsent("usage_analytics"),
trackHandler
);
2. Accesso e Esportazione Dati (Diritto di Accesso)
Gli utenti hanno il diritto di richiedere una copia di tutti i dati personali che detieni su di loro. Devi fornirla in un formato comunemente usato e leggibile da macchina. JSON o CSV vanno bene.
Cosa Costruire
Un endpoint che raccoglie tutti i dati personali di un utente da ogni tabella e servizio, poi li impacchetta in un file scaricabile.
interface DataExport {
exportedAt: string;
user: {
profile: Record<string, unknown>;
activity: Record<string, unknown>[];
consents: Record<string, unknown>[];
communications: Record<string, unknown>[];
};
}
app.get("/api/me/data-export", authenticate, async (req, res) => {
const userId = req.user.id;
const [profile, activity, consents, communications] = await Promise.all([
db.query("SELECT id, email, name, created_at FROM users WHERE id = $1", [
userId,
]),
db.query(
"SELECT action, metadata, created_at FROM user_activity WHERE user_id = $1 ORDER BY created_at DESC",
[userId]
),
db.query(
"SELECT consent_type, granted, granted_at, revoked_at FROM user_consents WHERE user_id = $1 ORDER BY created_at DESC",
[userId]
),
db.query(
"SELECT type, sent_at, subject FROM communications WHERE user_id = $1 ORDER BY sent_at DESC",
[userId]
),
]);
const exportData: DataExport = {
exportedAt: new Date().toISOString(),
user: {
profile: profile.rows[0],
activity: activity.rows,
consents: consents.rows,
communications: communications.rows,
},
};
res.setHeader("Content-Type", "application/json");
res.setHeader(
"Content-Disposition",
`attachment; filename="data-export-${userId}.json"`
);
res.json(exportData);
});
Questo endpoint deve coprire ogni tabella che contiene dati utente. Verifica il tuo schema in modo approfondito. Una tabella mancante significa un’esportazione incompleta, che e’ una violazione della conformita’.
3. Diritto alla Cancellazione (Diritto all’Oblio)
Gli utenti possono richiedere che tu cancelli tutti i loro dati personali. Devi conformarti a meno che tu non abbia un obbligo legale di conservarli (come registri fiscali o prevenzione frodi).
Cosa Costruire
Un endpoint di cancellazione che rimuove o anonimizza i dati utente su tutte le tabelle. Questo e’ piu’ difficile di quanto sembri a causa dei vincoli di chiave esterna e dei dati da cui dipendono altri sistemi.
app.delete("/api/me/account", authenticate, async (req, res) => {
const userId = req.user.id;
const client = await db.getClient();
try {
await client.query("BEGIN");
// Anonimizza i dati che devono essere conservati per i registri aziendali
await client.query(
`UPDATE orders
SET customer_name = 'deleted', customer_email = 'deleted'
WHERE user_id = $1`,
[userId]
);
// Cancella i dati che possono essere completamente rimossi
await client.query("DELETE FROM user_activity WHERE user_id = $1", [
userId,
]);
await client.query("DELETE FROM user_consents WHERE user_id = $1", [
userId,
]);
await client.query("DELETE FROM communications WHERE user_id = $1", [
userId,
]);
await client.query("DELETE FROM sessions WHERE user_id = $1", [userId]);
// Anonimizza il record utente invece di eliminarlo
// Questo preserva l'integrita' referenziale
await client.query(
`UPDATE users SET
email = 'deleted-' || id || '@removed.invalid',
name = 'Deleted User',
phone = NULL,
address = NULL,
deleted_at = NOW()
WHERE id = $1`,
[userId]
);
await client.query("COMMIT");
// Attiva la cancellazione nei sistemi esterni
await Promise.allSettled([
emailService.deleteSubscriber(userId),
analyticsService.deleteUser(userId),
searchIndex.removeUser(userId),
]);
res.json({ message: "Account and personal data deleted" });
} catch (error) {
await client.query("ROLLBACK");
throw error;
} finally {
client.release();
}
});
Decisioni chiave:
- Cancellare vs. anonimizzare. I record necessari per la contabilita’ (ordini, fatture) dovrebbero essere anonimizzati. Cancella tutto il resto.
- Sistemi esterni. I dati inviati a servizi di terze parti devono essere cancellati anche li’.
- Tempistica. Il GDPR dice “senza ingiustificato ritardo”. Completa la cancellazione entro 30 giorni. Per la maggior parte dei sistemi, rendila immediata.
4. Minimizzazione dei Dati
Raccogli e archivia solo i dati di cui hai effettivamente bisogno per uno scopo dichiarato. Se chiedi un numero di telefono ma non chiami mai gli utenti, non dovresti raccoglierlo.
Regole Pratiche
- Verifica ogni campo del form. Per ogni campo, chiedi: “Quale funzionalita’ specifica si rompe se rimuoviamo questo?” Se la risposta e’ nessuna, rimuovilo.
- Imposta periodi di conservazione. Non conservare i dati per sempre. Definisci per quanto tempo serve ogni tipo di dato, poi cancellalo automaticamente.
- Minimizza il logging. Rimuovi i dati personali dalle voci di log. Registra gli ID utente, non nomi o email.
-- Conservazione automatica dei dati con PostgreSQL
-- Esegui come job pianificato (es. pg_cron)
DELETE FROM user_activity
WHERE created_at < NOW() - INTERVAL '2 years';
DELETE FROM session_logs
WHERE created_at < NOW() - INTERVAL '90 days';
DELETE FROM password_reset_tokens
WHERE created_at < NOW() - INTERVAL '24 hours';
5. Crittografia
Il GDPR richiede “misure tecniche appropriate” per proteggere i dati personali. La crittografia e’ la piu’ importante.
A Riposo
- Crittografa il disco del tuo database. Tutti i principali cloud provider lo supportano. Abilitalo e verifica.
- Per campi altamente sensibili (codici fiscali, dati sanitari), aggiungi crittografia a livello applicativo in aggiunta.
- Crittografa i backup. Un backup non crittografato e’ una violazione in attesa di accadere.
In Transito
- TLS ovunque. Ogni connessione tra servizi, database e utenti. Nessuna eccezione.
- Imponi HTTPS. Reindirizza HTTP. Imposta gli header HSTS.
- Usa TLS per le connessioni al database. PostgreSQL lo supporta nativamente.
// Connessione PostgreSQL con TLS
import { Pool } from "pg";
const pool = new Pool({
host: process.env.DB_HOST,
port: 5432,
database: process.env.DB_NAME,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
ssl: {
rejectUnauthorized: true,
ca: fs.readFileSync("/path/to/server-ca.pem").toString(),
},
});
6. Notifica di Violazione
Se i dati personali vengono compromessi, devi notificare la relativa Autorita’ di Protezione dei Dati entro 72 ore. Se la violazione presenta un rischio elevato per gli individui, devi anche notificare gli utenti interessati.
Cosa Costruire
- Logging di audit. Traccia ogni accesso ai dati personali. Chi ha avuto accesso, quando e da dove.
- Rilevamento anomalie. Avvisa su pattern di accesso insoliti (esportazioni massive di dati, accesso da IP nuovi, accesso fuori dall’orario lavorativo).
- Un piano di risposta agli incidenti. Documenta chi fa cosa quando viene rilevata una violazione. Questo non e’ codice. E’ una checklist che il tuo team pratica.
CREATE TABLE data_access_log (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL,
accessed_by UUID NOT NULL,
access_type VARCHAR(50) NOT NULL,
resource_type VARCHAR(100) NOT NULL,
resource_id UUID,
ip_address INET,
user_agent TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_data_access_log_user
ON data_access_log (user_id, created_at);
CREATE INDEX idx_data_access_log_accessor
ON data_access_log (accessed_by, created_at);
7. Privacy by Design
Il GDPR dice che la privacy dovrebbe essere integrata nei sistemi fin dall’inizio, non aggiunta dopo. In pratica, questo significa rendere la privacy l’impostazione predefinita.
- Predefinito su privato. Le nuove funzionalita’ dovrebbero raccogliere dati minimi e richiedere l’opt-in per qualsiasi cosa oltre la funzione principale.
- Le impostazioni predefinite sull’opzione piu’ privata. Gli utenti che non toccano mai le loro impostazioni dovrebbero avere la massima protezione della privacy.
- Separa le responsabilita’. Non mescolare dati di analytics con dati funzionali. Non riutilizzare i token di autenticazione per il tracking.
Anonimizzazione vs. Pseudonimizzazione
Non sono la stessa cosa, e la distinzione conta.
- Pseudonimizzazione sostituisce le informazioni identificative con un token reversibile. Esempio: hashing degli indirizzi email. Se hai la funzione hash e l’email originale, puoi re-identificare la persona. Il GDPR si applica ancora perche’ la re-identificazione e’ possibile.
- Anonimizzazione rimuove le informazioni identificative in modo permanente. Esempio: analytics aggregate (“1.247 utenti hanno visitato la pagina prezzi”) senza modo di identificare quali utenti. Il GDPR non si applica ai dati veramente anonimizzati.
La vera anonimizzazione e’ difficile. Se il tuo dataset “anonimo” include un timestamp, una citta’ e un tipo di dispositivo, quella combinazione potrebbe identificare univocamente qualcuno. Sii conservativo.
Consenso ai Cookie
Se il tuo sito web usa cookie oltre a quelli strettamente necessari, hai bisogno del consenso prima di impostarli.
Richiede consenso: cookie di analytics, pixel pubblicitari, widget social media, qualsiasi script di tracking di terze parti.
Non richiede consenso: cookie di sessione, cookie del carrello, token CSRF, il cookie stesso delle preferenze sui cookie.
Il tuo banner di consenso dovrebbe bloccare i cookie non essenziali fino a quando il consenso viene dato, offrire scelte granulari e rendere “rifiuta tutto” facile quanto “accetta tutto”. Non costruire questo da zero. Strumenti come Cookiebot gestiscono la complessita’. La regola chiave: nessuno script di tracking si attiva prima che il consenso sia concesso.
Responsabili del Trattamento di Terze Parti
Ogni servizio di terze parti che gestisce i dati dei tuoi utenti e’ un “responsabile del trattamento” secondo il GDPR. Tu sei responsabile della loro conformita’.
Cosa Verificare
Prima di integrare qualsiasi servizio di terze parti che tocca dati personali:
- Hanno un DPA? Un Accordo di Trattamento Dati e’ obbligatorio. La maggior parte dei provider SaaS pubblica il proprio pubblicamente.
- Dove archiviano i dati? Se fuori dall’UE, verifica la base giuridica per il trasferimento.
- A quali dati accedono? Minimizza cio’ che invii. Se il servizio ha bisogno solo di un’email, non inviare il profilo completo.
- Puoi cancellare i dati dai loro sistemi? Le richieste di cancellazione degli utenti devono propagarsi ovunque.
- Come gestiscono le violazioni? Il loro DPA dovrebbe specificare le tempistiche di notifica.
Responsabili del Trattamento Comuni da Verificare
- Servizi email (Resend, SendGrid, Mailchimp)
- Analytics (Google Analytics, Mixpanel, Amplitude)
- Tracciamento errori (Sentry, Bugsnag)
- Elaborazione pagamenti (Stripe, Adyen)
- Cloud hosting (AWS, Google Cloud, Vercel)
- Strumenti di assistenza clienti (Intercom, Zendesk)
- API AI (OpenAI, Anthropic, Google AI)
Mantieni una lista di tutti i responsabili. Rivisitala trimestralmente.
Politiche di Conservazione Dati
Non conservare i dati personali piu’ a lungo del necessario. Definisci periodi di conservazione per ogni tipo di dato.
| Tipo di Dato | Conservazione Suggerita | Motivo |
|---|---|---|
| Dati account utente | Fino alla richiesta di cancellazione | Necessari per il servizio |
| Log di sessione | 90 giorni | Sicurezza e debug |
| Log di attivita’ utente | 1-2 anni | Analytics del prodotto |
| Ticket di supporto | 3 anni | Qualita’ del servizio |
| Record finanziari | 7 anni | Obblighi fiscali/legali |
| Token di reset password | 24 ore | Sicurezza |
| Tentativi di login falliti | 90 giorni | Monitoraggio sicurezza |
Implementa job di pulizia automatizzati. Non affidarti a qualcuno che si ricorda di eseguire uno script.
Checklist GDPR per Sviluppatori
Usa questa come punto di partenza quando costruisci o verifichi un sistema.
Raccolta Dati
- Ogni campo del form ha uno scopo dichiarato
- Nessun dato non necessario viene raccolto
- L’informativa sulla privacy e’ collegata da ogni punto di raccolta dati
- Il consenso viene raccolto prima dell’elaborazione (dove richiesto)
- I record di consenso sono archiviati con timestamp
Archiviazione Dati
- La crittografia a riposo del database e’ abilitata
- Il TLS e’ imposto per tutte le connessioni
- I campi sensibili hanno crittografia a livello applicativo
- I backup sono crittografati
- L’accesso ai dati di produzione e’ limitato e registrato
Diritti degli Utenti
- L’endpoint di esportazione dati esiste e copre tutte le tabelle
- L’endpoint di cancellazione account esiste e gestisce tutti i dati
- Gli utenti possono visualizzare e revocare il consenso nelle impostazioni
- La cancellazione si propaga ai servizi di terze parti
- Tutte le richieste sui diritti degli utenti ricevono risposta entro 30 giorni
Cookie e Tracking
- Il banner di consenso cookie e’ implementato
- I cookie non essenziali sono bloccati prima del consenso
- Le scelte di consenso sono granulari (non tutto-o-niente)
- “Rifiuta tutto” e’ prominente quanto “Accetta tutto”
Terze Parti
- Tutti i responsabili del trattamento sono documentati
- I DPA sono firmati con ogni responsabile
- I dati inviati a terze parti sono minimizzati
- La cancellazione dei dati dalle terze parti e’ possibile
Sicurezza
- I log di audit tracciano l’accesso ai dati personali
- L’alerting sulle anomalie e’ configurato
- Il piano di risposta agli incidenti e’ documentato
- Il processo di notifica violazione e’ definito (scadenza 72 ore)
Conservazione
- I periodi di conservazione sono definiti per tutti i tipi di dato
- I job di pulizia automatizzati sono pianificati
- I dati scaduti vengono effettivamente cancellati (verifica questo)
Considerazioni Finali
La conformita’ GDPR non e’ un progetto una tantum. E’ un insieme di pratiche integrate nel modo in cui costruisci software. Il lavoro tecnico e’ semplice: archiviazione del consenso, esportazione dati, endpoint di cancellazione, crittografia, logging di audit. Ingegneria standard.
La parte difficile e’ essere meticolosi. E’ facile dimenticare quel file di log, quell’evento di analytics o quell’integrazione di terze parti che archivia le email degli utenti. Verifica regolarmente. Testa il tuo endpoint di cancellazione. Verifica che le tue esportazioni siano complete. Integra la privacy nel tuo processo fin dall’inizio.
Hai bisogno di aiuto per costruire software conforme al GDPR o verificare i tuoi sistemi esistenti? Contattaci. Costruiamo applicazioni privacy-first per aziende europee e societa’ che servono utenti UE.