Caveman.PrivacyGuard
1.2.1
dotnet add package Caveman.PrivacyGuard --version 1.2.1
NuGet\Install-Package Caveman.PrivacyGuard -Version 1.2.1
<PackageReference Include="Caveman.PrivacyGuard" Version="1.2.1" />
<PackageVersion Include="Caveman.PrivacyGuard" Version="1.2.1" />
<PackageReference Include="Caveman.PrivacyGuard" />
paket add Caveman.PrivacyGuard --version 1.2.1
#r "nuget: Caveman.PrivacyGuard, 1.2.1"
#:package Caveman.PrivacyGuard@1.2.1
#addin nuget:?package=Caveman.PrivacyGuard&version=1.2.1
#tool nuget:?package=Caveman.PrivacyGuard&version=1.2.1
Caveman.PrivacyGuard 🛡️🇪🇺
<img width="638" height="408" alt="Gemini_Generated_Image_tnxoi9tnxoi9tnxo" src="https://github.com/user-attachments/assets/5a8e3193-b7d3-4a41-90e6-e672467ce6cb" />
Enterprise-grade PII & Privacy Analyzer for AI/LLM workflows
Rileva, valuta e maschera automaticamente dati sensibili in 27 paesi UE, con scoring del rischio, conformità GDPR/PCI-DSS/NIST e integrazione seamless con qualsiasi pipeline AI.
✨ Features
| Feature | Descrizione |
|---|---|
| 🌍 27 Paesi UE | Pattern nativi per IT, DE, FR, ES, PL, NL, SE, FI, DK, AT, BE, PT, IE, GR, CZ, RO, HU, BG, HR, SK, SI, LT, LV, EE, CY, MT, LU + regole EU generiche |
| 🔍 Detection Euristica | Regex precompilate + validatori algoritmici (Luhn, IBAN MOD97, checksum nazionali) + analisi entropia Shannon |
| 📊 Privacy Score | Punteggio 0-100 con livelli: Sicuro → Basso → Medio → Alto → Critico |
| 🎭 Auto-Masking | Sostituzione dinamica con placeholder contestuali ([EMAIL], [IBAN], [CF_IT], ecc.) |
| ⚙️ YAML-Driven | Regole configurabili in rules.yaml embedded, estendibili a runtime |
| 🔐 Compliance Flags | Mappatura automatica a GDPR, PCI-DSS, NIST 800-53, autorità nazionali (CNIL, BfDI, AEPD, ecc.) |
| 🧵 Thread-Safe | Pronto per microservizi ad alto throughput con ReaderWriterLockSlim e regex cache |
| 🔄 Session Restore | Placeholder univoci [PG_N] per occorrenza, ripristino lato client dei dati originali nelle risposte AI, zero dati sensibili inviati al LLM |
| ✂️ Dynamic Rules | Carica/scarica/ispeziona regole a runtime: LoadCustomYaml, RemoveRule(), GetRule(), GetLoadedCategories() |
| 🧹 Whitelist Lifecycle | AddToWhitelist, RemoveFromWhitelist, ClearWhitelist, GetWhitelist, IsWhitelisted |
| 🔌 Extensible Validators | Registra, rimuovi o resetta validatori personalizzati con ValidatorRegistry.Register / Unregister / Reset |
| ⚡ Async API | AnalyzeAsync con 4 overload + CancellationToken per UI/web |
| 🔌 JSON Config | LoadCustomJson / LoadCustomJsonFromString con hot-reload (WatchConfig / ConfigReloaded) |
| 💾 Session Export | ToJson / FromJson / ImportFromJson per persistenza placeholder |
| 🔍 IReadOnlySession | Interfaccia read-only per API pubbliche che non devono mutare la sessione |
| ✅ ValidateRules | Metodo pubblico per validare tutte le regole caricate |
| 🛡️ Safe Dispose | ThrowIfDisposed() su tutti i metodi pubblici, catch(SynchronizationLockException) graceful |
| 🪵 ILogger | Integrazione con Microsoft.Extensions.Logging.Abstractions per diagnostic |
| 📋 CHANGELOG | Tracciamento versioni incluso nel pacchetto NuGet |
| 🌐 .NET Standard 2.0 | Compatibile con framework .NET legacy |
| 🚀 Performance | RegexOptions.NonBacktracking (.NET 8), pre-compilazione, cache O(1), zero allocazioni ridondanti, timeout 3s anti-ReDoS |
📦 Installazione
dotnet add package Caveman.PrivacyGuard
🚀 Quick Start
Modalità Avviso (Default)
var analyzer = new PrivacyAnalyzer { EnableAutoMasking = true };
// 🔹 Default: Inglese
var resEn = analyzer.Analyze("CF: RSSMRA80A01H501U, email: test@x.com");
Console.WriteLine($"[EN] Risk: {resEn.RiskLevel}\n{resEn.WarningMessage}");
// 🔹 Overload: Italiano
var resIt = analyzer.Analyze("CF: RSSMRA80A01H501U, email: test@x.com", "it");
Console.WriteLine($"[IT] Rischio: {resIt.RiskLevel}\n{resIt.WarningMessage}");
// 🔹 Overload: Tedesco
var resDe = analyzer.Analyze("Steuer-ID: 12345678901, IBAN: DE89370400440532013000", "de");
Console.WriteLine($"[DE] Risiko: {resDe.RiskLevel}\n{resDe.WarningMessage}");
Output:
🔒 Score: 26/100
⚠️ Avviso: ⛔ Dati rilevati: Codice Fiscale (IT), Email. Pseudonimizzazione obbligatoria.
✅ Safe for AI: False
var analyzer = new PrivacyAnalyzer { EnableAutoMasking = true };
var text = "Cliente: Mario Rossi, email mario@azienda.it, IBAN: IT60X0542811101000000123456";
var result = analyzer.Analyze(text);
Console.WriteLine($"🛡️ Testo sicuro per LLM:\n{result.MaskedText}");
Output:
🛡️ Testo sicuro per LLM:
Cliente: Mario Rossi, email [EMAIL], IBAN: [IBAN]
🪄 Session Restore — Zero Sensitive Data to the LLM
Il vero punto di forza: i dati sensibili non lasciano mai il client. Il flusso è:
- Mask —
PrivacyAnalyzerrileva e sostituisce con placeholder univoci[PG_1],[PG_2], ecc. - Send — Il testo mascherato (privo di dati reali) viene inviato al LLM
- Restore — La risposta del LLM viene processata da
PrivacySession.Restore()che ripristina i valori originali lato client
var session = new PrivacySession();
var analyzer = new PrivacyAnalyzer { EnableAutoMasking = true };
// 1. Analizza e maschera (i dati restano solo nella session)
var result = analyzer.Analyze(
"Mario Rossi, email mario@azienda.it, IBAN: IT60X0542811101000000123456",
"en", session);
Console.WriteLine(result.MaskedText);
// Output: Mario Rossi, email [PG_1], IBAN: [PG_2]
// 2. Invia result.MaskedText al LLM...
var aiResponse = "Contatta il cliente via [PG_1] per l'addebito su [PG_2]";
// 3. Ripristina lato client (nessun dato sensibile è mai uscito)
var safeResponse = session.Restore(aiResponse);
Console.WriteLine(safeResponse);
// Output: Contatta il cliente via mario@azienda.it per l'addebito su IT60X0542811101000000123456
API Reference
// Crea una nuova sessione
var session = new PrivacySession();
// Analizza con sessione (placeholder univoci [PG_N])
var result = analyzer.Analyze(input, "en", session);
// Oppure via proprietà CurrentSession
analyzer.CurrentSession = new PrivacySession();
var result = analyzer.Analyze(input);
// Ripristina una risposta AI
string restored = session.Restore(aiResponseText);
// Ispeziona i placeholder generati
foreach (var entry in session.GetAll())
Console.WriteLine($"{entry.Key} → {entry.Value.OriginalValue} ({entry.Value.Category})");
// Ottieni un singolo mapping
var entry = session.GetEntry("[PG_1]");
// Aggiungi manualmente un placeholder (pubblico)
session.AddOrGet("Email", "manual@test.com");
// Unisci un'altra sessione (ignora duplicati per valore)
session.MergeFrom(anotherSession);
// Resetta la sessione
session.Clear();
// Metodo statico su PrivacyAnalyzer
string restored = PrivacyAnalyzer.RestoreText(aiResponse, session);
// Metodo di istanza (usa CurrentSession)
analyzer.CurrentSession = session;
string restored2 = analyzer.RestoreText(aiResponse);
Nota: Senza sessione (
Analyze(input)oAnalyze(input, lang)), il masking usa i placeholder testuali[EMAIL],[IBAN], ecc. come in precedenza.
| Codice | Paese | Identificatori Principali | Autorità di Riferimento |
|---|---|---|---|
| 🇮🇹 IT | Italia | Codice Fiscale, Partita IVA | Garante Privacy, Agenzia Entrate |
| 🇩🇪 DE | Germania | Steuer-ID, Personalausweis | BfDI, DSGVO |
| 🇫🇷 FR | Francia | NIR/SSN, SIREN/SIRET | CNIL, RGPD |
| 🇪🇸 ES | Spagna | NIF/NIE | AEPD, RGPD |
| 🇵🇱 PL | Polonia | PESEL, NIP | UODO, RODO |
| 🇳🇱 NL | Paesi Bassi | BSN | AP, AVG |
| 🇸🇪 SE | Svezia | Personnummer | IMY |
| 🇫🇮 FI | Finlandia | Henkilötunnus (HETU) | Tietosuojavaltuutettu |
| 🇩🇰 DK | Danimarca | CPR | Datatilsynet |
| 🇦🇹 AT | Austria | SV-Nummer, UID | DSB |
| 🇧🇪 BE | Belgio | Numéro National | APD |
| 🇵🇹 PT | Portogallo | NIF | CNPD |
| 🇮🇪 IE | Irlanda | PPSN | DPC |
| 🇬🇷 GR | Grecia | AFM, AMKA | HDPA |
| 🇨🇿 CZ | Cechia | Rodné číslo | ÚOOÚ |
| 🇷🇴 RO | Romania | CNP | ANSPDCP |
| 🇭🇺 HU | Ungheria | Adóazonosító | NAIH |
| 🇧🇬 BG | Bulgaria | EGN | CPDP |
| 🇭🇷 HR | Croazia | OIB | AZOP |
| 🇸🇰 SK | Slovacchia | Rodné číslo | ÚOOÚ |
| 🇸🇮 SI | Slovenia | EMŠO | IP |
| 🇱🇹 LT | Lituania | Asmens kodas | VDAI |
| 🇱🇻 LV | Lettonia | Personas kods | DVI |
| 🇪🇪 EE | Estonia | Isikukood | AKI |
| 🇨🇾 CY | Cipro | ID Number | CIPD |
| 🇲🇹 MT | Malta | ID Number | IDPC |
| 🇱🇺 LU | Lussemburgo | Numéro d'identification | CNPD |
⚙️ Configurazione Avanzata
Whitelist (Esclusioni Sicure)
analyzer.AddToWhitelist(
"test@company.eu", // Email di test
"127.0.0.1", // IP localhost
"IT00000000000" // PIVA dummy
);
// Rimozione e reset
analyzer.RemoveFromWhitelist("test@company.eu");
analyzer.ClearWhitelist(); // rimuove tutte le esclusioni
// Ispezione
var all = analyzer.GetWhitelist(); // IReadOnlySet<string>
if (analyzer.IsWhitelisted("127.0.0.1"))
Console.WriteLine("IP nella whitelist");
Validatori Personalizzati
// Registra un nuovo validatore per un formato nazionale custom
ValidatorRegistry.Register("MY_CUSTOM_ID", value =>
value.Length == 10 && value.StartsWith("XYZ") && value.All(char.IsDigit));
// Rimuove un validatore esistente
ValidatorRegistry.Unregister("MY_CUSTOM_ID");
// Resetta tutti i validatori ai built-in (rimuove i custom)
ValidatorRegistry.Reset();
Ispezione e Gestione Regole a Runtime
// Elenca tutte le categorie di regole attualmente caricate
var categories = analyzer.GetLoadedCategories();
// Ispeziona una regola specifica (regex, peso, validatore, ecc.)
var emailRule = analyzer.GetRule("Email");
Console.WriteLine(emailRule.Pattern); // regex compilata
Console.WriteLine(emailRule.BaseWeight); // peso
// Rimuove tutte le regole di una categoria
analyzer.RemoveRule("Email");
// Pulisce TUTTE le regole (embedded + custom)
analyzer.ClearRules();
Rilascio Risorse
PrivacyAnalyzer implementa IDisposable per rilasciare il ReaderWriterLockSlim. Tutti i metodi pubblici lanciano ObjectDisposedException se chiamati dopo lo smaltimento:
using var analyzer = new PrivacyAnalyzer { EnableAutoMasking = true };
var result = analyzer.Analyze("test@example.com");
// analyzer.Dispose() chiamato automaticamente all'uscita del using
Analisi Asincrona
Per applicazioni UI o web, AnalyzeAsync esegue l'analisi su un thread pool e supporta CancellationToken:
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
try
{
var result = await analyzer.AnalyzeAsync(
"Email: test@example.com, IBAN: IT60X0542811101000000123456",
cts.Token);
Console.WriteLine($"Score: {result.Score}");
}
catch (OperationCanceledException)
{
Console.WriteLine("Analisi cancellata per timeout.");
}
Overload disponibili: AnalyzeAsync(input), AnalyzeAsync(input, session, ct), AnalyzeAsync(input, language, ct), AnalyzeAsync(input, language, session, ct).
YAML Esterno e Dinamico
// Carica regole da file (si aggiungono a quelle embedded)
analyzer.LoadCustomYaml("path/to/custom-rules.yaml");
// Carica regole da stringa YAML (utile per DB/config remota)
var yaml = @"
version: ""2.0""
countries:
- code: ""XX""
rules:
- category: ""CustomPII""
pattern: '\bSENSITIVE_\w+\b'
base_weight: 20
compliance_tags: [""GDPR Art.4(1)""]";
analyzer.LoadCustomYamlFromString(yaml);
Compliance Tags da YAML
I flag di compliance (compliance_tags nel YAML) vengono automaticamente raccolti e uniti a quelli hardcodati. Puoi aggiungere tag personalizzati per ogni regola:
- category: "MyCustomID"
pattern: '\bMY_\d{6}\b'
base_weight: 15
compliance_tags: ["GDPR Art.4(1)", "Internal Policy #42"]
JSON Config e Hot-Reload
Oltre a YAML, supportiamo configurazione JSON con hot-reload automatico:
// Carica regole da file JSON
analyzer.LoadCustomJson("path/to/custom-rules.json");
// Carica da stringa
var json = @"{
""version"": ""2.0"",
""countries"": [
{ ""code"": ""XX"", ""rules"": [
{ ""category"": ""CustomPII"", ""pattern"": ""\\bSENSITIVE_\\w+\\b"", ""base_weight"": 20 }
]}
]
}";
analyzer.LoadCustomJsonFromString(json);
// Hot-reload: osserva il file e ricarica automaticamente
analyzer.WatchConfig("path/to/custom-rules.json");
// Evento notificato dopo ogni ricarica
analyzer.ConfigReloaded += (s, e) => Console.WriteLine("⚡ Config ricaricata!");
// Ferma il watcher
analyzer.StopWatching();
Validazione Regole
Verifica che tutte le regole caricate siano valide (nessuna eccezione in fase di match):
if (analyzer.ValidateRules())
Console.WriteLine("✅ Tutte le regole sono valide");
else
Console.WriteLine("❌ Regole invalide trovate");
Integrazione ILogger
Collega un logger per diagnostic durante analisi e configurazione:
analyzer.Logger = myLogger; // ILogger<PrivacyAnalyzer>
// Eventi loggati: categorie rilevate, score alto, load configurazioni
Session Export e Persistence
Esporta e importa sessioni come JSON per salvare/ripristinare lo stato tra richieste:
var session = new PrivacySession();
session.AddEntry("Email", "test@example.com");
// Esporta
string json = session.ToJson();
// Ricostruisci
var restored = PrivacySession.FromJson(json);
// Importa in sessione esistente
existingSession.ImportFromJson(json);
IReadOnlySession
API read-only sicura per esposizione pubblica:
IReadOnlySession readOnly = session;
int count = readOnly.Count;
var entry = readOnly.GetEntry("[PG_1]");
string text = readOnly.Restore(aiResponse);
🔐 Compliance & GDPR
PrivacyAnalysisResult.ComplianceFlags combina automaticamente:
- YAML —
compliance_tagsdefiniti per ogni regola inrules.yaml - Hardcoded — Mappatura automatica per categorie note (GDPR, PCI-DSS, NIST 800-53)
if (result.ComplianceFlags.Contains("GDPR Art.4(1)"))
{
// Logica per base giuridica, DPIA, minimizzazione
}
if (result.ComplianceFlags.Contains("PCI-DSS"))
{
// Crittografia, segmentazione rete, audit
}
| Componente | Descrizione | **** | **** |
|---|---|---|---|
| BaseScore | Somma dei pesi delle regole matchate × validazione × confidence | ||
| CorrelationMultiplier | 1.0 + (categorie_distinte × 0.12)" | max 2.2" | |
| ContextBoost | +0.12 per ogni PII vicino a parole trigger (""password:" | "riservato" | ecc.)" |
| DensityBonus | Penalizza testi brevi con molti PII (rischio fuga dati) |
Soglie di Rischio:
| Score | Livello | Azione Consigliata |
|---|---|---|
| 0-15 | ✅ Sicuro (AI Ready) | Invio diretto a LLM |
| 16-35 | ⚠️ Basso | Logging + monitoraggio |
| 36-60 | ⛔ Medio | Anonimizzazione obbligatoria |
| 61-85 | 🚨 Alto | Sandbox isolata o dati sintetici |
| 86-100 | 🛑 Critico | Blocco assoluto, processing on-premise |
⚠️ Disclaimer: Questa libreria è uno strumento tecnico di supporto. Non sostituisce una Valutazione d'Impatto sulla Protezione dei Dati (DPIA) né il parere di un DPO. La conformità GDPR richiede valutazioni contestuali, basi giuridiche e processi organizzativi.
🧪 Testing & Performance
// Benchmark rapido
var analyzer = new PrivacyAnalyzer();
var sw = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < 10_000; i++)
{
analyzer.Analyze("Testo con email test@example.com e IBAN DE89370400440532013000");
}
sw.Stop();
Console.WriteLine($"⚡ 10k analisi in {sw.ElapsedMilliseconds}ms ({10_000.0 / sw.ElapsedMilliseconds:F1} req/sec)");
🤝 Contributing
Fork il repo Crea un branch per la tua feature (git checkout -b feature/nuovo-paese) Aggiungi regole in rules.yaml + validatori in ValidatorRegistry.cs Aggiungi test in tests/ (xUnit) PR con descrizione chiara e esempi 🌍 Per aggiungere un nuovo paese: segui lo schema YAML esistente, implementa il validatore (se necessario) e aggiungi la voce nella tabella del README.
📄 License
Distribuito sotto licenza MIT. Vedi LICENSE per dettagli.
🆘 Support & Roadmap
| Versione | Feature | Stato |
|---|---|---|
| 1.0 | 27 paesi UE, masking, YAML embedded | ✅ Release |
| 1.1 | Session Restore, placeholder univoci, ripristino lato client | ✅ Release |
| 1.2 | JSON config, hot-reload, async API, batch analyze, session export, ILogger, netstandard2.0, whitelist lifecycle, validatori dinamici, regex cache, ValidateRules, IReadOnlySession, CHANGELOG | ✅ Release |
| 1.3 | Configurazione YAML remota, session streaming, dashboard CLI | 🔄 Pianificazione |
🛡️ Proteggi i dati, abilita l'AI. Compliance by design.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.Bcl.AsyncInterfaces (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.2)
- System.IO.FileSystem.Watcher (>= 4.3.0)
- System.Text.Json (>= 8.0.5)
- System.Threading.Tasks.Extensions (>= 4.5.4)
- YamlDotNet (>= 15.1.6)
-
net8.0
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.2)
- System.Text.Json (>= 8.0.5)
- YamlDotNet (>= 15.1.6)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.