LLMPolicyMesh 0.6.0-beta.3

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

LLMPolicyMesh

Programmable, provider-neutral AI guardrails for .NET

Provider-neutral Docker tested Website

LLMPolicyMesh brings programmable AI guardrails to .NET in the spirit of NeMo Guardrails and Guardrails AI—while unifying privacy protection, prompt-injection defense, tool and RAG security, budget enforcement, resilience, safe streaming, and auditability across any reachable AI model.

Use one policy layer with an application-owned Microsoft.Extensions.AI IChatClient or with any HTTP-accessible model endpoint. Your application keeps control of model clients, credentials, provider payloads, storage, keys, and deployment choices.

Install

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

Quick start

Create the provider client in your application, configure the policies you need, and wrap it:

using LLMPolicyMesh;
using LLMPolicyMesh.Configuration;
using Microsoft.Extensions.AI;

IChatClient providerClient = CreateApplicationModelClient();

var policy = new LLMPolicyMeshOptions();
policy.PromptInjection.Enabled = true;
policy.Tools.Enabled = true;
policy.Tools.DenyUnlistedTools = true;
policy.Tools.AllowedTools.Add("search_*");

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

ChatResponse response = await protectedClient.GetResponseAsync(
    "Contact jane@example.com about this ticket.");

The protected client applies configured policy to requests, responses, tool data, and streaming output. It owns and disposes the wrapped client.

What the package covers

Capability Consumer-facing support
Privacy Offline PII and secret detection, regional identifier packs, precision controls, custom detectors, replacement, removal, masking, HMAC, encryption, and reversible de-identification
Structured data Text, JSON, NDJSON, XML, form-urlencoded, CSV, CLR-object-to-JSON, and batch redaction
Model access Protected IChatClient, opaque HTTP gateway, dependency injection, and provider-neutral request/response contracts
Prompt security Inspection-only normalization, deterministic prompt-injection detection, response inspection, custom indicators, and application-owned semantic analyzers
Tool security Tool allow/deny rules, declaration policy, argument inspection, URL/schema constraints, tool-call limits, and indirect-injection protection for tool results
Retrieval security RAG chunk limits, relevance thresholds, schema mapping, prompt-injection inspection, sensitive-data inspection, removal, rejection, and sanitization
Policy Input/output limits, exact application token counters, ordered custom rules, payload modification or denial, and named policies selected from content-free metadata
Economic controls Per-request and per-tenant USD limits, application pricing, conservative reservations, usage settlement, and pluggable atomic stores
Resilience Bounded retry, timeout, Retry-After, circuit breaking, ordered fallback routes, and tool-request retry safety
Streaming Buffer-before-release redaction with byte, chunk, output, and content-type bounds
Audit and observability Sanitized sinks, Microsoft logging protection, JSON-lines output, tamper-evident ledgers, ActivitySource, Meter, and provider usage adapters
Web integration Redacting HttpMessageHandler and ASP.NET Core request/response middleware

Consumer examples

Each capability below has two public-API usage examples. Placeholder objects such as providerClient, httpClient, applicationNerAnalyzer, and applicationBudgetStore are supplied by the consuming application.

The examples use these common namespaces as needed:

using LLMPolicyMesh;
using LLMPolicyMesh.Abstractions.Audit;
using LLMPolicyMesh.Abstractions.Gateway;
using LLMPolicyMesh.Audit;
using LLMPolicyMesh.Budgets;
using LLMPolicyMesh.Configuration;
using LLMPolicyMesh.Policies;
using LLMPolicyMesh.Privacy;
using LLMPolicyMesh.Privacy.Redaction;
using Microsoft.Extensions.AI;

1. Text privacy and precision controls

Example 1 — redact PII and secrets
using LLMPolicyMesh.Privacy;

var redactor = LLMPolicyMeshPrivacy.CreateDefaultRedactor();
PiiRedactionResult result = redactor.Redact(
    "Email jane@example.com; token=sk_live_example1234567890.");

