Implementazione Avanzata del Data Masking Dinamico in PostgreSQL: Il Livello Tier 2 per la Protezione Granulare dei Dati Sensibili in Ambiente Italiano

Il Data Masking Dinamico rappresenta la frontiera più avanzata nella protezione dei dati personali e sensibili, soprattutto in contesti regolamentati come quelli descritti dal Codice Privacy italiano (D.Lgs. 101/2018) e dalla normativa GDPR. Nel Tier 2, il focus si sposta da semplici maschere statiche a soluzioni basate su policy contestuali, ruoli e dinamismo in tempo reale, garantendo conformità senza compromettere l’accessibilità operativa e l’efficienza del database PostgreSQL. Questa guida dettagliata esplora con metodologie esperte le fasi critiche dell’implementazione, dal data landscape mapping alla gestione dinamica delle regole, con esempi pratici e best practice per un’adozione sicura e scalabile nel contesto italiano.


1. Il Contesto Regolatorio e la Necessità del Tier 2: Protezione Dinamica Contesto-Dipendente

La protezione dei dati sensibili non può limitarsi a soluzioni statiche, che alterano fisicamente il data source e creano rischi di esposizione durante operazioni di backup, sviluppo o test. Il Tier 2 del Data Masking Dinamico risponde a questa esigenza introducendo maschere applicate in fase di query, senza modificare i dati originali, rispettando rigorosamente i principi di minimizzazione e sicurezza previsti dal Codice Privacy italiano. Questo livello è essenziale per ambienti multi-utente – come sistemi sanitari regionali, piattaforme finanziarie o portali pubblici – dove ruoli, accessi e contesti operativi variano continuamente. La normativa richiede non solo la confidenzialità, ma anche la coerenza funzionale dei dati, evitando che la mascheratura interrompa processi critici.

**Esempio pratico:** In una rete ospedaliera regionale, i dati del paziente CED devono essere visibili solo a medici autorizzati con ruolo specifico; mascherare tutto indiscriminatamente rallenterebbe diagnosi e trattamenti, mentre il Tier 2 applica maschere diverse in base al ruolo utente, preservando la leggibilità per chi è autorizzato.


2. Fondamenti Tecniche: Architettura PostgreSQL e Integrazione con Policy Dinamiche

PostgreSQL supporta nativamente meccanismi avanzati per il Data Masking attraverso estensioni e policy di sicurezza, ma il Tier 2 richiede un’architettura integrata che combini:
– **Row-Level Security (RLS)** per limitare l’accesso ai dati in base al ruolo e contesto utente
– **Dynamic Masking con funzioni personalizzate** per trasformare i dati solo in fase di lettura
– **Metadati strutturati** per mappare colonne sensibili e policy di mascheratura

L’estensione `pg_masking` (opzionale) o funzioni PL/pgSQL come `mask()` possono implementare regole basate su ruoli, ma per la massima granularità si preferisce definire policy RLS con condizioni complesse e funzioni native ottimizzate.

**Differenze chiave tra static e dinamico:**
| Aspetto | Static Masking | Dynamic Masking (Tier 2) |
|————————|—————————————|————————————————–|
| Modifica dati | Fisica, permanente | Solo in query, non altera storage |
| Performance | Overhead al write/init | Overhead in query, ottimizzabile con indici |
| Contesto applicato | Unico, globale | Contestuale, basato su ruoli, ruoli, orario |
| Conformità normativa | Parziale, rischio leakage | Completa, adattabile a GDPR, Codice Privacy |


3. Fasi Operative del Tier 2: Dalla Classificazione alla Validazione

Fase 1: Data Landscape Mapping e Classificazione Sensibile

Prima di definire regole, occorre mappare il data source con strumenti come OpenMetadata o pg_partman, identificando colonne contenenti dati personali: codice fiscale, codice CED, email, dati sanitari (es. diagnosi, terapie).
**Esempio pratico:**

