Skip to main content

One policy layer for every AI model.

Protect prompts, model responses, tool calls, retrieval content, logs, tickets and traces with provider-neutral privacy and AI governance controls for .NET.

  • Provider-neutral
PowerShell
dotnet add package LLMPolicyMesh --version 0.6.0-beta.3

The trust boundary

Application

Owns clients and storage

LLMPolicyMesh

  • Inspect
  • Redact
  • Limit
  • Route
  • Audit

Any AI model

Any provider or endpoint

One immutable policy snapshot is resolved per logical operation and applied to the primary attempt and to every permitted retry or fallback.

The operating problem

Everything that reaches a model is untrusted, and everything that leaves one is too.

Prompts, support tickets, logs, traces, retrieved documents, model responses and tool results can all carry personal data, credentials or attacker-controlled instructions. Meanwhile model SDKs expose different request schemas, and enterprise controls need to behave the same way across all of them.

Untrusted AI traffic

  • Prompts and support tickets
  • Tool results
  • Retrieved documents
  • Model output
  • Logs and traces

Any of which can contain:

  • PII
  • Secrets
  • Credentials
  • Prompt injection
  • Encoded evasions
  • Unsafe tool arguments
  • Indirect instructions
  • Unbounded model costs

Enterprise requirements

  • Privacy
  • Security
  • Cost control
  • Auditability
  • Provider independence

Retries and fallbacks can multiply cost or bypass tenant budgets unless every attempt shares one logical policy and accounting boundary. Audit destinations need sanitized evidence without forcing a specific database, logging framework or cloud service on every consumer.


One governed access layer for every model

Use commercial, cloud-hosted, local, self-hosted or custom AI models through one provider-neutral policy boundary. If your application can reach a model through a compatible client or HTTP endpoint, LLMPolicyMesh can govern what enters and leaves that interaction.

Provider freedom without fragmented controls

  • Protect provider clients through standard .NET AI integration
  • Govern vendor-specific and custom HTTP payloads
  • Apply consistent policy across primary and fallback models
  • Keep credentials, endpoints and provider choice under application control
  • Change providers without rebuilding the governance layer

How it works

Three stages, one policy boundary

The gateway resolves one immutable policy snapshot for a logical operation, then applies the same protection across the primary attempt and every permitted retry or fallback.

  1. Untrusted input

    Prompts, retrieved chunks, tools, logs, tickets and model payloads enter the policy boundary.

  2. Policy mesh

    LLMPolicyMesh applies, in order:

    • Input limits
    • PII and secret detection
    • Redaction
    • Prompt-injection inspection
    • Retrieval validation
    • Tool policies
    • Budget reservation
    • Retry and routing policy
    • Audit and telemetry
  3. Controlled output

    Only protected requests and sanitized responses are released. Limits, tool policy, optional injection analysis, custom rules and privacy redaction are reapplied on the way back.

The logical request sequence

The ten enforcement steps applied to a single logical model request.
StepStageEnforcement
1Select policyUse the default, an explicit named policy, or content-free tenant selection.
2Bound inputEnforce input bytes, characters, messages, content items and optional application token counts.
3Inspect toolsValidate declarations, explicit choices, call counts, arguments and tool results.
4Inspect normalized viewDecode supported evasions for inspection only; outbound content is never replaced by decoded text.
5Protect privacyApply application PII/NER, custom rules and built-in structured redaction before dispatch.
6Price and reserveResolve price, enforce per-request cost and reserve tenant capacity atomically.
7DispatchSend through the application-owned HttpClient or IChatClient and emit sanitized operational evidence.
8SettleUse provider usage or conservative bounded estimates; ambiguous failures are charged according to configured policy.
9Protect outputReapply limits, tool policy, optional injection analysis, custom rules and privacy redaction.
10Return safelyAudit the outcome and release only protected response content.

Six control planes

  • Privacy — detect and transform PII and secrets across text, structured payloads, logs, requests, responses and streams.
  • Policy — normalize inspection copies, detect injection and evasion patterns, protect retrieval chunks, enforce limits, run application rules.
  • Tool security — allow or deny tools, constrain arguments, inspect encoded values, sanitize indirect instructions.
  • Economics — price requests, enforce maximum spend, reserve tenant budgets atomically, settle from actual or conservative usage.
  • Resilience — bounded retry, timeout, circuit breaker and explicit fallback routes without weakening policy.
  • Evidence — sanitized audit records, privacy-safe telemetry and optional tamper-evident ledgers.