Console.WriteLine(result.RedactedText);
Example 2 — tune confidence and known exceptions
var options = new PiiRedactionOptions
{
    MinimumConfidence = 0.85d,
};
options.IgnoredValues.Add("noreply@example.com");
options.ExcludedEntityTypes.Add(PiiEntityType.IpAddress);

PiiRedactionResult result = redactor.Redact(input, options);

2. Regional and custom detection

Example 1 — select regional identifier packs
var regionalRedactor = LLMPolicyMeshPrivacy.CreateRedactor(
    PiiCountryPack.UnitedKingdom,
    PiiCountryPack.Germany,
    PiiCountryPack.India);

PiiRedactionResult result = regionalRedactor.Redact(input);

CreateRedactor() always includes the core generic, secret, and United States rules; add only the additional country packs your application needs.

Example 2 — add an application identifier detector
using LLMPolicyMesh.Privacy.Detection;

IPiiDetector detector = LLMPolicyMeshPrivacy
    .CreateDetectorBuilder()
    .AddRegexRule(
        "company.employee-id",
        PiiEntityType.Custom,
        @"(?<![A-Za-z0-9])EMP-[0-9]{6}(?![A-Za-z0-9])",
        confidence: 0.99d)
    .Build();

IReadOnlyList<PiiMatch> findings = detector.Detect(input);

3. Privacy transformations and reversible de-identification

Example 1 — HMAC one entity and mask another
using var emailHash = PiiOperator.HmacSha256(applicationHmacKey);
using var nationalIdMask =
    PiiOperator.Mask('*', preserveSuffixLength: 4);

var options = new PiiRedactionOptions();
options.Operators[PiiEntityType.EmailAddress] = emailHash;
options.Operators[PiiEntityType.NationalIdentifier] = nationalIdMask;

string safeText = redactor.Redact(input, options).RedactedText;

Additional public operators support replacement, redaction, removal, keeping a value, and application-defined transformations through PiiOperator.Custom.

Example 2 — encrypt and later restore protected values
using var protector = LLMPolicyMeshPrivacy.CreateAesProtector(
    applicationEncryptionKey,
    applicationAuthenticationKey);
using var encrypt = PiiOperator.Encrypt(protector);

var options = new PiiRedactionOptions { DefaultOperator = encrypt };
string protectedText = redactor.Redact(input, options).RedactedText;
string restoredText = LLMPolicyMeshPrivacy.Deanonymize(
    protectedText,
    protector);

The application owns key generation, storage, rotation, access control, and disposal. Encryption and authentication keys must be distinct 32-byte values.

4. Structured data and batch redaction

Example 1 — redact JSON and replace a complete subtree
var jsonOptions = new JsonRedactionOptions();
jsonOptions.PathReplacements["/profile/private"] = "[REMOVED:SUBTREE]";

JsonRedactionResult result = LLMPolicyMeshPrivacy
    .CreateDefaultJsonRedactor()
    .Redact(json, jsonOptions);

string safeJson = result.RedactedJson;
Example 2 — redact media-typed payloads and batches
string safeCsv = LLMPolicyMeshPrivacy.RedactPayload(
    csv,
    "text/csv");

IReadOnlyList<PiiRedactionResult> batch =
    LLMPolicyMeshPrivacy.RedactBatch(ticketDescriptions);

Use CreateDefaultObjectRedactor() when the input is a CLR object and the desired output is safe JSON.

5. Safe streaming

Example 1 — redact values split across provider chunks
await foreach (string safeChunk in
    LLMPolicyMeshApi.RedactStreamAsync(modelChunks))
{
    await destination.WriteAsync(safeChunk);
}

No source chunk is released before the complete logical payload has been bounded, inspected, and redacted.

Example 2 — apply structured-stream bounds
var streamPolicy = new LLMStreamingRedactionOptions
{
    ContentType = "application/json",
    MaximumBufferedBytes = 512 * 1024,
    MaximumBufferedChunks = 2_000,
    MaximumRedactedBytes = 512 * 1024,
    OutputChunkSizeCharacters = 4_096,
};