SELECT column, data_type, is_sensitive
FROM information_schema.columns
WHERE data_type IN (‘char’, ‘varchar’, ‘text’)
AND (lower(data_type) LIKE ‘%personal%’ OR lower(data_type) LIKE ‘%codice%’);

Classificare i dati in livelli L1 (parziale, es. mascheratura parziale di email) e L2 (totale, es. sostituzione con valori fittizi non reversibili).
**Raccomandazione italiana:** adottare il modello di rischio definito dall’AGID, con valutazione del dato sensibile come “alto” per salute, dati finanziari, identità.

Fase 2: Progettazione Policy Dinamiche con RLS e Funzioni PL/pgSQL

**2.1 Policy RLS per Contesto Utente**
Definire policy che applicano maschere solo agli utenti autorizzati, con condizioni temporali o ruoli.
Esempio: mascherare l’indirizzo email a meno che non sia amministratore;

CREATE POLICY mask_email_role ON utenti
WITH (check = false)
USING (user_role = ‘medico’ THEN mask(email, ‘mask@region.it’)
WHEN user_role = ‘admin’ THEN email
ELSE email || ‘_masked’);

**2.2 Mascheratura Contestuale con Funzioni Critiche**
Implementare funzioni come `mask_date_range()` per dati temporali, garantendo coerenza e sicurezza:

CREATE OR REPLACE FUNCTION mask_date_range(start::date, end::date) RETURNS text AS $$
BEGIN
RETURN format(‘%04d-%02d-%02d’, (start + interval ‘1 day’) – interval ‘1 day’);
END; $$ LANGUAGE plpgsql;

Utilizzabile così:

SELECT mask_date_range(NOW() – INTERVAL ‘7 days’, NOW()) AS email_masked FROM utenti;

**2.3 Integrazione con RLS e Row-Level Security**

CREATE POLICY refresh_email_mask ON utenti
WITH (check = false)
USING (user_role = ‘medico’ THEN mask_email_role(email, current_user_role())
WHEN user_role = ‘admin’ THEN email
ELSE email || ‘_masked’);

Triggers assicurano aggiornamenti in tempo reale:

CREATE OR REPLACE FUNCTION refresh_mask() RETURNS trigger AS $$
BEGIN
NEW.email := mask_email_role(NEW.email, current_user_role());
RETURN NEW;
END; $$ LANGUAGE plpgsql;
CREATE TRIGGER trg_refresh_mask BEFORE INSERT ON utenti FOR EACH ROW EXECUTE PROCEDURE refresh_mask();

Fase 3: Test, Audit e Ciclo di Vita delle Maschere

**3.1 Validazione e Test di Conformità**
Creare un dataset di prova con dati sensibili mascherati: verificare che email siano irriconoscibili ma mantengano formato valido, dati sanitari non distorti.
**Tabella comparativa esempio:**
| Dato Originale | Mascherato | Validità | Coerenza |
|—————-|————|———-|———-|
| nome: “Luca Rossi” | “L____ Rossi” | ✅ | ✅ |
| codice_fiscale: “12345678901” | “***0123456789” | ✅ | ✅ |
| data_salute: “2023-05-14” | “2023-04-14” | ✅ | ✅ |

**3.2 Performance Testing con Query Complesse**
Maschere colonne in join con tabelle correlate; misurare latenza con `EXPLAIN ANALYZE` per rilevare colli di bottiglia.
**Esempio:**

EXPLAIN ANALYZE SELECT u.nome, m.email FROM utenti u JOIN masked_email m ON u.id = m.user_id;

Ottimizzare con indici su colonne `user_id` e `email_masked`, e valutare l’uso di materialized views se query ripetitive.

**3.3 Audit di Conformità**
Utilizzare strumenti come Aqua Security o OpenSCAP per verificare che le maschere rispettino GDPR e Codice Privacy, con report dettagliati su:
– Policy applicate per ogni tipo dato
– Utenti autorizzati
– Periodo di revisione delle maschere

**3.4 Ciclo di Vita e Governance**
Gestire politiche con revisione trimestrale, documentando ogni modifica.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top