Core capabilities

Eighteen controls, one consolidated package

All shipping functionality is delivered as a single NuGet package. There are no separate privacy, gateway, audit, logging, HTTP or ASP.NET integration packages to discover and keep in step.

Implemented in reviewed source

PII and secret protection

Detection and redaction across identity, financial, network and credential data, with configurable precision and optional country coverage.

Learn more about the privacy engine

Prompt-injection and evasion inspection

Bounded multi-pass normalization creates inspection variants for Unicode tricks, invisible characters, encodings and reversed text. Variants are inspected, never substituted.

Retrieval and RAG guardrails

Shape validation, chunk bounds and score policy for retrieved content. Malformed score shapes and duplicate properties fail closed.

Learn more about retrieval checks

Tool allow/deny policy

Deny rules override allow rules. Unlisted tools can be rejected outright, and declarations and calls are count-bounded.

Tool-result protection

Per-tool risk levels drive indirect-instruction inspection, with reject, sanitize or replace outcomes.

Request and tenant budgets

Atomic reservations compare committed plus outstanding cost against hourly, daily or monthly UTC limits.

Learn more about budgets

Retry and fallback routing

Only configured transient statuses, transport failures, attempt timeouts and classified exceptions are retried. Each fallback route gets full policy.

Circuit breaking and timeouts

Endpoint-local closed, open and half-open states prevent work and spending on known-open routes. Attempt and total timeouts are bounded.

Safe streaming redaction

Complete logical output is buffered, bounded and redacted before release, so a sensitive value split across chunks cannot leak early.

Sanitized auditing

Gateway and HTTP-handler factories place the package sanitizer before your sinks, so evidence never becomes a second privacy leak.

Learn more about auditing

Microsoft logging

A privacy-safe ILogger wrapper redacts formatted messages, structured values, scopes and exception text.

ASP.NET Core middleware

Incoming request and outgoing response bodies are protected through the shared framework. Available on net8.0.

Outbound HTTP handler

A DelegatingHandler protects arbitrary textual outbound HTTP request and response bodies.

Microsoft.Extensions.AI integration

Wrap any application-created IChatClient to protect messages, instructions, functions, results, responses and streaming updates.

Learn more about model access

Custom policy rules

Ordered input and output policy rules with predicate validation enforce application-specific contracts.

Named tenant policies

Immutable policy snapshots can be selected explicitly or through content-free tenant metadata.

Remote and local PII analyzer contracts

Public contracts for remote PII analyzers, prompt-injection analyzers, selectors and token counters, with thresholds and explicit fail-open or fail-closed behaviour.

Privacy-safe telemetry

ActivitySource and Meter emit policy and rule outcomes, latency and counts without payload content.

Privacy engine

PII and secret protection before data reaches the model

The privacy subsystem is designed for ordinary text and structured payloads alike, with configurable precision, opt-in country packs and both reversible and irreversible operators.

Implemented coverage

Identity and contact

  • Internationalized email
  • Phone numbers
  • Addresses
  • Dates of birth
  • Passports
  • Driving licences
  • National identifiers
  • Tax identifiers

Financial

  • Validated payment cards
  • Country-aware IBAN
  • SWIFT/BIC
  • Bank context
  • Crypto address shapes

Network and device

  • IPv4
  • IPv6
  • URLs
  • MAC addresses

Credentials and secrets

  • Private keys
  • JWT
  • Bearer tokens
  • AWS
  • GitHub
  • Slack
  • Google
  • Stripe
  • SendGrid
  • Azure Storage

Country packs

Generic and US coverage is always available. The United Kingdom, Germany, India, Italy and Spain packs are opt-in.

  • Generic
  • US
  • UK
  • Germany
  • India
  • Italy
  • Spain

