Invarix.Guard.Professional 1.2.0

dotnet add package Invarix.Guard.Professional --version 1.2.0
                    
NuGet\Install-Package Invarix.Guard.Professional -Version 1.2.0
                    
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="Invarix.Guard.Professional" Version="1.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Invarix.Guard.Professional" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Invarix.Guard.Professional" />
                    
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 Invarix.Guard.Professional --version 1.2.0
                    
#r "nuget: Invarix.Guard.Professional, 1.2.0"
                    
#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 Invarix.Guard.Professional@1.2.0
                    
#: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=Invarix.Guard.Professional&version=1.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Invarix.Guard.Professional&version=1.2.0
                    
Install as a Cake Tool

Invarix.Guard.Professional

Invarix Guard Logo

Commercial add on for Invarix.Guard, the .NET native AI safety middleware. Runs in process with no scanner egress; your inputs never leave your box, even when your LLM call goes to OpenAI or Anthropic.

This package is license gated and requires a Professional tier license. Contact sales@invarix.dk for purchasing details, or buy directly at invarix.dk.

What it adds

The headline feature is the CustomBlocklistScanner, a license gated IScanner that lets you define rules in a JSON file your ops team can edit without redeploying. Each rule fires through two paths in parallel:

  1. Keyword path. Exact, predictable, fast. List the words or phrases you want flagged (e.g. "weapons", "drugs", "death"); rule fires on word boundary case insensitive match. No ML lottery.
  2. Semantic path. Embeddings catch paraphrases the keyword list can't anticipate. Rule fires when input similarity to any anchor (example or description) crosses the threshold.

Either path firing fires the rule. You can mix and match per rule: keyword only, examples only, or both.

Rules support 100+ languages out of the box. Write rules in English; matching works in Spanish, French, Chinese, Arabic, etc. with the same threshold.

Rule fields

  • keywords (optional): exact terms to match. Word boundary, case insensitive. Most reliable; pick concrete words you'd never want said.
  • examples (optional): 1 to 5 short phrases describing the intent. Each is embedded individually; the scanner takes max similarity at scan time.
  • description (optional): free text. Embedded as an additional semantic anchor.
  • threshold (optional): cosine similarity floor for the embedding path. Default 0.82.
  • action (required): block, warn, or log.
  • severity (required): low, medium, high, critical.

At least one of keywords or examples must be present.

Installation

dotnet add package Invarix.Guard.Professional

Community is a transitive dependency, so the line above is enough. For clarity:

dotnet add package Invarix.Guard

Setup

Three calls in Program.cs:

using Invarix.Guard.Extensions;
using Invarix.Guard.Professional.Extensions;

var builder = WebApplication.CreateBuilder(args);

// 1. Community: provides the engine + ML models.
builder.Services.AddInvarixGuard(o => o
    .BlockInjection()
    .BlockPII()
    .BlockToxicContent()
    .WithML(ml => ml.ModelsDirectory = "models"));

// 2. Pro license check: fails fast at startup if missing or invalid.
builder.Services.AddInvarixGuardProfessional(
    licenseToken: Environment.GetEnvironmentVariable("INVARIX_GUARD_LICENSE"));

// 3. Custom blocklist: reads rules from JSON and registers as IScanner.
builder.Services.AddCustomBlocklist(o =>
{
    o.ConfigPath = "config/blocklist.json";
    // o.WatchForChanges = true (default) hot reloads on file save.
});

var app = builder.Build();
app.UseInvarixGuard(); // Community middleware automatically picks up the Pro scanner.

app.MapPost("/chat", (ChatRequest r) => Results.Ok(new { reply = "..." }));
app.Run();

The Pro scanner runs as part of the normal app.UseInvarixGuard() pipeline. No extra middleware glue.

Rules file

Default location: blocklist.json in the working directory. Override via CustomBlocklistOptions.ConfigPath.

Schema

{
  "version": 1,
  "rules": [
    {
      "id": "internal-codename-bluesky",
      "description": "References to Project Blue Sky (internal codename, NDA only)",
      "keywords": ["Blue Sky", "BlueSky", "Project Bluesky"],
      "examples": [
        "Project Blue Sky timeline",
        "the Blue Sky launch event",
        "what is codenamed Blue Sky"
      ],
      "action": "block",
      "severity": "high"
    },
    {
      "id": "salary-disclosure",
      "description": "Discussions of internal salary, compensation, or pay details",
      "keywords": ["salary", "salaries", "compensation", "comp band", "pay range", "wage"],
      "examples": [
        "what is the salary range for senior engineers",
        "how much does the VP of Sales make"
      ],
      "action": "warn",
      "severity": "medium"
    },
    {
      "id": "competitor-strategic-mention",
      "description": "Strategic mentions of named competitors. Log only, do not block.",
      "keywords": ["Acme Inc", "Acme Corp"],
      "examples": [
        "we should beat Acme Inc on this",
        "the Acme deal is at risk"
      ],
      "action": "log",
      "severity": "low"
    }
  ]
}

