FluxGuard.Remote
0.17.0
dotnet add package FluxGuard.Remote --version 0.17.0
NuGet\Install-Package FluxGuard.Remote -Version 0.17.0
<PackageReference Include="FluxGuard.Remote" Version="0.17.0" />
<PackageVersion Include="FluxGuard.Remote" Version="0.17.0" />
<PackageReference Include="FluxGuard.Remote" />
paket add FluxGuard.Remote --version 0.17.0
#r "nuget: FluxGuard.Remote, 0.17.0"
#:package FluxGuard.Remote@0.17.0
#addin nuget:?package=FluxGuard.Remote&version=0.17.0
#tool nuget:?package=FluxGuard.Remote&version=0.17.0
FluxGuard
Secure by Default — Guardrails for LLM Applications.
Philosophy
FluxGuard is a guardrail library designed to accelerate secure LLM application development.
Core Principles
Secure by Default
- Protection starts immediately upon installation
- All core guards are enabled by default
- No unsafe defaults
Minimal Boilerplate
- Start with a single line
- Ready to use without complex configuration
- Sensible defaults even with many options
Full Customization
- Intercept at every decision point
- Modify behavior through hook system
- Completely override default policies
Local First
- 95%+ requests processed locally in <20ms
- Works without external services
- Remote is optional extension
Graceful Degradation
- Guard failures don't block requests (default)
- Remote timeouts fall back to local results
- All failure behaviors can be overridden
Installation
# This is all you need for most cases
dotnet add package FluxGuard
# For advanced analysis (LLM Judge, Semantic Cache)
dotnet add package FluxGuard.Remote
# For framework integrations (ASP.NET Core, Microsoft.Extensions.AI)
dotnet add package FluxGuard.SDK
Quick Start
// One line: the standard preset (the L1 pattern guards below)
var guard = FluxGuard.Create();
var inputCheck = await guard.CheckInputAsync(userMessage);
if (inputCheck.IsBlocked)
{
return inputCheck.BlockReason;
}
var response = await llm.CompleteAsync(userMessage);
var outputCheck = await guard.CheckOutputAsync(userMessage, response);
if (outputCheck.IsBlocked)
{
return outputCheck.BlockReason;
}
return response;
This alone provides (standard preset, L1):
- Prompt injection detection ✅
- Jailbreak attempt detection ✅
- Encoding bypass attack defense ✅
- PII exposure (input) / leakage (output) detection ✅
- Refusal detection on output ✅
- Input / output length limits (
MaxInputLength,MaxOutputLength; 128,000 characters by default) ✅
Not part of any preset: the L2 (local ML) guards and L3 (remote) guards are added explicitly — see Guard Layers.
Architecture
┌─────────────────────────────────────────────────────────────┐
│ FluxGuard (Core) │
├─────────────────────────────────────────────────────────────┤
│ │
│ INPUT ──▶ [L1: Regex] ──▶ [L2: Local ML] ──▶ DECISION │
│ <1ms 5-20ms │
│ │
│ OUTPUT ◀── [L1: Regex] ◀── [L2: Local ML] ◀── LLM │
│ │
└─────────────────────────────────────────────────────────────┘
│
▼ (Optional: FluxGuard.Remote)
┌─────────────────────────────────────────────────────────────┐
│ FluxGuard.Remote │
├─────────────────────────────────────────────────────────────┤
│ [L3: LLM Judge] ──▶ Semantic Analysis ──▶ Final Decision │
│ 50-200ms (on escalation) │
└─────────────────────────────────────────────────────────────┘
Guard Layers
| Layer | Location | Latency | Default |
|---|---|---|---|
| L1 | Local | <1ms | ✅ ON (presets register these) |
| L2 | Local | 5-20ms | ❌ OFF — no preset registers them; builder.AddL2Guards(sessionManager) adds them on top of the preset. They need an OnnxSessionManager and the model files, and the call throws if a file is missing |
| L3 | Remote | 50-200ms | ❌ OFF (opt-in) |
Guards
Input Guards
| Guard | Description | Layer | On by default |
|---|---|---|---|
PromptInjection |
Instruction override detection | L1 | ✅ EnablePromptInjection |
Jailbreak |
DAN, AIM persona attack blocking | L1 | ✅ EnableJailbreak |
EncodingBypass |
Base64, Unicode bypass detection | L1 | ✅ EnableEncodingBypass |
PIIExposure |
PII detection in input | L1 | ✅ EnablePIIExposure |
L2.PromptInjection |
ML prompt-injection classifier | L2 | ❌ AddL2Guards(...) |
Output Guards
| Guard | Description | Layer | On by default |
|---|---|---|---|
PIILeakage |
PII detection in the response (detects and blocks; it does not rewrite the response) | L1 | ✅ EnablePIILeakage |
Refusal |
Model refusal response detection | L1 | ✅ EnableRefusal |
L2.Toxicity |
ML toxicity classifier | L2 | ❌ AddL2Guards(...) |
Every guard is bounded by GuardTimeoutMs (5000 by default). A guard that throws or times out is a guard error:
skipped under FailMode.Open, blocking under FailMode.Closed.
Rate limiting is not part of this library; use the host's rate limiter (ASP.NET Core RateLimiter, or the gateway).
Groundedness / hallucination checks live in the FluxGuard.Remote package.
Configuration
Builder Pattern
var guard = FluxGuard.Create(builder => builder
.ApplyStandardPreset()
.ConfigureInputGuards(opt =>
{
// Longer inputs are blocked before any guard runs. 0 means no limit.
opt.MaxInputLength = 8192;
})
.ConfigureOutputGuards(opt =>
{
opt.MaxOutputLength = 4096;
}));
Presets
// Standard (default)
var guard = FluxGuard.Create();
var guard = FluxGuard.Create(b => b.WithPreset(GuardPreset.Standard));
// Strict - every standard guard with lower escalation thresholds; ApplyStrictPreset() also lowers
// the block / flag thresholds
var guard = FluxGuard.Create(b => b.ApplyStrictPreset());
// Minimal - prompt injection, jailbreak and PII leakage only, minimum latency
var guard = FluxGuard.Create(b => b.ApplyMinimalPreset());
Switches set with ConfigureInputGuards / ConfigureOutputGuards apply to the preset's guards whether they
are set before or after the preset is chosen.
Dependency Injection
// Default registration - Standard preset
services.AddFluxGuard();
// Custom configuration
services.AddFluxGuard(opt =>
{
opt.FailMode = FailMode.Open; // default for Minimal/Standard; Strict defaults to Closed
opt.GuardTimeoutMs = 2000; // how long the pipeline waits for one guard (default 5000)
});
// Log output follows the host's ILoggerFactory and its filters; the library has no log-level option of its own.
Remote Guard (Optional)
Add only when advanced analysis is needed.
dotnet add package FluxGuard.Remote
// OpenAI — model must be set explicitly (no default since 0.11.0)
IFluxGuard guard = FluxGuardBuilder.Create()
.WithRemoteGuard("your-openai-api-key")
.WithModel("gpt-4o-mini")
.WithTimeout(200) // the local verdict stands when the judge takes longer
.WithBlockThreshold(0.8) // default: an "unsafe" verdict under this confidence is reported, not blocked
.Build() // back to the FluxGuardBuilder
.Build();
// Bring your own IRemoteLlmService
IFluxGuard guard = FluxGuardBuilder.Create()
.WithRemoteGuard("unused")
.WithModel("my-model")
.WithCompletionService(myLlmService)
.Build()
.Build();
// DI (ASP.NET Core) — register remote separately
services.AddFluxGuard();
services.AddFluxGuardRemote("your-openai-api-key", opt =>
{
opt.Judge.Model = "gpt-4o-mini";
opt.TimeoutMs = 200;
});
Remote provides:
- LLM-as-Judge analysis of what the local guards escalate
- Caching of judge verdicts
- Hallucination / groundedness detection (L3)
A judge or detector that cannot answer is a guard error, so FailMode decides: passed under Open, blocked under
Closed.
MCP Guard (Optional)
Validates MCP (Model Context Protocol) tool calls and results — for applications that connect to
MCP servers and want tool-poisoning defenses on that channel. Nothing else in FluxGuard.Remote
registers or requires it.
// DI (ASP.NET Core)
services.AddFluxGuardMcpGuardrail();
// Manual construction
var guardrail = new MCPToolValidator();
guardrail.RegisterServer(new MCPServerInfo
{
Name = "my-mcp-server",
IsTrusted = true,
AllowedTools = ["read_file", "list_files"]
});
MCP Guard provides:
- Server/tool allowlisting (
ValidateToolCallAsync) - Dangerous-argument pattern detection (shell injection, path traversal, etc.)
- Indirect-injection and sensitive-data checks on tool results (
ValidateToolResultAsync) - Tool description integrity (
ValidateToolDescriptionsAsync, opt-in — passenableToolDescriptionIntegrityCheck: truetoAddFluxGuardMcpGuardrail()/MCPToolValidator's constructor): hashes each tool's description and input schema the first time a server is seen, then flags drift on every later call — catches an MCP server silently rewriting a trusted tool's behavior contract after the fact.
RAG Security Pipeline (Optional)
Validates documents retrieved by a RAG pipeline before they reach the LLM's context — for
applications indexing untrusted or third-party content that want indirect-prompt-injection
defenses on that channel. Nothing else in FluxGuard.Remote registers or requires it.
// DI (ASP.NET Core)
services.AddFluxGuardRagSecurity();
// Manual construction
var pipeline = new IndirectInjectionDetector();
var result = await pipeline.ValidateDocumentAsync(new RAGDocument
{
Content = retrievedText,
Source = "vector-store"
});
if (!result.IsSafe)
{
// result.Threats — detected indirect-injection patterns and their confidence
}
RAG Security Pipeline provides:
- Indirect prompt-injection detection in retrieved/ingested documents (
ValidateDocumentAsync/ValidateDocumentsAsync) — the same detectorMCP Guard'sValidateToolResultAsyncuses internally for tool results, exposed here for RAG retrieval content directly.
SDK Integration
For ASP.NET Core and Microsoft.Extensions.AI integration.
dotnet add package FluxGuard.SDK
ASP.NET Core Middleware
// Program.cs
builder.Services.AddFluxGuard();
builder.Services.AddFluxGuardMiddleware(o =>
{
o.ProtectedPaths.Add("/api/chat"); // none listed = every path
o.InputFieldName = "input"; // JSON field holding the text to check
o.MaxBodySize = 1024 * 1024; // default; a larger body gets 413 and is neither checked nor passed on
});
app.UseFluxGuard();
The middleware checks the body of POST / PUT / PATCH requests. A blocked request is answered with
BlockedStatusCode; a flagged one is passed on with X-FluxGuard-Flagged / X-FluxGuard-Score headers.
Microsoft.Extensions.AI
var chatClient = new ChatClientBuilder(innerClient)
.UseFluxGuard(new FluxGuardChatClientOptions
{
ValidateInput = true, // default
ValidateOutput = true, // default
ValidateStreamingOutput = true, // default false: streamed responses are not checked unless you turn this on
})
.Build(serviceProvider); // resolves IFluxGuard from DI
A blocked request or response throws FluxGuardChatBlockedException (its Result is the GuardResult). A streamed
response is checked once, on the whole text, when the stream ends: the updates have already been forwarded, so the
exception arrives after the last one and is the caller's signal to retract what it showed.
Hooks & Customization
Intercept at every decision point.
var guard = FluxGuard.Create(builder => builder.WithHooks(hooks => hooks
// Return false to skip the check entirely
.OnBeforeCheck(ctx => ValueTask.FromResult(true))
.OnAfterCheck((ctx, result) => { /* audit */ return ValueTask.CompletedTask; })
.OnBlocked(async (ctx, result) => await alertService.NotifyAsync(result))
.OnPassed((ctx, result) => ValueTask.CompletedTask)
.OnFlagged((ctx, result) => ValueTask.CompletedTask)
// Override the verdict: null keeps it, AllowPass / ForceBlock replace it
.OnCustomDecision((ctx, result) => ValueTask.FromResult(
ctx.UserId == "admin" ? FailDecision.AllowPass("admin bypass") : null))
// A guard threw or timed out: Continue applies FailMode, AllowPass / ForceBlock decide here
.OnGuardError((ctx, guardName, ex) => ValueTask.FromResult(FailDecision.Continue))));
For the escalation hooks (OnBeforeEscalationAsync, OnEscalationTimeoutAsync) implement IFluxGuardHooks, or
derive from FluxGuardHooks and override what you need, and pass it to WithHooks(...).
Fail Mode
services.AddFluxGuard(opt =>
{
// What a guard that throws or times out means
opt.FailMode = FailMode.Open; // skip that guard (availability first)
opt.FailMode = FailMode.Closed; // block the request (security first)
});
This holds for every guard, the L2 and L3 guards included: a guard that cannot run reports an error and the fail
mode decides. For per-error control use the OnGuardError hook above.
When you don't set FailMode, it is derived from the preset (since 0.12.0):
| Preset | Fail mode when unset |
|---|---|
Minimal |
Open |
Standard (default) |
Open |
Strict |
Closed |
Choosing Strict states "security over availability", so the fail mode follows that intent.
An explicit assignment always wins, in either direction and whatever order it is set in:
// Strict, but keep availability first
FluxGuard.Create(b => b.WithPreset(GuardPreset.Strict).WithFailMode(FailMode.Open));
Security note — outside
Strict, the default is fail-open. WithFailMode.Open, a guard that throws (e.g. a regex match timeout on a very long input) is logged as a warning and skipped: that request passes without that guard's verdict. This is the right default for observe-only deployments, but once you enforce guard verdicts (blocking requests on detection), useStrictor setFailMode.Closed— otherwise an input engineered to make one guard fail silently bypasses it. Guard regexes carry a 1s match timeout as a hard upper bound; every bundled pattern is backtracking-safe, so hitting it indicates extreme input size or severe host contention.
Internationalization
The PII guards load pattern sets by language. SupportedLanguages selects which sets are loaded; the generic
patterns (email, credit card, API keys, ...) are always on.
| Code | Pattern set |
|---|---|
en |
US (SSN, phone, ...) |
ko |
Korean (resident registration number, phone, credentials, ...) |
ja |
Japanese (My Number, phone, ...) |
var guard = FluxGuard.Create(builder => builder
.ConfigureInputGuards(o => o.SupportedLanguages = ["ko", "en"])); // default: every code
The other guards are not filtered by this list.
Custom Guards
A custom rule is a guard: implement IInputGuard (or IOutputGuard) and add it. Adding a guard does not replace the
preset when you also name one.
public sealed class CompetitorGuard : IInputGuard
{
public string Name => "Competitor";
public string Layer => "L1";
public bool IsEnabled => true;
public int Order => 200;
public ValueTask<GuardCheckResult> CheckAsync(GuardContext context) =>
ValueTask.FromResult(context.NormalizedInput.Contains("competitor1", StringComparison.OrdinalIgnoreCase)
? new GuardCheckResult { GuardName = Name, Passed = false, Score = 0.9, Severity = Severity.High, Details = "competitor mention" }
: GuardCheckResult.Safe);
}
var guard = FluxGuard.Create(builder => builder
.WithPreset(GuardPreset.Standard)
.AddInputGuard(new CompetitorGuard()));
Logging & Statistics
Logging goes through the ILoggerFactory you pass (WithLogging(loggerFactory), or the container's with
AddFluxGuard). Blocks and guard errors are warnings or errors; the rest is debug.
Statistics are recorded when you hand the pipeline a collector. Without one, nothing is recorded.
var stats = new InMemoryStatsCollector(); // or FluxGuardMetrics: System.Diagnostics.Metrics, meter "FluxGuard"
var guard = FluxGuard.Create(builder => builder.WithStats(stats));
var snapshot = stats.GetStats();
Console.WriteLine($"Total: {snapshot.TotalChecks}, blocked: {snapshot.BlockedCount} ({snapshot.BlockRate:P1})");
Console.WriteLine($"Avg latency: {snapshot.AverageLatencyMs:F1} ms, guard errors: {snapshot.ErrorCount}");
With AddFluxGuard(...), register an IGuardStatsCollector in the container and the pipeline picks it up.
Configuration File
{
"FluxGuard": {
"Preset": "Standard",
"FailMode": "Open",
"GuardTimeoutMs": 5000,
"InputGuards": {
"EnablePromptInjection": true,
"EnableJailbreak": true,
"EnableEncodingBypass": true,
"EnablePIIExposure": true,
"MaxInputLength": 8192
},
"OutputGuards": {
"EnablePIILeakage": true,
"EnableRefusal": true,
"MaxOutputLength": 4096
}
}
}
services.AddFluxGuard(configuration) binds the FluxGuard section to FluxGuardOptions, so the keys are that
type's property names.
Performance
No benchmark ships with this repository, so this README states no latency or throughput figures. The numbers that used to sit here were design targets from docs/ROADMAP.md, and they were never measured. What is true of the shape: the L1 guards are regex and string work in process, L2 runs an ONNX model per check, and L3 makes a network call to a model provider — so the three layers differ by orders of magnitude, and only L1 is in every preset.
Packages
| Package | Description | Dependencies |
|---|---|---|
FluxGuard |
L1 guardrails (all presets) and the L2 ONNX guards (opt-in via AddL2Guards) |
ONNX Runtime |
FluxGuard.Remote |
Remote analysis (L3) | FluxGuard, HTTP |
FluxGuard.SDK |
Framework integrations | FluxGuard, ASP.NET Core, MEAI |
The L2 guards live in the FluxGuard package but no preset registers them — they need model
files on disk, so they are an explicit builder.AddL2Guards(sessionManager) call.
License
MIT License - see LICENSE for details.
| Product | Versions 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. |
-
net10.0
- FluxGuard (>= 0.17.0)
- Microsoft.Extensions.Http (>= 10.0.12)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.12)
- Microsoft.Extensions.Options (>= 10.0.12)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on FluxGuard.Remote:
| Package | Downloads |
|---|---|
|
FluxIndex.SDK
FluxIndex SDK - RAG orchestration core (context, indexer, retriever, DI helpers). Storage and pipeline integrations ship as separate FluxIndex.Storage.* / FluxIndex.Integrations.* packages. |
|
|
FluxFeed
FluxFeed - document pipeline surface (ingest/parse/clean) feeding FluxIndex. File-source vault with git-like tracking and real-time folder monitoring. |
|
|
IronHive.Agent.FluxGuard
IronHive Agent - FluxGuard-backed tool guards: an IMcpToolCallGuard for MCP tool calls and an IToolResultGuard for in-process tool results, over one FluxGuard IMCPGuardrail |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.17.0 | 3,010 | 9/20/2026 |
| 0.16.0 | 420 | 9/20/2026 |
| 0.15.1 | 1,517 | 9/17/2026 |
| 0.15.0 | 538 | 9/16/2026 |
| 0.14.2 | 369 | 9/16/2026 |
| 0.14.1 | 5,391 | 8/31/2026 |
| 0.14.0 | 110 | 8/28/2026 |
| 0.13.0 | 399 | 8/27/2026 |
| 0.12.0 | 135 | 7/28/2026 |
| 0.11.2 | 129 | 7/21/2026 |
| 0.11.1 | 241 | 5/15/2026 |
| 0.11.0 | 211 | 3/20/2026 |
| 0.10.2 | 158 | 2/23/2026 |
| 0.10.1 | 88 | 2/20/2026 |
| 0.10.0 | 103 | 1/31/2026 |
| 0.3.0 | 105 | 1/31/2026 |