Transformations

  • Replace — substitute a redaction token.
  • Remove — drop the value entirely.
  • Mask — preserve edges for readability.
  • Deterministic HMAC — keyed, stable pseudonyms for joins.
  • Authenticated reversible encryption — recover the original later.
  • Keep — deliberately retain a matched value.
  • Application-defined operators — your own transformation.

Granular entity configuration takes precedence over broad compatibility categories.

Precision controls

  • Checksum and structural validation
  • Bounded context scoring
  • Exact exclusions and entity/rule exclusions
  • Confidence thresholds
  • Custom regex and national-ID definitions

Not claimed

Malformed structured input, invalid analyzer spans, overlapping results, unsafe exclusions and configured limit violations are designed to fail safely. The package does not claim that a finite recognizer set can identify every future identifier or credential format.


Structured payloads, not just prose

Protection is content-aware, so redaction survives serialization. The same engine covers property names, numeric JSON values, exact RFC 6901 paths and subtrees, and streamed content.

  • Plain text
  • JSON
  • NDJSON
  • XML
  • URL-encoded forms
  • CSV
  • Objects to safe JSON
  • Property names
  • Numeric JSON values
  • RFC 6901 paths
  • RFC 6901 subtrees
  • Streaming content
C# — opt in to a country pack, override one operator
var options = new PiiRedactionOptions();

// Opt in to a country pack and override one entity's operator.
using var nationalIdMask = PiiOperator.Mask(
    '*', preserveSuffixLength: 2);
options.Operators[PiiEntityType.NationalIdentifier] = nationalIdMask;

var redactor = LLMPolicyMeshPrivacy.CreateRedactor(
    PiiCountryPack.UnitedKingdom);
PiiRedactionResult result = redactor.Redact(payload, options);
C# — redact a streamed response before release
await foreach (string safeChunk in
    LLMPolicyMeshApi.RedactStreamAsync(modelChunks))
{
    await response.WriteAsync(safeChunk);
}

Model access

Use any model client. Apply one policy boundary.

Consumers can govern opaque HTTP model traffic or any Microsoft.Extensions.AI IChatClient without introducing a model-provider dependency into LLMPolicyMesh.

Microsoft.Extensions.AI

The application creates any provider client implementing IChatClient, and LLMPolicyMesh wraps it. The wrapper owns and disposes the supplied client; credentials and provider configuration stay application concerns.

Opaque HTTP gateway

The application provides the endpoint, authentication, HTTP client and provider payload. LLMPolicyMesh carries an opaque payload rather than forcing provider-specific request classes on you.

Examples

C#
// The application creates its own provider client.
IChatClient provider = CreateApplicationModelClient();

var policy = new LLMPolicyMeshOptions();
policy.PromptInjection.Enabled = true;

// A policy wrapper, not a provider client factory.
using IChatClient protectedClient =
    LLMPolicyMeshApi.ProtectChatClient(provider, policy);
C#
// You own the endpoint, authentication, HttpClient and the provider's own
// JSON payload. LLMPolicyMesh carries that payload as opaque content.
var policy = new LLMPolicyMeshOptions();
policy.PromptInjection.Enabled = true;

HttpClient httpClient = CreateApplicationHttpClient();
ILLMPolicyGateway gateway =
    LLMPolicyMeshApi.CreateGateway(httpClient, policy);

// LLMEndpoint carries validated endpoint metadata.
// LLMRequest carries the opaque provider payload.
LLMEndpoint endpoint = BuildApplicationEndpoint();
LLMRequest request = BuildProviderPayload(endpoint, prompt);

LLMResponse response = await gateway.SendAsync(request, cancellationToken);
LLMUsage usage = response.Usage;
C#
var policy = new LLMPolicyMeshOptions();
policy.Resilience.Enabled = true;
policy.Resilience.MaximumAttemptsPerRoute = 2;
policy.Resilience.MaximumTotalAttempts = 4;
policy.Resilience.AttemptTimeout = TimeSpan.FromSeconds(20);
policy.Resilience.TotalTimeout = TimeSpan.FromSeconds(60);

// Every ordered client receives the complete policy boundary.
using IChatClient protectedClient =
    LLMPolicyMeshApi.ProtectChatClient(
        new[]
        {
            new LLMChatClientRoute("primary", primaryClient),
            new LLMChatClientRoute("fallback", fallbackClient),
        },
        policy);
