.NET
AI agent detection for ASP.NET Core and .NET Framework
Checkpoint for .NET works on ASP.NET Core (6, 7, 8, 9) and .NET Framework (4.6.2 through 4.8.1). One package, pick your runtime, ship.
Install
dotnet add package KyaOs.CheckpointInstall-Package KyaOs.CheckpointNuGet resolves the right adapter for your project's target framework automatically.
Quick start
Register in Program.cs:
using Checkpoint.AspNetCore.Extensions;
using Checkpoint.Core.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCheckpoint(options =>
{
options.ProjectId = builder.Configuration["Checkpoint:ProjectId"]!;
options.ApiKey = builder.Configuration["Checkpoint:ApiKey"]!;
options.OnAgentDetected = DetectedAction.Block;
});
var app = builder.Build();
app.UseCheckpoint(); // before routing + auth
app.UseRouting();
app.UseAuthorization();
app.MapControllers();
app.Run();Set credentials in appsettings.json:
{
"Checkpoint": {
"ProjectId": "your_project_id",
"ApiKey": "your_api_key"
}
}Requires a 64-bit host process. Azure App Service B1 or higher with Platform = 64-bit in Configuration → General Settings, or Windows Server IIS with Enable 32-Bit Applications = False in the app pool's Advanced Settings. Azure App Service Free (F1) and Shared (D1) tiers are 32-bit only and not supported — the site will refuse to start at module init with a clear error if the host is 32-bit.
No code changes. Add to Web.config:
<configuration>
<appSettings>
<add key="Checkpoint:ProjectId" value="your_project_id" />
<add key="Checkpoint:ApiKey" value="your_api_key" />
<add key="Checkpoint:OnAgentDetected" value="Block" />
</appSettings>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="Checkpoint"
type="Checkpoint.AspNet.CheckpointModule, Checkpoint.AspNet" />
</modules>
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>
</configuration>runAllManagedModulesForAllRequests="true" is required so detection runs on static files too.
Deploy. Checkpoint runs on every request.
Configuration
builder.Services.AddCheckpoint(options =>
{
options.ProjectId = "your_project_id";
options.ApiKey = "your_api_key";
options.OnAgentDetected = DetectedAction.Block;
options.ConfidenceThreshold = 70;
options.SkipPaths = ["/health", "/api/webhooks/*"];
options.IncludePaths = ["/api/*"];
options.McpServerUrl = "https://mcp.example.com";
options.SiteName = "My Website";
options.BlockedResponse = new BlockedResponseOptions
{
StatusCode = 403,
Message = "Access denied: AI agent detected",
};
});<appSettings>
<add key="Checkpoint:ProjectId" value="your_project_id" />
<add key="Checkpoint:ApiKey" value="your_api_key" />
<add key="Checkpoint:OnAgentDetected" value="Block" />
<add key="Checkpoint:ConfidenceThreshold" value="70" />
<add key="Checkpoint:SkipPaths" value="/health,/api/webhooks/*" />
<add key="Checkpoint:IncludePaths" value="/api/*" />
<add key="Checkpoint:McpServerUrl" value="https://mcp.example.com" />
<add key="Checkpoint:SiteName" value="My Website" />
</appSettings>Web.config uses the same key names as appsettings.json. Comma-separated values for list options like SkipPaths and IncludePaths.
Detection actions
| Action | Behavior |
|---|---|
Allow | Let the request through silently |
Log | Log and allow |
Block | Return 403 |
Redirect | 302 to McpServerUrl |
Instruct | 401 with MCP-I authorization instructions for the agent |
Path filtering
IncludePaths takes priority — if set, only matching paths are processed. Both support wildcard suffixes (/api/*).
Access detection results
Detection results live on HttpContext.Items — read them in controllers or downstream middleware.
public IActionResult Get()
{
var result = HttpContext.Items["Checkpoint.Result"] as DetectionResult;
if (result?.IsAgent == true)
{
return Ok(new { agent = result.DetectedAgent?.Name, confidence = result.Confidence });
}
return Ok(new { message = "Hello human!" });
}public IHttpActionResult Get()
{
var result = HttpContext.Current.Items["Checkpoint.Result"] as DetectionResult;
if (result?.IsAgent == true)
{
return Ok(new { agent = result.DetectedAgent?.Name, confidence = result.Confidence });
}
return Ok(new { message = "Hello human!" });
}Response headers
Every response includes detection metadata:
| Header | Value | When |
|---|---|---|
KYA-Detected | true / false | Always |
KYA-Confidence | 0–100 | Always |
KYA-Class | Human / AiAgent / Bot | Always |
KYA-Agent | Agent name | When detected |
KYA-Verification | Pattern / Signature | When detected |
Signature verification
Ed25519 signature verification for ChatGPT (RFC 9421) and KYA Agent DID is on by default. Verified agents get 100% confidence. ChatGPT's public key refreshes automatically from OpenAI's JWKS.
To disable:
options.EnableSignatureVerification = false;<add key="Checkpoint:EnableSignatureVerification" value="false" />MCP-I instruct mode
DetectedAction.Instruct returns a 401 with MCP-I authentication instructions — WWW-Authenticate: KYA header, a machine-readable mcp_i JSON body, and a plain-language message the agent can relay to its user.
options.OnAgentDetected = DetectedAction.Instruct;
options.McpServerUrl = "https://mcp.example.com";<add key="Checkpoint:OnAgentDetected" value="Instruct" />
<add key="Checkpoint:McpServerUrl" value="https://mcp.example.com" />Dashboard reporting
Detection events flow to your Checkpoint dashboard automatically — every AI agent and bot classified above the confidence threshold is reported fire-and-forget after the request completes. Pure human traffic is not reported. Same payload, same gating, and same dashboard experience across ASP.NET Core and .NET Framework.
Requires Checkpoint:ProjectId and Checkpoint:ApiKey to be set. Without them, detection and enforcement still run — only the dashboard hop is skipped.
Troubleshooting
The errors below are specific to the .NET Framework adapter. Modern ASP.NET Core installs don't hit any of them.
Module fails to start with PlatformNotSupportedException
Symptom. First request returns a 500, with an exception whose message begins:
Checkpoint requires a 64-bit host process. Current process is 32-bit.Cause. The app pool is running in 32-bit mode. Checkpoint's WebAssembly runtime ships x64 only and has no 32-bit fallback.
Fix.
- Azure App Service. Upgrade the App Service Plan from Free (F1) or Shared (D1) to Basic (B1) or higher. In the portal, open Configuration → General Settings, set Platform to 64-bit, and restart the app.
- IIS on Windows Server. In IIS Manager, open Application Pools → your pool → Advanced Settings and set Enable 32-Bit Applications to
False. - Standalone host. Add
<PlatformTarget>x64</PlatformTarget>to your csproj, orAnyCPUwith<Prefer32Bit>false</Prefer32Bit>.
FileLoadException with HRESULT 0x80131040
Symptom. First request returns a 500, with an error like:
Could not load file or assembly 'Microsoft.Extensions.Logging.Abstractions'
or one of its dependencies. (0x80131040)Cause. Classic ASP.NET needs binding redirects in Web.config for the transitive Microsoft.Extensions.* and System.Text.Json dependency graph. Checkpoint.AspNet 0.2.1+ ships an auto-generated redirect set inside the NuGet package, but it's applied differently depending on whether your project uses packages.config or PackageReference.
Fix for packages.config. No action needed. NuGet applies the transform to Web.config automatically on Install-Package.
Fix for PackageReference. NuGet does not auto-transform content files for PackageReference projects. Pick one:
-
Enable MSBuild auto-redirect generation in your consumer csproj (recommended):
<PropertyGroup> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType> </PropertyGroup> -
Copy the shipped redirect set manually. Open the XDT at the path below, copy its
<runtime>block, and paste it into yourWeb.config:~/.nuget/packages/checkpoint.aspnet/<version>/contentFiles/any/net462/web.config.install.xdt
FileNotFoundException for wasmtime.dll at module init
Symptom. First request returns a 500, with a FileNotFoundException whose message begins:
wasmtime.dll not found next to the Checkpoint.Core assemblyCause. The NuGet consumer-side targets file that copies wasmtime.dll into your build output didn't fire. As of Checkpoint.Core 0.2.2+, the file ships at buildTransitive/net462/ and is imported automatically by both direct and transitive PackageReference consumers as well as packages.config consumers.
Fix.
- Upgrade to
KyaOs.Checkpoint0.2.2 or later. Versions 0.2.0 and 0.2.1 shipped the targets file atbuild/only, which NuGet skips for transitive consumers — a known bug fixed in 0.2.2. - Install
KyaOs.CheckpointorCheckpoint.AspNet, not bareCheckpoint.Core. The targets file lives in the Framework adapter's transitive graph; a project that references onlyCheckpoint.Coredirectly won't pull it in. - If the error persists after upgrading, run
msbuild /verbosity:detailedand search the log forCheckpoint.Core.targets. A missing import means NuGet's targets graph isn't being walked by your project type — open an issue on agent-shield with a minimal repro.
Supported versions
| Runtime | Versions |
|---|---|
| ASP.NET Core | .NET 6, 7, 8, 9 |
| .NET Framework | 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1 |
.NET Framework requires a 64-bit host process (Windows Server IIS or Azure App Service B1+).