await foreach (string safeChunk in
    LLMPolicyMeshApi.RedactStreamAsync(modelChunks, streamPolicy))
{
    await destination.WriteAsync(safeChunk);
}

6. Provider-neutral model access

Example 1 — protect any IChatClient
IChatClient providerClient = CreateApplicationModelClient();

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

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

ChatResponse response = await protectedClient.GetResponseAsync(messages);
Example 2 — send an opaque HTTP model request
using System.Net.Http.Headers;
using LLMPolicyMesh.Abstractions.Gateway;

httpClient.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", modelApiKey);

ILLMPolicyGateway gateway = LLMPolicyMeshApi.CreateGateway(httpClient);
var request = new LLMRequest(
    new LLMEndpoint("primary", new Uri(modelEndpoint)),
    providerJson,
    tenantId: "tenant-42",
    modelId: "application-model");

LLMResponse response = await gateway.SendAsync(request);

The payload remains provider-defined. LLMPolicyMesh does not require provider request classes or manage provider credentials.

7. Prompt-injection defense and evasion normalization

Example 1 — enable local request inspection
var policy = new LLMPolicyMeshOptions();
policy.InputNormalization.Enabled = true;
policy.PromptInjection.Enabled = true;
policy.PromptInjection.Sensitivity = PromptInjectionSensitivity.Medium;

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

Normalization expands bounded encoded or obfuscated variants for inspection; it does not replace the application payload sent to the model.

Example 2 — inspect responses and add application indicators
policy.PromptInjection.Enabled = true;
policy.PromptInjection.InspectResponses = true;
policy.PromptInjection.Sensitivity = PromptInjectionSensitivity.High;
policy.PromptInjection.CustomIndicators.Add(
    "reveal the application system policy");

8. Tool declaration, argument, and result security

Example 1 — allow intended tools and deny the rest
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.MaximumToolCallsPerResponse = 8;
Example 2 — constrain URL arguments and sanitize unsafe tool results
var url = new ToolArgumentConstraint("fetch_*", "/url")
{
    Required = true,
    MaximumLength = 2_048,
};
url.AllowedUrlHosts.Add("*.trusted.example");
policy.Tools.ArgumentConstraints.Add(url);

policy.Tools.ToolResults.Action = ToolResultPolicyAction.Sanitize;
policy.Tools.ToolResults.RiskProfiles["read_email"] =
    ToolResultRiskLevel.High;

9. Retrieval and RAG security

Example 1 — enforce chunk counts and relevance
policy.Retrieval.Enabled = true;
policy.Retrieval.Action = RetrievalPolicyAction.Remove;
policy.Retrieval.MaximumChunks = 12;
policy.Retrieval.MinimumRelevanceScore = 0.55d;
policy.Retrieval.RequireRelevanceScore = true;
Example 2 — map an application schema and sanitize unsafe chunks
policy.Retrieval.Enabled = true;
policy.Retrieval.Action = RetrievalPolicyAction.Sanitize;
policy.Retrieval.ArrayPropertyNames.Add("knowledge_items");
policy.Retrieval.TextPropertyNames.Add("passage");
policy.Retrieval.ScorePropertyNames.Add("rank_score");
policy.Retrieval.SanitizationReplacement = "[FILTERED:RAG_CHUNK]";
policy.Retrieval.InspectPromptInjection = true;
policy.Retrieval.InspectSensitiveData = true;

10. Input/output limits and custom policy rules

Example 1 — enforce character and token ceilings
policy.Limits.Enabled = true;
policy.Limits.MaximumInputCharacters = 100_000;
policy.Limits.MaximumOutputCharacters = 40_000;
policy.Limits.MaximumInputTokens = 16_000;
policy.Limits.MaximumOutputTokens = 4_000;
policy.Limits.Counter = applicationTokenCounter; // implements ITokenCounter

Without an application counter, the package uses a conservative UTF-16-code-unit count rather than assuming a model tokenizer.

Example 2 — add ordered application policy
policy.Rules.Add(LLMPolicyMeshApi.CreateValidationRule(
    "application-input-contract",
    PolicyPhase.Input,
    context => ApplicationInputIsValid(context.Payload),
    "The application input contract denied the request.",
    order: 100));

