Sign inSign up

mariomastrorilli/pii_scrubber

By mariomastrorilli

Updated 7 months ago

Pseudonimizzazione e ripristino controllato di dati personali (PII), basato su Microsoft Presidio

Image
Security
Machine learning & AI
0

10K+

mariomastrorilli/pii_scrubber repository overview

PII Scrubber Microservice

Microservizio FastAPI per pseudonimizzazione e ripristino controllato di dati personali (PII), basato su Microsoft Presidio + vault PostgreSQL.

Obiettivo

Il servizio riduce il rischio privacy quando un applicativo deve inviare testo a componenti esterni (es. LLM, servizi di classificazione, canali terzi), sostituendo i dati personali con token e consentendo il ripristino solo in ambiente controllato.

Valore per compliance GDPR

Questo microservizio supporta un approccio privacy-by-design e privacy-by-default:

  • Minimizzazione dei dati (art. 5(1)(c)): verso sistemi esterni transitano token, non valori personali in chiaro.
  • Integrita e riservatezza (art. 5(1)(f), art. 32): separazione tra testo tokenizzato e vault di mapping.
  • Protezione dei dati fin dalla progettazione (art. 25): pseudonimizzazione integrata nel flusso applicativo.
  • Riduzione superficie esposta: il restore avviene solo all'interno dell'infrastruttura fidata.

Nota importante: questa soluzione implementa pseudonimizzazione, non anonimizzazione irreversibile. I dati restano dati personali ai sensi GDPR se il mapping e la chiave sono disponibili. Per compliance totale è fondamentale garantire la cifratura del volume di PostgreSQL e limitare gli accessi esclusivamente midiante utenza applicativa.

Funzionalita principali

  • Endpoint POST /anonymize
    • cifra in modo reversibile il conversation_id
    • tokenizza PII nel testo (PERSON, PHONE*, EMAIL*, ecc.)
    • supporta testo libero e JSON strutturato
  • Endpoint POST /restore
    • ripristina il testo originale a partire dai token
    • ripristina anche il conversation_id originale
  • Supporto JSON avanzato
    • masking di valori su chiavi note (full_name, name, phone, email)
    • masking delle chiavi dei dizionari annidati (es. nomi in children)
    • parsing robusto con fallback:
      1. JSON standard (json.loads)
      2. Python literal (ast.literal_eval) per payload con apici singoli
      3. fallback NLP plain text
  • Normalizzazione restore
    • PERSON: restituzione normalizzata in base alle componenti del token
    • PHONE*: restituzione normalizzata (E.164 o forma normalizzata disponibile)

Architettura (alto livello)

  1. Input applicativo -> /anonymize
  2. conversation_id -> cifrato con chiave segreta (SCRUBBER_CRYPTO_KEY)
  3. Presidio identifica le entity
  4. Vault PostgreSQL salva mapping token <-> valore per conversazione
  5. Output tokenizzato verso sistemi esterni
  6. /restore usa token + masked_conversation_id per ripristinare valori e conversation id

API

POST /anonymize

Request:

{
  "conversation_id": "chat-123",
  "raw_text": "Buongiorno, sono Mario Rossi. Chiamami al +39 333 123 4567"
}

Response (esempio):

{
  "masked_conversation_id": "<encrypted-id>",
  "masked_text": "Buongiorno, sono <PERSON_1:first_name last_name>. Chiamami al <PHONE_1>"
}
POST /restore

Request:

{
  "masked_conversation_id": "<encrypted-id>",
  "masked_text": "Buongiorno, sono <PERSON_1:first_name last_name>. Chiamami al <PHONE_1>"
}

Response:

{
  "conversation_id": "chat-123",
  "raw_text": "Buongiorno, sono Mario Rossi. Chiamami al +393331234567"
}

OpenAPI: GET /openapi.json

Configurazione

Variabili ambiente principali
  • SCRUBBER_CRYPTO_KEY (obbligatoria): chiave segreta per cifrare/decifrare conversation_id
  • CONFIG_DIR (default /config in container): directory file YAML
  • DEFAULT_LANG (default en, consigliato it per uso italiano)
  • LANGUAGES_CONFIG_FILE (default languages-config.yaml)
  • RECOGNIZERS_CONFIG_FILE (opzionale, es. pattern-recognizers.yaml)
  • SCRUBBER_APP_CONFIG_FILE (default scrubber-app-config.yaml)

DB (se non usi DB_PII_SCRUBBER_URI):

  • DB_HOST, DB_PORT
  • POSTGRES_PASSWORD (admin setup)
  • SCRUBBER_DB_USER, SCRUBBER_DB_PASSWORD, SCRUBBER_DB_NAME
I 3 file YAML
1) config/languages-config.yaml

Configura NLP engine (spaCy), mapping label->entity Presidio, e labels_to_ignore.

Uso tipico:

  • scegliere modello lingua (it_core_news_lg)
  • ridurre falsi positivi ignorando entità poco affidabili nel tuo dominio (es. LOCATION)
