Skip to content

Rizzo PII Sidecar

rizzo-pii-0.3B è un modello di token-classification Italian-first, CPU-oriented con circa 0.3B parametri. Il modello upstream riporta 22 categorie PII, inclusi identificatori specifici italiani come codice fiscale, partita IVA, dati catastali, document ID e province.

Factum non invia il mapping PII all’LLM esterno. L’integrazione richiede include_mapping=true, trattiene il mapping nel processo della richiesta, e ripristina i placeholder localmente dopo l’estrazione semantica.

Il confine di privacy è nella sequenza: pseudonimizzazione prima della chiamata LLM, ripristino locale dopo.

raw document/text
┌──────────────────────────┐
│ Rizzo PII /analyze │
│ anonymized_text │
│ mapping = {placeholder: │
│ original} │
└────────────┬─────────────┘
│ solo pseudonimi
┌──────────────┐
│ External LLM │
└──────┬───────┘
│ output con placeholder
┌──────────────────────────┐
│ restore(obj, mapping) │
│ LOCALE / SINCRONO │
└────────────┬─────────────┘
│ dati reali
HTTP response → DROP mapping

Il modello upstream riporta 22 categorie. Quelle rappresentative per documenti amministrativi italiani includono:

# Categoria Descrizione Esempio
1 FULLNAME Nome e cognome completo Mario Rossi
2 GENDER Genere M, F
3 AGE Età 45
4 EMAIL Indirizzo email / PEC m.rossi@pec.it
5 TELEPHONENUM Numero di telefono +39 333 1234567
6 STREET Nome via / piazza Via Roma
7 BUILDINGNUM Numero civico 15/A
8 CITY Città / comune Milano
9 ZIPCODE CAP 20100
10 PROVINCE Provincia (sigla) MI
11 IBAN Codice IBAN IT60X0542811101000000123456
12 CREDITCARDNUMBER Numero carta di credito 4532 1234 5678 9012
13 AMOUNT Importo / valore monetario € 1.500,00
14 CF Codice Fiscale RSSMRA75M15F205X
15 PIVA Partita IVA 01234567890
16 CATASTO Dati catastali Fg. 12 Part. 345
17 DOCID Numero documento d’identità AB1234567
18 ID_DOC Tipo documento d’identità Carta d’Identità
19 ORG Organizzazione / azienda Mario Rossi S.r.l.
20 DATE Data (formato vario) 15/01/2026
21 TIME Ora 14:30:00
22 TARGA Targa veicolo AB123CD

Before:

Il Sig. Mario Rossi, C.F. RSSMRA85H12F205Z,
P.IVA 12345678901, IBAN IT60X0542811101000000123456,
risiede in Via Garibaldi 24, 20121 Milano.

After Rizzo (anonymized):

Il Sig. [FULLNAME_1], C.F. [CF_1],
P.IVA [PIVA_1], IBAN [IBAN_1],
risiede in [STREET_1] [BUILDINGNUM_1], [ZIPCODE_1] [CITY_1].

Restored (dopo LLM):

Il Sig. Mario Rossi, C.F. RSSMRA85H12F205Z,
P.IVA 12345678901, IBAN IT60X0542811101000000123456,
risiede in Via Garibaldi 24, 20121 Milano.
Before Anonymized Restored
Mario Rossi [FULLNAME_1] Mario Rossi
m.rossi@email.it [EMAIL_2] m.rossi@email.it
+39 333 1234567 [TELEPHONENUM_1] +39 333 1234567
Via Roma 15/A, Milano [STREET_1] [BUILDINGNUM_1], [CITY_1] Via Roma 15/A, Milano
IT60X0542811101000000123456 [IBAN_1] IT60X0542811101000000123456
RSSMRA75M15F205X [CF_1] RSSMRA75M15F205X
01234567890 [PIVA_1] 01234567890
€ 1.500,00 [AMOUNT_1] 1500.00 (numero)
AB1234567 [DOCID_1] AB1234567
Mario Rossi S.r.l. [ORG_1] Mario Rossi S.r.l.
15/01/2026 [DATE_1] 15/01/2026

Il backend NON chiama un endpoint /restore remoto.

L’implementazione in backend/app/services/rizio_pii.py esegue il ripristino localmente e sincronamente sulla risposta strutturata dell’LLM. Sostituisce ricorsivamente i placeholder in stringhe, dict e liste, poi restituisce l’oggetto ricostruito.

I placeholder monetari ([AMOUNT_N], [IMPORTO_N], [TOTALE_N]) vengono convertiti in numeri (formato italiano 1.500,00 → float). Il restore è JSON-aware: se l’LLM incapsula il placeholder tra virgolette, opera sulla struttura decodificata, non sulla stringa grezza.

Questo significa che il mapping non attraversa mai il confine del modello esterno.

Il backend imposta per default:

RIZZO_PII_REQUIRED=true

Quando attivo e Rizzo non è raggiungibile dopo i retry configurati (2 tentativi, backoff esponenziale 0.2s, 0.4s, timeout 5s):

Rizzo unavailable → NO LLM CALL → 503 Service Unavailable

Il backend supporta anche RIZZO_PII_REQUIRED=false (degrado). In quella modalità il testo in chiaro può essere inviato all’LLM e non è equivalente al percorso privacy-safe. La configurazione di deployment va verificata prima di affermare che il fail-closed è attivo in produzione.

Factum porta una patch runtime idempotente per il sidecar Rizzo che inserisce gc.collect() al punto controllato nel path /analyze e verifica la sintassi Python prima della sostituzione. Exit semantics:

0 = patch applicata
2 = patch già presente
1 = errore

Esposte dal backend (non dal sidecar) su /metrics:

Metrica Tipo Descrizione
rizzo_pii_entities_detected Counter Entità PII rilevate, per tag
rizzo_pii_pseudonymize_duration_seconds Histogram Latenza chiamata pseudonimizzazione
rizzo_pii_restore_duration_seconds Histogram Durata restore locale placeholder
rizzo_pii_calls_total Counter Chiamate al sidecar per esito (ok, sidecar_down, timeout, retry, error)
rizzo_pii_up Gauge Sidecar raggiungibile (1) o no (0)
rizzo_pii_timeout_total Counter Timeout verso il sidecar

Prova architetturalmente:

  • Il PII in chiaro è pseudonimizzato prima del path LLM esterno
  • Il mapping Factum è ripristinato localmente
  • Il percorso required-sidecar è fail-closed
  • L’integrazione ha metriche osservabili

Non prova da solo:

  • End-to-end zero retention per upload artifacts
  • Una certificazione GDPR legale
  • Politiche di retention specifiche del provider fuori dal confine Factum
  • Recall/precision PII a livello di documento in produzione
  • Che il sidecar sia attualmente deployato in produzione (l’inventario infrastrutturale del repository lo elenca come non ancora deployato)
  • Un ceiling di memoria universale — il limite di 1.5 GiB è una configurazione di deployment, non un vincolo architetturale dimostrato