policy.Rules.Add(LLMPolicyMeshApi.CreateRule(
    "normalize-application-envelope",
    PolicyPhase.Input,
    (context, cancellationToken) =>
    {
        cancellationToken.ThrowIfCancellationRequested();
        string replacement = NormalizeEnvelope(context.Payload);
        return new ValueTask<PolicyRuleResult>(
            PolicyRuleResult.Modified(replacement));
    },
    order: 110));

Use content-free denial reasons because operational failures may expose the reason to the caller or audit destination.

11. Application-owned semantic and PII analyzers

Example 1 — add semantic prompt-injection analysis
policy.PromptInjection.Enabled = true;
policy.PromptInjection.Analyzer = applicationPromptAnalyzer;
policy.PromptInjection.MinimumAnalyzerRiskScore = 0.70d;
policy.PromptInjection.AnalyzerFailOpen = false;

applicationPromptAnalyzer implements IPromptInjectionAnalyzer and returns a PromptInjectionAnalysisResult containing only a decision, risk score, and content-free rule ID.

Example 2 — add an application-approved PII/NER analyzer
policy.RemotePii.Analyzer = applicationNerAnalyzer;
policy.RemotePii.MinimumConfidence = 0.80d;
policy.RemotePii.AnalyzeRequests = true;
policy.RemotePii.AnalyzeResponses = true;
policy.RemotePii.FailOpen = false;
policy.RemotePii.ReplacementFormat = "[REDACTED:{0}]";

policy.RemotePii.EntityTypes.Clear();
policy.RemotePii.EntityTypes.Add("PERSON");
policy.RemotePii.EntityTypes.Add("ORGANIZATION");

The application owns analyzer transport, authentication, model choice, residency, availability, and data-processing approval.

12. Named policies and tenant selection

Example 1 — select a named policy explicitly
LLMNamedPolicy regulated = LLMPolicyMeshApi.CreateNamedPolicy(
    "regulated",
    named =>
    {
        named.PromptInjection.Enabled = true;
        named.Retrieval.Enabled = true;
        named.Limits.Enabled = true;
        named.Limits.MaximumInputTokens = 8_000;
    });

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

var request = new LLMRequest(
    endpoint,
    providerJson,
    policyName: "regulated");
Example 2 — select from content-free request metadata
ILLMPolicySelector selector = LLMPolicyMeshApi.CreatePolicySelector(
    (context, cancellationToken) =>
    {
        cancellationToken.ThrowIfCancellationRequested();
        string? name = regulatedTenants.Contains(context.TenantId)
            ? "regulated"
            : null;
        return new ValueTask<string?>(name);
    });

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

Selectors receive tenant, endpoint, correlation, and requested-policy metadata—not prompt or response content.

13. Request and tenant budgets

Example 1 — enforce request and tenant spend caps
using LLMPolicyMesh.Budgets;

policy.Budget.Enabled = true;
policy.Budget.MaximumCostPerRequestUsd = 0.05m;
policy.Budget.MaximumCostPerTenantUsd = 25m;
policy.Budget.TenantPeriod = LLMBudgetPeriod.Daily;
policy.Budget.DefaultMaximumOutputTokens = 2_000;
policy.Budget.PriceProvider = LLMPolicyMeshApi.CreatePriceProvider(
    new Dictionary<string, LLMModelPrice>
    {
        ["application-model"] = new(0.15m, 0.60m),
    });
policy.Budget.Store = LLMPolicyMeshApi.CreateInMemoryBudgetStore();

The in-memory store is intended for one application instance. Supply an application implementation of ILLMBudgetStore when multiple processes share a tenant ledger.

Example 2 — resolve pricing and chat tenants dynamically
policy.Budget.Enabled = true;
policy.Budget.MaximumCostPerTenantUsd = 40m;
policy.Budget.PriceProvider = LLMPolicyMeshApi.CreatePriceProvider(
    (context, cancellationToken) =>
        priceCatalog.ResolveAsync(context.ModelId, cancellationToken));
