Skip to main content
Browse docs
By Audience
Getting Started
Configuration
Use Cases
IDE Integration
Third-Party Integrations
Engineering Cache
Console
API Reference
Gateway
Workflow Guides
Templates
Providers and SDKs
Industry Guides
Advanced Guides
Browse by Role
Deployment Guides
In-Depth Guides
Tutorials
FAQ

.NET Integration with Keeptrusts

Keeptrusts exposes an OpenAI-compatible HTTP API. Any .NET HttpClient or library that targets the OpenAI REST contract can route through the gateway — no proprietary SDK required.

Use this page when

  • You are connecting an ASP.NET or .NET application to the Keeptrusts gateway for policy-enforced AI calls.
  • You need HttpClient, Semantic Kernel, or Polly patterns pointing at the gateway's OpenAI-compatible endpoint.
  • You want to handle policy blocks (HTTP 409) gracefully in .NET error handling.
  • You need health check integration with ASP.NET's AddHealthChecks() for gateway connectivity.

Primary audience

  • Primary: Technical Engineers
  • Secondary: AI Agents, Technical Leaders

How it works

ASP.NET app
→ HttpClient / Semantic Kernel (base URI pointed at Keeptrusts)
→ kt gateway (policy evaluation)
→ upstream LLM provider
→ response (redacted / enriched per policy)

Prerequisites

  • Keeptrusts CLI installed and a running gateway (kt gateway run)
  • A valid gateway key (kt_gk_...)
  • .NET 8+ SDK

HttpClient integration

Register a named HttpClient in Program.cs:

builder.Services.AddHttpClient("Keeptrusts", client =>
{
client.BaseAddress = new Uri("http://localhost:41002/v1/");
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer",
builder.Configuration["Keeptrusts:GatewayKey"]);
});

Calling the completions endpoint

public class GovernedChatService
{
private readonly HttpClient _http;

public GovernedChatService(IHttpClientFactory factory)
{
_http = factory.CreateClient("Keeptrusts");
}

public async Task<string> CompleteAsync(string userMessage)
{
var body = new
{
model = "gpt-4o",
messages = new[] { new { role = "user", content = userMessage } }
};

var response = await _http.PostAsJsonAsync("chat/completions", body);
response.EnsureSuccessStatusCode();

var result = await response.Content
.ReadFromJsonAsync<JsonElement>();

return result
.GetProperty("choices")[0]
.GetProperty("message")
.GetProperty("content")
.GetString()!;
}
}

Semantic Kernel integration

Microsoft Semantic Kernel accepts a custom HttpClient, so the gateway slots in directly:

using Microsoft.SemanticKernel;

var httpClient = new HttpClient
{
BaseAddress = new Uri("http://localhost:41002/v1/")
};

var kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(
modelId: "gpt-4o",
apiKey: builder.Configuration["Keeptrusts:GatewayKey"]!,
httpClient: httpClient)
.Build();

var result = await kernel.InvokePromptAsync(
"Summarize our data retention policy.");

Console.WriteLine(result);

Using Semantic Kernel with DI

Register the kernel in the DI container:

builder.Services.AddSingleton(sp =>
{
var config = sp.GetRequiredService<IConfiguration>();
var httpClient = new HttpClient
{
BaseAddress = new Uri(config["Keeptrusts:GatewayUrl"]!)
};

return Kernel.CreateBuilder()
.AddOpenAIChatCompletion(
modelId: "gpt-4o",
apiKey: config["Keeptrusts:GatewayKey"]!,
httpClient: httpClient)
.Build();
});

ASP.NET middleware for governance headers

Add middleware that forwards governance metadata from gateway responses:

public class GovernanceHeaderMiddleware
{
private readonly RequestDelegate _next;

public GovernanceHeaderMiddleware(RequestDelegate next) => _next = next;

public async Task InvokeAsync(HttpContext context)
{
await _next(context);

if (context.Items.TryGetValue("GovernanceEventId", out var eventId))
{
context.Response.Headers.Append(
"X-Governance-Event-Id", eventId?.ToString());
}
}
}

Register it in Program.cs:

app.UseMiddleware<GovernanceHeaderMiddleware>();

Polly retry policies