2) config/pattern-recognizers.yaml

Custom recognizer regex/context-based.

Uso tipico:

  • pattern telefono italiani
  • recognizer specifici JSON (full_name, phone, email) per aumentare precisione su payload strutturati
3) config/scrubber-app-config.yaml

Regole applicative del microservizio:

  • denylist: termini da non mascherare (es. saluti)
  • entity_priority: tie-break tra entita su overlap
  • json_key_primary_entity: semantica per masking JSON key/value (es. children: CHILD)

Di seguito esempio di configurazione in yaml:

# Application-level scrubber behavior config

denylist:
  - dotty
  - buonasera
  - buongiorno
  - salve
  - ciao
  - grazie
  - prego
  - per favore
  - scusi
  - scusami

entity_priority:
  PERSON: 100
  PHONE: 90
  PHONE_NUMBER: 90
  EMAIL: 80
  EMAIL_ADDRESS: 80
  LOCATION: 70

json_key_primary_entity:
  full_name: PERSON
  name: PERSON
  phone: PHONE
  email: EMAIL_ADDRESS
  children: CHILD

Esecuzione locale (venv)

git clone <repo-url>
cd pii-scrubber
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp example.env .env

Genera chiave crypto:

python scripts/generate_key.py
# copia il valore in .env -> SCRUBBER_CRYPTO_KEY=...

Avvio servizio:

set -a
. ./.env
set +a
bash scripts/entrypoint.sh

Servizio disponibile su http://localhost:8080.

Script operativi (pull, build, run)

A) Pull aggiornamenti da git
#!/usr/bin/env bash
set -euo pipefail

git fetch --all --tags
git pull --rebase
B) Build immagine Docker
#!/usr/bin/env bash
set -euo pipefail

docker build -t pii_scrubber:latest .
C) Generazione crypto key via Docker
#!/usr/bin/env bash
set -euo pipefail

docker run --rm -v "$PWD":/app -w /app python:3.13-slim python scripts/generate_key.py
D) Run container Docker

Prerequisiti:

  • .env valorizzato (incluso SCRUBBER_CRYPTO_KEY)
  • PostgreSQL raggiungibile
#!/usr/bin/env bash
set -euo pipefail

docker run --rm \
  -p 8080:8080 \
  --env-file .env \
  -e CONFIG_DIR=/config \
  -v "$PWD/config":/config \
  -v "$PWD/data":/app/data \
  --name pii_scrubber \
  mariomastrorilli/pii_scrubber:latest

Template docker-compose

services:
  pii_scrubber:
    image: mariomastrorilli/pii_scrubber:latest
    container_name: pii_scrubber
    restart: unless-stopped
    env_file:
      - .env
    environment:
      CONFIG_DIR: /config
      DB_HOST: db
      DB_PORT: "5432"
      # opzionale alternativa completa:
      # DB_PII_SCRUBBER_URI: postgresql://pii_scrubber:pii_scrubber@db:5432/pii_scrubber
    volumes:
      - ./config:/config:ro
      - ./data:/app/data
    ports:
      - "8080:8080"
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:16
    container_name: pii_scrubber_db
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: postgres
    ports:
      - "5432:5432"
    volumes:
      - db_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 20

volumes:
  db_data:

Test

E2E (tutti):

./.venv/bin/python -m unittest discover -s test -p 'test*_e2e.py' -v

Include anche:

  • cifratura/decifratura conversation_id
  • JSON key masking (es. chiavi in children)
  • flussi plain text conversazionali

Release pipeline

Task VS Code:

  • Release Pipeline

Script:

bash scripts/release_pipeline.sh v1.2.3

La pipeline gestisce:

  • validazione tag SemVer (vX.Y.Z[-prerelease][+build])
  • check/update immagine base python (con conferma)
  • report compatibilita requirements (stable only, con opzioni di applicazione)
  • build, run, wait readiness
  • rigenerazione SDK OpenAPI
  • test E2E + test SDK
  • commit, tag git, push
  • buildx multi-arch e push Docker Hub

Hardening consigliato (produzione)

  • Ruotare periodicamente SCRUBBER_CRYPTO_KEY con strategia di migrazione.
  • Separare rete interna per DB e API.
  • Limitare accesso endpoint /restore (authN/authZ, mTLS, allowlist).
  • Abilitare audit log applicativo senza PII in chiaro.
  • Definire policy di retention su mapping token nel vault.
  • Eseguire DPIA completa con misure tecniche/organizzative del contesto reale.

Limiti noti

  • Accuratezza NLP dipende dal dominio linguistico e dalla qualita dei recognizer.
  • La pseudonimizzazione non elimina obblighi GDPR su dati personali.
  • Input non strutturato puo richiedere tuning continuo di recognizer/denylist.

Created by Mario Mastrorilli

Tag summary

Content type

Image

Digest

sha256:879c04115

Size

1.2 GB

Last updated

7 months ago

docker pull mariomastrorilli/pii_scrubber