policy.Budget.Store = applicationBudgetStore;
policy.Budget.TenantResolver = LLMPolicyMeshApi.CreateBudgetTenantResolver(
    (context, cancellationToken) =>
        tenantDirectory.ResolveAsync(context.CorrelationId, cancellationToken));

14. Retry, circuit breaking, and fallback

Example 1 — protect ordered IChatClient routes
policy.Resilience.Enabled = true;
policy.Resilience.MaximumAttemptsPerRoute = 2;
policy.Resilience.MaximumTotalAttempts = 4;
policy.Resilience.AttemptTimeout = TimeSpan.FromSeconds(20);
policy.Resilience.TotalTimeout = TimeSpan.FromSeconds(60);

using IChatClient protectedClient = LLMPolicyMeshApi.ProtectChatClient(
    new[]
    {
        new LLMChatClientRoute("primary", primaryClient, "primary-model"),
        new LLMChatClientRoute("fallback", fallbackClient, "fallback-model"),
    },
    policy);
Example 2 — provide an explicit HTTP fallback template
var request = new LLMRequest(
    primaryEndpoint,
    primaryProviderJson,
    tenantId: "tenant-42",
    modelId: "primary-model",
    maximumOutputTokens: 2_000,
    fallbackRoutes: new[]
    {
        new LLMFallbackRoute(
            fallbackEndpoint,
            fallbackProviderJson,
            modelId: "fallback-model",
            maximumOutputTokens: 2_000),
    });

Retries and fallbacks are bounded. Tool-bearing retries require explicit idempotency-safe configuration.

15. Sanitized audit and safe Microsoft logging

Example 1 — write sanitized audit events to an application destination
using LLMPolicyMesh.Abstractions.Audit;
using LLMPolicyMesh.Audit;

IAuditSink audit = LLMPolicyMeshAudit.CreateDelegateSink(
    async (auditEvent, cancellationToken) =>
    {
        await applicationAuditStore.WriteAsync(
            auditEvent,
            cancellationToken);
        return AuditWriteResult.Written();
    });

ILLMPolicyGateway gateway = LLMPolicyMeshApi.CreateGateway(
    httpClient,
    auditSink: audit);
Example 2 — protect application logging
using Microsoft.Extensions.Logging;

ILogger safeLogger = logger.WithLLMPolicyMeshRedaction();

using (safeLogger.BeginScope(new Dictionary<string, object?>
{
    ["CustomerEmail"] = customerEmail,
}))
{
    safeLogger.LogInformation("Ticket text: {Ticket}", ticketText);
}

The wrapper redacts formatted messages, structured values, scopes, and exception text before forwarding them to the application-owned logging provider.

16. Tamper-evident audit ledgers

Example 1 — write a sanitized hash-chained ledger
await using FileStream stream = File.Open(
    ledgerPath,
    FileMode.Create,
    FileAccess.ReadWrite,
    FileShare.Read);

using IDisposableAuditSink ledger =
    LLMPolicyMeshAudit.CreateTamperEvidentJsonLinesSink(
        stream,
        integrityKey: applicationIntegrityKey,
        leaveOpen: true);

ILLMPolicyGateway gateway = LLMPolicyMeshApi.CreateGateway(
    httpClient,
    auditSink: ledger);
Example 2 — verify a complete ledger
stream.Position = 0;
AuditLedgerVerificationResult verification =
    LLMPolicyMeshAudit.VerifyTamperEvidentJsonLines(
        stream,
        applicationIntegrityKey);

if (!verification.IsValid)
{
    throw new InvalidOperationException(
        $"Audit ledger verification failed: {verification.FailureKind}");
}

The application owns the destination, retention, access policy, and optional integrity key.

17. HTTP pipelines and ASP.NET Core

Example 1 — insert a redacting HTTP handler
var policy = new LLMPolicyMeshOptions
{
    RedactRequests = true,
    RedactResponses = true,
};

using var handler = LLMPolicyMeshApi.CreateHttpHandler(
    innerHandler: new HttpClientHandler(),
    options: policy);
