TasmanianDevil 0.2.1

dotnet add package TasmanianDevil --version 0.2.1
                    
NuGet\Install-Package TasmanianDevil -Version 0.2.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="TasmanianDevil" Version="0.2.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TasmanianDevil" Version="0.2.1" />
                    
Directory.Packages.props
<PackageReference Include="TasmanianDevil" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add TasmanianDevil --version 0.2.1
                    
#r "nuget: TasmanianDevil, 0.2.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package TasmanianDevil@0.2.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=TasmanianDevil&version=0.2.1
                    
Install as a Cake Addin
#tool nuget:?package=TasmanianDevil&version=0.2.1
                    
Install as a Cake Tool

TasmanianDevil

Context-aware PII detection and de-identification for .NET. A from-scratch engine whose architecture is inspired by Microsoft Presidio (MIT), rebuilt as idiomatic, dependency-light C#. Framework-agnostic and fast.

dotnet add package TasmanianDevil

Why TasmanianDevil

  • Validated, not just regex. Recognizers carry real checksum validation (Luhn, IBAN mod-97, Verhoeff, ISO-7064, ICAO, bech32), so a 16-digit number is only a credit card if it actually checks out.
  • Context-aware scoring. A bare token scores low and is dropped; nearby words ("card", "IBAN", "postcode") lift it over threshold via a dependency-free Porter-stemmer lemma matcher.
  • Reversible by design. Encrypt PII, hand the opaque text to a third party, and decrypt the exact original back - the operator pipeline records enough to round-trip byte-for-byte.
  • Beyond plain text. Structured JSON (by dotted path) and CSV (by inferred column) redaction, plus batch APIs over keyed records - all preserving shape and non-string values.
  • Offline core + an optional ML reach. The whole engine runs with zero models. When you want more, the TasmanianDevil.Onnx add-on plugs a real multilingual span-NER model into the same pipeline (see below) - getting that working is the hard part, and TasmanianDevil ships it.

Detection coverage

Generic (always on): CREDIT_CARD (Luhn), EMAIL_ADDRESS, IBAN_CODE (mod-97), CRYPTO (base58 + bech32/bech32m), IP_ADDRESS (v4/v6), URL, MAC_ADDRESS, PHONE_NUMBER (libphonenumber).

US pack (always on): US_SSN, US_ITIN, ABA_ROUTING_NUMBER, US_BANK_NUMBER, US_DRIVER_LICENSE, US_PASSPORT, US_NPI (Luhn), US_MBI, MEDICAL_LICENSE (DEA checksum).

Opt-in country packs (enabling all at once inflates false positives, so you choose): uk, de, in, it, es - each with validated national IDs, tax numbers, passports, driving licences, vehicle registrations, etc.

Quick start

using TasmanianDevil;

var engine = new PiiEngine();
var result = engine.Deidentify("Email jane@contoso.com or call +1 425 555 0100.");
Console.WriteLine(result.AnonymizedText);
// Email <EMAIL_ADDRESS> or call <PHONE_NUMBER>.

Operators

replace (default <ENTITY_TYPE>), redact, mask, hash (salted SHA-256/512), encrypt/decrypt (reversible AES-CBC), keep, and custom (your lambda):

var options = new PiiOptions
{
    Operators = new Dictionary<string, OperatorConfig>
    {
        ["EMAIL_ADDRESS"] = new("mask", new() { [OperatorParams.CharsToMask] = 6 }),
        ["CREDIT_CARD"]   = new("redact"),
        ["DEFAULT"]       = new("encrypt", new() { [OperatorParams.Key] = key }),
    },
    Countries = [PiiCountries.De],
};
var engine = new PiiEngine(options);
var deid = engine.Deidentify(text);          // deid.IsReversible == true (all-encrypt)

var decrypt = new Dictionary<string, OperatorConfig>
{
    ["DEFAULT"] = new("decrypt", new() { [OperatorParams.Key] = key }),
};
var back = engine.Reidentify(deid, decrypt); // exact original, byte-for-byte

Structured & batch

engine.AnonymizeJson(json, new JsonRedactionScope { IncludePaths = ["user.email"] });
engine.AnonymizeCsv(header, rows);           // infers which columns are PII
engine.AnonymizeBatch(new Dictionary<string,string> { ["billing_email"] = "..." });

The lower-level engines (AnalyzerEngine, AnonymizerEngine, DeanonymizerEngine, StructuredEngine, Batch*Engine) are all public if you want to compose them directly. See samples/PiiShowcase for a narrated end-to-end tour.

Optional multilingual ONNX NER

TasmanianDevil.Onnx adds PERSON / LOCATION / ORGANIZATION / DATE_TIME span detection - the entity classes regex fundamentally cannot reach - via a zero-shot GLiNER model (mDeBERTa-v3 backbone), multilingual out of the box. It registers as an ordinary recognizer, so its spans flow through the exact same overlap-resolution and anonymization as the regex/checksum entities.

dotnet add package TasmanianDevil.Onnx

It runs the model through Kyoto. The ONNX export is published at filip-w/gliner-multi-pii-onnx (fp16 default, ~580 MB):

using TasmanianDevil.Onnx;