C#
// Named policies are immutable at gateway creation and may be selected
// explicitly or through content-free metadata.
LLMNamedPolicy regulated = LLMPolicyMeshApi.CreateNamedPolicy(
    "regulated",
    policy =>
    {
        policy.PromptInjection.Enabled = true;
        policy.Retrieval.Enabled = true;
        policy.Limits.Enabled = true;
        policy.Limits.MaximumInputTokens = 8_000;
    });

ILLMPolicyGateway gateway = LLMPolicyMeshApi.CreateGateway(
    httpClient,
    namedPolicies: new[] { regulated });

// LLMRequest can select it with policyName: "regulated".

These examples demonstrate public package usage. Confirm exact member signatures, overloads and configuration requirements against the published API documentation before copying them into production code.

Security

Tools and retrieved content are separate security surfaces

The policy engine treats model input, model output, retrieval content and tool results as potentially hostile, while remaining independent of any provider schema.

Tool security

  • Allow and deny rules
  • Deny precedence over allow
  • Declaration filtering
  • Required tool choices
  • Call limits
  • Duplicate JSON property rejection
  • Nested argument inspection
  • Encoded argument inspection
  • Destructive operation checks
  • Per-tool constraints
  • Risk-based tool-result sanitization

Defence-in-depth checks cover destructive SQL, commands, traversal, scripts, templates and unsafe network targets. Exact values, maximum lengths, URL hosts, required properties and custom rules can be applied per tool.

Retrieval and RAG

  • Retrieval array validation
  • Chunk limits
  • Relevance score requirements
  • Finite numeric score enforcement
  • Property and nested string inspection
  • Unsafe chunk rejection
  • Remove or replace actions
  • Prompt-injection checks inside retrieved content

Recognized collections must be arrays. Duplicate properties and malformed score shapes fail closed. Present scores must be unique, numeric, finite and above the configured minimum. An unsafe chunk can be replaced in full, so attacker fragments cannot survive.

Configure each security surface explicitly

C# — allow only approved tools and sanitize tool results
var policy = new LLMPolicyMeshOptions();
policy.Tools.Enabled = true;
policy.Tools.DenyUnlistedTools = true;
policy.Tools.AllowedTools.Add("search_*");
policy.Tools.AllowedTools.Add("read_ticket");
policy.Tools.DeniedTools.Add("*_admin");
policy.Tools.ToolResults.Action = ToolResultPolicyAction.Sanitize;

using IChatClient protectedClient =
    LLMPolicyMeshApi.ProtectChatClient(provider, policy);
C# — filter unsafe or low-relevance retrieval chunks
var policy = new LLMPolicyMeshOptions();
policy.PromptInjection.Enabled = true;
policy.Retrieval.Enabled = true;
policy.Retrieval.Action = RetrievalPolicyAction.Remove;
policy.Retrieval.MaximumChunks = 12;
policy.Retrieval.MinimumRelevanceScore = 0.55;
policy.Retrieval.RequireRelevanceScore = true;

ILLMPolicyGateway gateway =
    LLMPolicyMeshApi.CreateGateway(httpClient, policy);

Inspection-only normalization

Bounded multi-pass normalization creates additional inspection variants for Unicode tricks, invisible characters, hexadecimal, percent encoding, Base64 and Base64url, JSON escapes and reversed text.

These variants are inspected but never substituted into the outbound payload.

Threat-model limit

Deterministic rules reduce common injection and evasion risk. They do not prove arbitrary natural-language content safe. High-assurance deployments should combine this layer with least-privilege tools, retrieval provenance, application authorization and an independently evaluated semantic classifier. Tool policy also does not replace safe tool implementation: parameterized queries, process isolation, canonical path validation, egress controls and least-privilege credentials remain your responsibility.

Economics and resilience

Retries and fallbacks share one logical request boundary

Cost and resilience are governed together, so transient failures and fallback routes cannot silently bypass spending policy.