Field reference

Field Required Type Notes
version Yes int Currently 1. Future proofs the schema.
rules Yes array One entry per rule. Empty array is valid (zero rules).
rules[].id Yes string Unique within the file. Surfaced in ScanMatch.Rule as CustomBlocklist:{id}.
rules[].description No string Free text. Also embedded as an additional semantic anchor. A tight description like "Discussions of internal salary, compensation, or pay details" gives the rule extra recall on top of the per example anchors.
rules[].examples If no keywords array of string 1 to 5 paraphrased examples. Each embedded as its own anchor. Empty or whitespace only entries are dropped.
rules[].keywords If no examples array of string Word boundary, case insensitive triggers. Fires the rule immediately when matched, no embedding compute. Most reliable path; use for terms you'd always want to catch.
rules[].threshold No float Cosine similarity threshold for the embedding path. Default 0.82. Clamped to [0.4, 0.95]. Has no effect on the keyword path.
rules[].action Yes string block, warn, or log. Case insensitive.
rules[].severity Yes string low, medium, high, or critical. Case insensitive.

Keyword matching

  • Word boundary at the start of the keyword. "pay" matches "pay", "paycheck", "Paypal" (start of word) but not "repay" or "display" (mid word).
  • Case insensitive. "Salary" matches salary, SALARY, SaLaRy.
  • Multi word keywords work. "pay range" matches "the pay range is" cleanly.
  • Trade off: "pay" matches "Paypal". If that's a problem, use a more specific keyword ("pay range", "pay band") or rely on the embedding path with examples instead.

Hot reload

By default the JSON file is watched. When you save a change, the scanner reloads after a short debounce window.

  • A successful reload swaps the active rule list. In flight scans always finish against the rule list they started with.
  • A reload that fails (broken JSON, file removed) is logged as an error and the previous rules stay live. A typo in the editor never takes down prod.
  • Disable watching for environments where the file is generated at build time and never changes:
builder.Services.AddCustomBlocklist(o => o.WatchForChanges = false);

Per rule actions

Action Behavior
block Stops the request at the configured severity. The engine returns its block response and your handler is never invoked.
warn Records the match but doesn't stop the request. The match shows up in GuardResult so your handler can decide what to do. Use for known noisy rules where you want signal but not action.
log Logs the match to your ILogger with rule ID, similarity, and severity. No effect on the request. Use for "we want to know this is happening" rules.

A Pro rule firing at High or Critical overrides a Community side Pass verdict, so you can use Pro rules to add policy on top of the built in scanners without touching them.

Performance

The embedding compute is shared with Community's built in scanner: there's no extra ML cost on top of what Community already pays. Adding 100 rules contributes well under 100 µs to per request latency. Memory is a few hundred KB per 100 rules.

Failure modes

Symptom Cause Fix
InvalidOperationException: AddInvarixGuardProfessional ... before AddCustomBlocklist Forgot to register the Pro license. Call AddInvarixGuardProfessional(licenseToken) first.
InvalidOperationException: AddInvarixGuard ... before AddCustomBlocklist Forgot to register Community. Call AddInvarixGuard(...) first.
InvalidOperationException: needs the multilingual embedding model embedding.onnx not resolvable. Ensure model file is in MLGuardOptions.ModelsDirectory, or enable AutoDownloadModels.
InvalidLicenseException (any reason) Token missing, malformed, expired, signature failed, or wrong SKU. Check INVARIX_GUARD_LICENSE env var or the value passed to AddInvarixGuardProfessional.
Rules silently not firing Threshold too tight, examples too few or too narrow. Review ILogger debug output; lower threshold by 0.05 or add 1 to 2 more examples.
Stale rules after editing JSON WatchForChanges = false, or filesystem layer not delivering events (some Docker volume mounts). Either enable change watching or restart the host process.

Lifetime + commercial terms

Professional is sold as a one time, lifetime license per company:

  • All updates forever.
  • Per company, unlimited environments: staging, prod, dev, internal demos.
  • Non transferable on acquisition.
  • No support. Not over email, chat, or GitHub Issues. The README is the only resource.

The license token is signed Ed25519 and validated fully offline against a public key baked into the package. No phone home, no licensing server. The version you bought keeps running indefinitely; it doesn't matter if Invarix shuts down.

Contact

  • Commercial licensing, custom terms: sales@invarix.dk
  • Security, vulnerability reports: security@invarix.dk
Product Compatible and additional computed target framework versions.
.NET 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 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

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.