var ner = new GlinerNerRecognizer(new GlinerNerOptions
{
    ModelPath = modelPath, TokenizerPath = spmPath, ConfigPath = configPath,
});
registry.AddRecognizer(ner);   // now PERSON/LOCATION/... join the same analyzer pass

Optional out-of-process detection (Remote / Azure)

Two add-ons let PII detection move out of process instead, while anonymization stays local - both are detectors, not redactors: they return entity spans that flow through the same AnalyzerEngine/AnonymizerEngine as every other recognizer.

TasmanianDevil.Remote speaks a generic HTTP contract - point it at any compatible service. TasmanianDevil.Azure talks directly to the Azure AI Language REST API (no Azure.AI.TextAnalytics SDK dependency), natively detecting PERSON, ADDRESS, PHONE_NUMBER, EMAIL_ADDRESS, ORGANIZATION, DATE_TIME, CREDIT_CARD, US_SSN, IP_ADDRESS, IBAN_CODE, URL (see AzurePiiCategoryMap) - configure SupportedEntities/PiiCategories for whichever subset you need. PERSON/ADDRESS are the main reason to reach for it: free-form names and street addresses have no checksum or fixed structure for the offline engine to validate.

Privacy note. Both send the raw, unredacted analyzed text off-box. This is the inherent tradeoff of remote detection - only use it when you've accepted that, and prefer a network boundary you control over a public hop where possible.

dotnet add package TasmanianDevil.Remote   # generic HTTP contract - point at any compatible service
dotnet add package TasmanianDevil.Azure    # Azure AI Language - native Person + full street Address

The engine is async-first: EntityRecognizer has an AnalyzeAsync alongside sync Analyze (defaulting to a zero-cost wrapper), and AnalyzerEngine/PiiEngine both expose AnalyzeAsync/ AnonymizeAsync/DeidentifyAsync counterparts. A remote recognizer is "just an async EntityRecognizer" - it overrides AnalyzeAsync, leaves sync Analyze returning nothing, and the sync API path silently ignores it.

using TasmanianDevil.Remote;

var registry = PiiRecognizers.CreateRegistry("en");
registry.AddRecognizer(new RemotePiiRecognizer(
    new HttpPiiDetectionClient(new RemotePiiOptions { Endpoint = endpoint, SupportedEntities = [PiiEntities.Person] }),
    new RemotePiiOptions { Endpoint = endpoint, SupportedEntities = [PiiEntities.Person] }));

var engine = new PiiEngine(analyzer: new AnalyzerEngine(registry));
var result = await engine.AnonymizeAsync("Hi, this is John Smith.");

Or, for the Azure detector (native Person/Address, no Azure.AI.TextAnalytics SDK dependency):

using TasmanianDevil.Azure;

var client = new AzurePiiClient(new AzurePiiOptions
{
    Endpoint = azureEndpoint,
    SubscriptionKey = azureKey,
    SupportedEntities = [PiiEntities.Person, PiiEntities.Address],
});
registry.AddRecognizer(new AzurePiiRecognizer(client, new AzurePiiOptions { /* same options */ }));

Both fail open by default (a remote failure yields no results for that request rather than throwing, so local recognizers still redact what they can) and clamp/validate everything the remote side returns (entity type must be among what was requested, score clamped to [0,1], offsets must fit the analyzed text) before trusting it. See each package's XML docs for the full option surface (timeout, auth, category-map override, confidence threshold). The guardrail-level integration (.RedactPiiWithRemote()/.RedactPiiWithAzure()) lives in AgentGuard's AgentGuard.RemotePii/AgentGuard.Azure packages - see its docs/remote-pii.md for the full wire contract, a sidecar recipe, and managed-identity setup.

Attribution

See THIRD_PARTY_NOTICES.txt (Microsoft Presidio MIT, CommonRegex MIT, libphonenumber Apache-2.0, public-domain Porter stemmer / Verhoeff / ISO-7064 / ICAO / Luhn algorithms).

License

MIT

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on TasmanianDevil:

Package Downloads
TasmanianDevil.Onnx

Optional ONNX named-entity recognition for TasmanianDevil. Adds offline, multilingual PERSON / LOCATION / ORGANIZATION / DATE_TIME span detection (GLiNER, via Kyoto) into the TasmanianDevil analyzer/anonymizer pipeline as an ordinary recognizer. Bring-your-own ONNX model.

AgentGuard.Pii

AgentGuard guardrail adapter for TasmanianDevil PII detection/de-identification. Exposes the order-20 PiiRule and the .RedactPii() policy-builder extension over the TasmanianDevil engine. See https://github.com/filipw/AgentGuard for details.

TasmanianDevil.Azure

Optional Azure AI Language PII detection for TasmanianDevil. Calls the Azure AI Language PII entity recognition REST API directly (no SDK dependency) and merges the returned entity spans - including native Person and full street Address categories - into the TasmanianDevil analyzer/anonymizer pipeline as an ordinary async recognizer. Detector only - anonymization stays local.

TasmanianDevil.Remote

Optional out-of-process PII detection for TasmanianDevil. Calls a generic HTTP detector (e.g. a TasmanianDevil + GLiNER sidecar) and merges the returned entity spans into the TasmanianDevil analyzer/anonymizer pipeline as an ordinary async recognizer. Detector only - anonymization stays local.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.1 978 7/8/2026
0.2.0 120 7/7/2026
0.1.0 1,557 6/25/2026