using var protectedHttpClient = new HttpClient(handler);
Example 2 — redact ASP.NET Core request and response bodies
using LLMPolicyMesh.Integrations.AspNetCore;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton(new HttpClient());
builder.Services.AddLLMPolicyMesh(
    services => services.GetRequiredService<HttpClient>(),
    policy => policy.PromptInjection.Enabled = true);

var app = builder.Build();
app.UseLLMPolicyMeshRedaction(options =>
{
    options.MaximumBodyBytes = 1024 * 1024;
    options.RedactRequests = true;
    options.RedactResponses = true;
});

ASP.NET Core integration is available on net8.0. Place the middleware before components that should receive sanitized supported textual bodies.

18. Provider usage extraction

Example 1 — attach an application usage reader
policy.UsageReader = applicationUsageReader; // implements ILLMUsageReader
policy.UsageReaderFailOpen = false;
policy.OnUsageReaderError = exception =>
    applicationMetrics.RecordUsageReaderFailure(exception.GetType().Name);

ILLMPolicyGateway gateway =
    LLMPolicyMeshApi.CreateGateway(httpClient, policy);
Example 2 — implement a provider payload adapter
sealed class ApplicationUsageReader : ILLMUsageReader
{
    public ValueTask<LLMUsage?> ReadAsync(
        LLMUsageReadContext context,
        CancellationToken cancellationToken = default)
    {
        cancellationToken.ThrowIfCancellationRequested();
        ProviderUsage? usage = ParseUsage(context.Payload);

        LLMUsage? result = usage is null
            ? null
            : new LLMUsage(
                inputTokens: usage.InputTokens,
                outputTokens: usage.OutputTokens,
                totalTokens: usage.TotalTokens);

        return new ValueTask<LLMUsage?>(result);
    }
}

The reader runs in-process. It must not log or export the raw provider response supplied in context.Payload.

19. Tracing and metrics

Example 1 — subscribe to package activities
services.AddOpenTelemetry()
    .WithTracing(tracing => tracing
        .AddSource(LLMPolicyMeshTelemetry.ActivitySourceName)
        .AddOtlpExporter());
Example 2 — subscribe to package metrics
services.AddOpenTelemetry()
    .WithMetrics(metrics => metrics
        .AddMeter(LLMPolicyMeshTelemetry.MeterName)
        .AddPrometheusExporter());

Exporter packages and destinations belong to the application. Keep application-supplied policy, rule, route, and endpoint names stable, low-cardinality, and free of customer data.

Failure handling

Policy denials throw LLMPolicyViolationException. Exhausted retry, timeout, fallback, or circuit behavior throws LLMResilienceException. Catch these at the application boundary where you can map them to safe user-facing behavior:

try
{
    LLMResponse response = await gateway.SendAsync(request, cancellationToken);
}
catch (LLMPolicyViolationException exception)
{
    HandlePolicyDenial(exception.ViolationKind);
}
catch (LLMResilienceException exception)
{
    HandleModelUnavailable(exception.FailureKind);
}

Do not expose provider payloads, exception internals, credentials, or sensitive policy context in end-user error messages.

Target frameworks

  • net8.0
  • netstandard2.1

ASP.NET Core middleware is available on net8.0. The core privacy, gateway, policy, budget, resilience, audit, and model-access contracts are packaged for the supported targets where their platform dependencies are available.

Security and ownership boundary

LLMPolicyMesh is an in-process technical control layer. The consuming application remains responsible for:

  • constructing model clients and HTTP transports;
  • managing credentials, endpoints, authorization, and provider configuration;
  • selecting model-specific tokenizers and maintaining price data;
  • providing distributed budget storage when required;
  • owning analyzer services, cryptographic keys, audit destinations, and retention;
  • executing tools inside an appropriately isolated and authorized environment; and
  • testing policies against its own payload schemas, models, languages, and threat model.

These controls can support privacy, security, and governance programs. They are not a legal certification or a guarantee that every sensitive value or attack will be detected.

License

MIT

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos 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
0.6.0-beta.3 85 9/2/2026