Skip to content

Runbook: chiavi di mask (creazione, rotazione, compromissione) ​

Le chiavi HMAC con cui la transform mask pseudonimizza le colonne.

Chi lo esegue. Chi amministra l'ambiente dell'installazione (.env o il gestore di segreti). La chiave non passa mai da chat, ticket, mail o repository.

Creare una chiave ​

  1. Genera 32 byte casuali in base64:

    bash
    openssl rand -base64 32

    Deve essere casuale: mai una passphrase o una parola codificata in base64. Una chiave fatta di byte ripetuti viene rifiutata, ma il controllo ferma solo gli errori grossolani.

  2. Scegli un id: minuscole, cifre, underscore singoli in mezzo (crm, crm_2027). L'id finisce dentro ogni pseudonimo (v1:<id>:<hex>), quindi non si rinomina dopo il primo caricamento.

  3. Configura l'ambiente:

    bash
    MASK_KEY_INSTANCES=crm
    MASK_KEY_CRM_SECRET=<il valore generato>

    Con una sola chiave basta MASK_KEY_SECRET, che vale come id default.

  4. Avvia la pipeline. Una chiave assente, non base64 o più corta di 32 byte ferma la run subito, con un ConfigError che nomina la variabile e mai il valore.

Stessa chiave in tutti gli ambienti che devono fare join fra loro, chiavi diverse dove i dataset non devono essere collegabili (produzione e demo, per esempio).

Ruotare una chiave ​

Ruotare cambia tutti gli pseudonimi: i dati caricati con la chiave vecchia non fanno più join con quelli nuovi. Va deciso, non fatto di passaggio.

  1. Crea la chiave nuova con un id nuovo (crm_2027) e aggiungila alla lista, senza togliere la vecchia: MASK_KEY_INSTANCES=crm,crm_2027. Se la chiave attuale è MASK_KEY_SECRET, senza lista, il suo id è default e i suoi pseudonimi iniziano per v1:default:: la lista diventa MASK_KEY_INSTANCES=default,crm_2027, e MASK_KEY_SECRET resta dov'è. Il segreto deve essere nuovo: due id con lo stesso valore fermano la run con un ConfigError.
  2. Cambia la costante dell'id nella pipeline e rilascia.
  3. Decidi cosa fare dei dati già caricati, che si riconoscono dal prefisso v1:crm::
    • ricaricarli dalla sorgente con la chiave nuova, se la sorgente li ha ancora;
    • oppure lasciarli, sapendo che i join fra i due periodi non funzionano.
  4. Quando nessuna pipeline usa più l'id vecchio e i dati vecchi sono stati ricaricati o scaduti, togli la chiave vecchia dall'ambiente.

Se una chiave è compromessa ​

Chi ha la chiave può ricalcolare lo pseudonimo di un valore noto, e su domini piccoli invertirlo per enumerazione: i dati pseudonimizzati con quella chiave vanno trattati come dati in chiaro.

  1. Ruota subito (sezione sopra) e togli la chiave vecchia dall'ambiente appena possibile.
  2. Ricarica o cancella i dati con il prefisso della chiave compromessa, a ogni destinazione.
  3. Segnala l'accaduto al responsabile della protezione dei dati: può essere una violazione da notificare (GDPR art. 33).

Cosa controllare se qualcosa non torna ​

SintomoCausa
MASK_KEY_…_SECRET non è impostatavariabile assente, o id nella lista senza la sua variabile
… non è base64 validovalore troncato, con virgolette dentro, o in base64url
Istanza "x" non configurata per il connettore mask-keyl'id della pipeline non è in MASK_KEY_INSTANCES
MaskKey "x" è il segnaposto di getSpec()run() passa maskKeyForSpec invece di loadMaskKeyRegistry().get
MASK_KEY_SECRET non è impostata, ma MASK_KEY_CRM_SECRET c'èmanca MASK_KEY_INSTANCES=crm: senza la lista si legge solo la chiave default
… id di chiave non validoun id con maiuscole, trattini o spazi nella lista o nella pipeline (l'errore non lo cita, di proposito)
… e … hanno lo stesso valoredue id con lo stesso segreto: genera una chiave nuova per l'id nuovo
… non è casuale (byte ripetuti)zeri o una parola ripetuta al posto di una chiave generata
Una colonna arriva in chiaro a destinazionenome sbagliato in columns (refuso, maiuscole): usa onAbsent: "error"
Join fra due tabelle che non trova nienteprefissi v1:<id>: diversi, oppure tipi diversi (1 e "1")

Noeva è un marchio registrato di 4D S.R.L.