Use Polly to retry on transient failures (429, 5xx) while letting policy blocks (409) propagate:

builder.Services.AddHttpClient("Keeptrusts", client =>
{
client.BaseAddress = new Uri("http://localhost:41002/v1/");
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer",
builder.Configuration["Keeptrusts:GatewayKey"]);
})
.AddPolicyHandler(Policy<HttpResponseMessage>
.Handle<HttpRequestException>()
.OrResult(r =>
r.StatusCode == HttpStatusCode.TooManyRequests ||
(int)r.StatusCode >= 500)
.WaitAndRetryAsync(3,
attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt))));

Policy blocks (409) are not retried — they indicate a governance decision, not a transient fault.

Error handling

public async Task<string> SafeCompleteAsync(string message)
{
var body = new
{
model = "gpt-4o",
messages = new[] { new { role = "user", content = message } }
};

var response = await _http.PostAsJsonAsync("chat/completions", body);

if (response.StatusCode == HttpStatusCode.Conflict) // 409
{
var detail = await response.Content.ReadAsStringAsync();
throw new GovernancePolicyException(detail);
}

response.EnsureSuccessStatusCode();

var result = await response.Content.ReadFromJsonAsync<JsonElement>();
return result
.GetProperty("choices")[0]
.GetProperty("message")
.GetProperty("content")
.GetString()!;
}

public class GovernancePolicyException : Exception
{
public GovernancePolicyException(string detail)
: base($"Request blocked by governance policy: {detail}") { }
}

Health check

Add a gateway health check for ASP.NET health monitoring:

builder.Services.AddHealthChecks()
.AddUrlGroup(
new Uri("http://localhost:41002/v1/models"),
name: "keeptrusts-gateway",
timeout: TimeSpan.FromSeconds(3));

Access the health endpoint at /healthz to verify gateway connectivity.

Configuration via appsettings.json

{
"Keeptrusts": {
"GatewayUrl": "http://localhost:41002/v1/",
"GatewayKey": "kt_gk_your_gateway_key"
}
}

Override with environment variables in production:

export Keeptrusts__GatewayUrl=https://gateway.example.com/v1/
export Keeptrusts__GatewayKey=kt_gk_production_key

Validating your policy config

kt policy lint --file policy-config.yaml

Tailing governance events

kt events tail --follow

Summary

PatternKey change
HttpClientSet BaseAddress to gateway URL
Semantic KernelPass custom HttpClient to builder
PollyRetry 429 / 5xx, skip 409
Health checkAddUrlGroup targeting /v1/models
ASP.NET middlewareForward governance headers
Error handlingCatch 409 for policy blocks

For AI systems

  • Canonical terms: Keeptrusts gateway, gateway key (kt_gk_...), OpenAI-compatible API, HttpClient, Microsoft Semantic Kernel, Polly retry policy, HTTP 409 policy block.
  • Key config: BaseAddress = http://localhost:41002/v1/, Authorization: Bearer kt_gk_..., appsettings.json section Keeptrusts:GatewayUrl and Keeptrusts:GatewayKey.
  • CLI commands: kt gateway run, kt policy lint, kt events tail --follow.
  • Best next pages: Python SDK patterns, Node.js SDK patterns, Java & Spring Boot.

For engineers

  • Prerequisites: .NET 8+ SDK, running Keeptrusts gateway (kt gateway run), a gateway key from the console.
  • Validate: curl http://localhost:41002/v1/models returns model list. Health check at /healthz confirms ASP.NET can reach the gateway.
  • Key pattern: Retry 429/5xx with Polly exponential backoff; never retry 409 (policy block is intentional).
  • Production override: Set Keeptrusts__GatewayUrl and Keeptrusts__GatewayKey environment variables to override appsettings.json.

For leaders

  • No SDK lock-in: Uses standard HttpClient and Semantic Kernel — no proprietary Keeptrusts NuGet package required.
  • Governance transparency: Every AI call passes through the gateway; policy blocks return 409 with structured reasons for audit.
  • Adoption path: Change one URL (BaseAddress) to route existing OpenAI integrations through governance.
  • Resilience: Polly handles transient failures without masking governance decisions.

Next steps