AgenticFirewall.Core 1.0.2

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

AgenticFirewall.Core

A .NET 8 library that validates and sanitizes LLM input and output before it reaches your users. Drop it into any agentic application — no LLM dependency required.


Features

Layer What it catches
Global blocklist Prompt injection, jailbreak phrases, credential fishing, destructive commands
Role/delimiter injection Fake conversation-turn markers ([INST], <\|im_start\|>, ### Human:, etc.)
Agent-specific blocklists Domain attacks tailored to 10 built-in agent types
Custom banned words Per-application word lists merged into the validation pipeline at call time
Normalization pipeline Homoglyphs, leet-speak, zero-width chars, Bidi overrides, base64 encoding
Sensitive data redaction SSNs, credit card numbers, API keys
Input size enforcement Configurable character-count cap to block token-flooding attacks

Installation

.NET CLI

dotnet add package AgenticFirewall.Core

Package Manager Console

Install-Package AgenticFirewall.Core

PackageReference (csproj)

<PackageReference Include="AgenticFirewall.Core" Version="1.0.0" />

View on NuGet: nuget.org/packages/AgenticFirewall.Core

All dependencies (AhoCorasick, Microsoft.Extensions.DependencyInjection.Abstractions) are pulled in automatically.


Alternative — Project reference (source)

<ProjectReference Include="..\AgenticFirewall.Core\AgenticFirewall.Core.csproj" />

Dependencies: AhoCorasick 2.0.279


Integration

ASP.NET Core / any DI app

Register with one line in Program.cs:

using AgenticFirewall.Core;

builder.Services.AddAgenticFirewall();

Inject IFirewallService wherever you need it:

app.MapPost("/api/chat", (ChatRequest req, IFirewallService firewall) =>
{
    firewall.Validate(req.Message, AgentType.AppointmentBooker);
    // ...
});

As ASP.NET Core middleware (validates every request automatically):

// Program.cs
app.UseMiddleware<FirewallMiddleware>();

// FirewallMiddleware.cs
public class FirewallMiddleware(RequestDelegate next, IFirewallService firewall, ILogger<FirewallMiddleware> logger)
{
    public async Task InvokeAsync(HttpContext context)
    {
        if (context.Request.Path.StartsWithSegments("/api/chat"))
        {
            context.Request.EnableBuffering();
            using var reader = new StreamReader(context.Request.Body, leaveOpen: true);
            var body = await reader.ReadToEndAsync();
            context.Request.Body.Position = 0;

            try
            {
                firewall.Validate(body, AgentType.General);
            }
            catch (SecurityException ex)
            {
                logger.LogWarning("[Firewall] Blocked: {Message}", ex.Message);
                context.Response.StatusCode = 403;
                await context.Response.WriteAsJsonAsync(new { blocked = true, reason = ex.Message });
                return;
            }
        }
        await next(context);
    }
}

Console app / no DI

Use the static Firewall façade — no setup required:

using AgenticFirewall.Core;

try
{
    Firewall.Validate(userInput, AgentType.EmailSender);
    string safe = Firewall.Redact(userInput);
    // forward `safe` to the LLM
}
catch (SecurityException ex)
{
    Console.WriteLine($"Blocked: {ex.Message}");
}

Validate LLM output too

Run the same check on the model's response before showing it to the user:

var llmResponse = await GetLlmResponseAsync(userInput);

try
{
    Firewall.Validate(llmResponse); // catches data leaks, injected instructions, etc.
    Display(llmResponse);
}
catch (SecurityException ex)
{
    logger.LogWarning("[Firewall] LLM response blocked: {Message}", ex.Message);
    Display("Sorry, that response was blocked by the safety filter.");
}

Manual DI registration (without the extension method)

builder.Services.AddSingleton<IFirewallService, FirewallService>();

API Reference

Firewall (static façade)

Firewall.Validate(string input, InputSizeLimit sizeLimit = Standard);
Firewall.Validate(string input, AgentType agentType, InputSizeLimit sizeLimit = Standard);
Firewall.Validate(string input, IEnumerable<string> customBannedWords, bool isAllCustom = false, InputSizeLimit sizeLimit = Standard);
Firewall.Validate(string input, AgentType agentType, IEnumerable<string> customBannedWords, bool isAllCustom = false, InputSizeLimit sizeLimit = Standard);
string Firewall.Redact(string input);

IFirewallService (DI interface)

void   Validate(string input, InputSizeLimit sizeLimit = InputSizeLimit.Standard);
void   Validate(string input, AgentType agentType, InputSizeLimit sizeLimit = InputSizeLimit.Standard);
void   Validate(string input, IEnumerable<string> customBannedWords, bool isAllCustom = false, InputSizeLimit sizeLimit = InputSizeLimit.Standard);
void   Validate(string input, AgentType agentType, IEnumerable<string> customBannedWords, bool isAllCustom = false, InputSizeLimit sizeLimit = InputSizeLimit.Standard);
string Redact  (string input);

Both Validate overloads throw System.Security.SecurityException on any detected threat. Redact never throws.


AgentType Enum

Pass an AgentType to layer domain-specific patterns on top of the global blocklist.

Value Domain Extra patterns block
General (default) Global blocklist only
AppointmentBooker Calendar Bulk export/cancel, cross-user access
EmailSender Email Mass send, BCC exfiltration, inbox forwarding
PaymentProcessor Payments Unauthorized transfers, fraud-check bypass
CustomerSupport CRM Data dumps, impersonation, mass account changes
DataAnalyst Data / SQL DROP/TRUNCATE, raw dumps, permission escalation
CodeAssistant Code Malware, exploit generation, offensive scripts
ContentModerator Moderation Filter bypass, force-approve harmful content
HRAssistant HR Salary/PII exfil, disciplinary record access
MedicalAssistant Healthcare Patient record dumps, unauthorized prescribing
LegalAssistant Legal Privileged communication leak, case file exfil

Custom Banned Words

Pass any IEnumerable<string> of application-specific terms to block content that is safe in general but forbidden for your particular product — competitor names, internal project codes, legally sensitive phrases, etc.

Every term in the custom list is normalized through the same pipeline as user input, so leet-speak, homoglyph substitution, invisible characters, and base64 obfuscation are all neutralized before the match.

Global check + custom words

string[] banned = ["competitor", "lawsuit", "confidential"];

firewall.Validate(userInput, banned);
// or static façade:
Firewall.Validate(userInput, banned);

Agent-specific check + custom words

firewall.Validate(userInput, AgentType.CustomerSupport, banned);
// or static façade:
Firewall.Validate(userInput, AgentType.CustomerSupport, banned);

All three layers are evaluated in order:

  1. Size check — rejects oversized input immediately
  2. Global blocklist — prompt injection, jailbreak, credential fishing, etc.
  3. Agent-specific blocklist — domain patterns for the chosen AgentType
  4. Custom banned words — your application-defined list

A SecurityException is thrown at the first failing layer.

// Example: block mentions of competitor brands in a support bot
string[] brandPolicy = ["AcmeCorp", "RivalSaaS", "OtherVendor"];

app.MapPost("/api/chat", (ChatRequest req, IFirewallService firewall) =>
{
    firewall.Validate(req.Message, AgentType.CustomerSupport, brandPolicy);
    // ...
});

Obfuscation resistancec0mp3t1t0r (leet), соmpetitor (Cyrillic 'с'), and com​petitor (zero-width space) all normalize to competitor before the match, so users cannot bypass the list through encoding tricks.

isAllCustom — full control mode

Set isAllCustom: true to skip the built-in global and agent-specific blocklists entirely and only enforce your custom list (the size limit still applies). This is ideal for validating LLM responses, where the global blocklist contains common English words like "system", "run", "delete" that would cause false positives in natural-language output.

// Validate the LLM response with only response-specific banned terms
string[] responsePolicy = ["jailbreak", "ignore previous", "[INST]", "<|im_start|>"];

firewall.Validate(llmResponse, responsePolicy, isAllCustom: true);
isAllCustom Global blocklist Agent blocklist Custom list Size limit
false (default) Checked Checked Checked Checked
true Skipped Skipped Checked Checked

InputSizeLimit Enum

The enum value is the character limit — no lookup table needed.

Value Chars Use when
Simple 250 Tightly constrained chatbot commands
Standard (default) 1 024 Chat messages, short queries
Extended 8 192 Emails, support tickets, code snippets
Large 32 768 Full documents, large code files

Oversized inputs are rejected before normalization, so the check is always cheap.


Normalization Pipeline

Every input is canonicalized before hitting the blocklist, preventing evasion through encoding tricks.

Raw input
   │
   ├─ 1. Strip zero-width, invisible, and Bidi-override characters
   │       (zero-width spaces, RLO/LRO/PDF, LRM/RLM, Bidi isolates…)
   │
   ├─ 2. Decode base64 segments (20+ consecutive base64 chars)
   │       "aWdub3JlIHByZXZpb3Vz" → "ignore previous"
   │
   ├─ 3. Homoglyph substitution + lowercase
   │       Cyrillic 'а' → 'a', Greek 'ο' → 'o', accented chars, etc.
   │
   └─ 4. Leet-speak substitution
           '0'→'o', '1'→'i', '3'→'e', '@'→'a', '$'→'s', …

The same pipeline runs on every blocklist term at startup, so 1gn0r3 pr3v10us still matches ignore previous.


Security Notes

  • Role/delimiter injection — tokens like [INST], <|im_start|>, <<SYS>>, <human>, and ### Assistant are blocked because legitimate user input never contains LLM-internal boundary markers.
  • Bidi override characters (U+202A–U+202E, U+2066–U+2069) are stripped unconditionally — they can reverse text rendering while the raw bytes still reach the model unchanged.
  • Pattern matching uses Aho-Corasick — O(n) in input length with no backtracking, immune to ReDoS.
  • Validate throws rather than returning bool — a missed if check cannot silently allow bad input through.
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 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. 
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.

Version Downloads Last Updated
1.0.2 97 4/11/2026
1.0.1 85 4/11/2026
1.0.0 85 4/11/2026