Request lifecycle

  1. Resolve price

    Application-owned, asynchronous, provider-neutral pricing. Missing or failed resolution is fail-closed.

  2. Estimate protected request

    Protected input plus declared maximum output tokens are priced before provider dispatch.

  3. Enforce request limit

    The maximum cost per request is applied to the estimate.

  4. Reserve tenant budget

    Atomic reservations compare committed plus outstanding cost against hourly, daily or monthly UTC limits.

  5. Dispatch attempt

    Sent through your own HttpClient or IChatClient, with sanitized operational evidence emitted.

  6. Settle actual or conservative cost

    Actual usage replaces estimates. Indeterminate attempts can commit the estimate, so a failed attempt plus a retry cannot hide spend.

Economic controls

  • Maximum cost per request
  • Maximum cost per tenant
  • Hourly, daily and monthly periods
  • Application-owned price provider
  • Application-owned distributed store
  • Bounded process-local store

Resilience controls

  • Retry classification
  • Attempt and total timeouts
  • Retry-After support
  • Endpoint-local circuit breaker
  • Ordered fallback routes
  • Idempotency protection

Application-owned

No database required

A bounded process-local budget store is available for a single application instance. Multi-process durability and atomicity belong to an application implementation of the public budget-store contract. LLMPolicyMesh does not require Redis, SQL Server, SQLite, PostgreSQL or any other database provider.

C# — enforce spend and retry limits together
var policy = new LLMPolicyMeshOptions();

policy.Budget.Enabled = true;
policy.Budget.MaximumCostPerRequestUsd = 0.25m;
policy.Budget.MaximumCostPerTenantUsd = 40m;
policy.Budget.TenantPeriod = LLMBudgetPeriod.Daily;
policy.Budget.PriceProvider = applicationPriceProvider;
policy.Budget.Store = applicationBudgetStore;

policy.Resilience.Enabled = true;
policy.Resilience.MaximumAttemptsPerRoute = 2;
policy.Resilience.MaximumTotalAttempts = 4;
policy.Resilience.TotalTimeout = TimeSpan.FromSeconds(60);

Audit and observability

Evidence that does not become a second privacy leak

Built-in paths sanitize before forwarding, and telemetry keeps payload content out by default.

What the package constructs

  • Provider-neutral IAuditSink destination contract
  • Mandatory audit sanitization, placed before your sinks
  • Microsoft ILogger redaction of messages, structured values, scopes and exception text
  • Delegate, composite and JSON Lines sinks
  • Tamper-evident SHA-256 ledger over a record sequence
  • Optional application-keyed HMAC-SHA-256 ledger
  • Ledger verification that classifies malformed records, gaps, broken links, wrong keys, field ambiguity and incomplete final records
  • Privacy-safe ActivitySource
  • Privacy-safe Meter
  • Per-policy and per-rule outcomes and latency

Application-owned

You choose the destination

IAuditSink is a contract, not a storage engine. Point it anywhere:

  • Microsoft logging
  • SQLite
  • SQL Server
  • PostgreSQL
  • Cloud storage
  • SIEM
  • Custom application sink

Database libraries and schemas belong to the consuming application. Key rotation, retention, access control, durable flushing and backups do too. That is intentional: the package supplies safe contracts and evidence construction without pulling database providers or native binaries into every consumer.

C# — send sanitized audit events to Microsoft logging
IAuditSink audit =
    LLMPolicyMeshAudit.CreateLoggerSink(logger);

using IChatClient protectedClient =
    LLMPolicyMeshApi.ProtectChatClient(
        provider,
        policy,
        audit);

Framework integrations

The same policy core at every common .NET boundary

Functionality is not split across optional NuGet packages. Each surface below ships inside the one package.

Integration surfaces, their target frameworks and what each one protects.
Integration Target What it protects
Opaque HTTP gateway netstandard2.1 + net8.0 Provider request and response payloads, limits, tools, budgets, retry and fallback, audit.
Microsoft.Extensions.AI IChatClient netstandard2.1 + net8.0 Messages, instructions, functions, results, responses and streams.
ASP.NET Core middleware net8.0 Incoming request and outgoing response bodies through Microsoft.AspNetCore.App.
DelegatingHandler netstandard2.1 + net8.0 Arbitrary textual outbound HTTP request and response bodies.
Microsoft ILogger netstandard2.1 + net8.0 Formatted messages, state values, scopes and exceptions.
Dependency injection netstandard2.1 + net8.0 Registration of an application-owned HttpClient and the consolidated gateway API.
Streaming helper netstandard2.1 + net8.0 Buffer-before-release redaction of asynchronous text chunks.

ASP.NET Core is additive

The net8.0 target uses the Microsoft.AspNetCore.App shared framework for middleware. The netstandard2.1 asset stays free of that requirement and exposes the cross-platform provider-neutral core.

C# — ASP.NET Core registration
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddLLMPolicyMesh(
    services => services.GetRequiredService<HttpClient>(),
    options => options.PromptInjection.Enabled = true);

var app = builder.Build();

app.UseLLMPolicyMeshRedaction();
app.Run();

Ownership boundary

What the package enforces, and what stays yours

The design stays useful because it draws a hard line between reusable policy enforcement and environment-specific security ownership.

A row-by-row comparison of responsibilities enforced by LLMPolicyMesh against those owned by the consuming application.
LLMPolicyMesh enforces Your application owns
Privacy and policy orderingProvider credentials
Tool and retrieval controlsTool authorization and sandboxing
Budget contracts and validationDistributed durable storage
Sanitized audit constructionAudit destination and retention
Retry and fallback policyProvider SLA and endpoint access
Safe streamingEnd-user authorization

The application also keeps the concrete model client, endpoints, model selection, databases and distributed storage, logging providers, audit destinations, infrastructure and authorization. LLMPolicyMesh governs the interaction around those components.

Questions

Frequently asked questions

No. LLMPolicyMesh uses provider-neutral integration points and lets your application supply and configure the model client or endpoint.

Yes. There are two access paths. You can wrap any client implementing IChatClient, or you can use the opaque HTTP gateway, where your application chooses the provider JSON schema, endpoint, authentication and model. LLMPolicyMesh carries the payload rather than translating vendor protocols into a proprietary request object.

No. It does not store API keys, discover models, or translate every vendor protocol. Credentials, secret storage, endpoint authorization and provider SDK configuration remain application concerns.

No. A bounded process-local budget store is available for a single application instance. Multi-process durability and atomicity belong to your implementation of the public budget-store contract.

No. The core package does not require a database provider. Durable storage integrations remain an application choice.

Yes. IAuditSink is a provider-neutral destination contract, so you choose logging, a database, cloud storage or anything else. Delegate, composite and JSON Lines sinks ship with the package, and the sanitizer is placed before your sink. Destination, key storage and rotation, durable flush, access control, backups and retention are yours.

Yes. ASP.NET Core applications can apply policy-aware redaction to incoming request and outgoing response bodies.

Yes. The IChatClient wrapper protects messages, instructions, functions, results, responses and streaming updates. The protected wrapper owns and disposes the client you supply.

Yes. Declarations, explicit choices, calls, arguments and results are each inspected before use or release. Deny rules override allow rules, duplicate JSON properties are rejected, nested and JSON-encoded argument values are inspected, and per-tool risk levels drive indirect-instruction inspection with reject, sanitize or replace outcomes.

Tool policy does not replace safe tool implementation. Parameterized queries, process isolation, canonical path validation, network egress controls, least-privilege credentials and normal authorization are still yours.

Yes. Applications can add custom rules, conditional selection, external analysis and validation to enforce application-specific requirements.

Yes. Atomic reservations compare committed plus outstanding cost against hourly, daily or monthly UTC limits, and actual usage replaces estimates at settlement. Indeterminate provider attempts can commit the estimate, so a failed attempt plus a retry cannot hide spend. Pricing and the distributed atomic store are application-owned contracts.

No. It supplies technical controls that can support GDPR, CCPA and enterprise AI governance programs. Whether a deployment complies depends on configuration, lawful basis, data flows, retention, access controls, organizational procedures and jurisdiction-specific advice. No external regulatory or security certification is asserted.

The beta label indicates a pre-stable release whose public experience may continue to evolve based on compatibility feedback and production adoption.

Put one enforceable policy boundary around every model call.

Install the package, keep your own model client, and govern what crosses the boundary in both directions.

PowerShell
dotnet add package LLMPolicyMesh --version 0.6.0-beta.3