Enforce: .NET Cedar Policy + Consent
Turn on Cedar policy checks and a consent screen in your .NET app
Goal
Turn your .NET app from watching AI agents into acting on them. By the end of this cookbook, you'll have:
- Every request checked against your deployed Cedar policy
- Cooperative agents sent to a branded consent screen when they need permission
- The standards-based delegation challenge available for sensitive routes
This is for .NET middleware. Agents that cooperate get sent to your consent screen; the rest are blocked. For sensitive routes that must never be bypassed (like payments), also put the Gateway in front of your app.
Prerequisites
- A .NET app already running Checkpoint middleware in detection mode — this cookbook adds enforcement on top
- A
ProjectIdandApiKeyfor the project — see Credentials - ASP.NET Core (net8) or .NET Framework (net462)
Time Estimate
10-15 minutes
Use the latest version: 1.8.1. All four .NET packages move together, so you only
ever change one number. (This number updates itself from the source code, so it's always current.)
Steps
Four steps. The policy you deploy in the dashboard does the work — your app just reads it.
On the .NET Framework tabs below, package entries go in packages.config and settings go in the
<appSettings> section of Web.config. On ASP.NET Core, settings go in appsettings.json (or
inline in AddCheckpoint).
1. Install the package
Add KyaOs.Checkpoint — it pulls in the other three packages for you.
<PackageReference Include="KyaOs.Checkpoint" Version="1.8.1" /><package id="KyaOs.Checkpoint" version="1.8.1" targetFramework="net462" />2. Connect it to your project
Add your ProjectId and ApiKey (from the dashboard). If you already run the .NET middleware, these are set — skip ahead.
builder.Services.AddCheckpoint(options =>
{
options.ProjectId = builder.Configuration["Checkpoint:ProjectId"]!;
options.ApiKey = builder.Configuration["Checkpoint:ApiKey"]!;
});<add key="Checkpoint:ProjectId" value="your_project_id" />
<add key="Checkpoint:ApiKey" value="your_api_key" />3. Deploy your Cedar policy
Open the Policy tab for your project (/dashboard/{orgId}/{projectId}/policy) to see your policies; create one from Policy → Compose (/dashboard/{orgId}/{projectId}/policy/compose). Your app reads the deployed policy automatically — nothing to add in code.
4. Point at your consent screen
Tell your app where the consent screen lives. When the policy decides an agent needs permission, it's sent here.
options.AuthorizationHostUrl = "https://kya.vouched.id";<add key="Checkpoint:AuthorizationHostUrl" value="https://kya.vouched.id" />Brand the screen — logo, name, and scope wording — in the dashboard consent editor (Policy → Auth, /dashboard/{orgId}/{projectId}/policy/auth). The consent-config API is read-only (GET /api/v1/bouncer/projects/{projectId}/consent-config). See Consent Flows.
Verify It's Working
Open a protected route as an agent and watch the dashboard show the verdict (Permit, Block, or Challenge — see Verdicts).
Advanced settings
You don't need these to get started. By default, a policy challenge verdict already sends agents to consent via the standards-based delegation challenge. The options below scope it to specific routes and actions, and make it friendly to AI agents that can't read a blocked page.
The standards-based challenge
As of KyaOs.Checkpoint 1.8.0, EnableDelegationChallengeWire defaults to true: a CHALLENGE verdict already emits the spec delegation challenge (the dual WWW-Authenticate: Delegation ..., Bearer resource_metadata="..." grammar from draft-kya-http-02 §8.1, see The Delegation challenge wire), not the legacy Bearer-only step-up. What you still set explicitly is which scopes require it and which org identity signs the registered proof:
options.DelegationChallengeScopes = ["payment:process", "data:export"]; // which actions require it
options.ResourceOrgDid = "did:web:acme.com"; // your org's identity — binds the signed proof<add key="Checkpoint:DelegationChallengeScopes" value="payment:process,data:export" />
<add key="Checkpoint:ResourceOrgDid" value="did:web:acme.com" />Need the pre-1.8.0 Bearer-only step-up temporarily? Set EnableDelegationChallengeWire = false
(or Checkpoint:EnableDelegationChallengeWire=false). This opt-out is only available through the
1.8.x line: it's removed in 1.9.0 on 2026-12-01 (#4795). Migrate off it before then.
Choose how strict to be
Some AI agents can't read a page once it's blocked, so they never see the consent link. Negotiated makes sure cooperative agents still get the link, while everything else stays blocked.
options.DelegationChallengeMode = DelegationChallengeMode.Negotiated;<add key="Checkpoint:DelegationChallengeMode" value="Negotiated" />| Mode | Behaviour |
|---|---|
Negotiated (default) | 200 for a cooperative agent, 401 for everything else. Recommended. |
Spec401 | Always the spec 401. Cooperative AI fetchers may miss the body. |
Always200 | Always the 200 envelope. Most permissive. |
All settings in one place
{
"Checkpoint": {
"ProjectId": "your_project_id",
"ApiKey": "your_api_key",
"EnableComposedPolicy": true,
"EnableDelegationChallengeWire": true,
"DelegationChallengeScopes": "payment:process,data:export",
"DelegationChallengeMode": "Negotiated",
"AuthorizationHostUrl": "https://kya.vouched.id",
"ResourceOrgDid": "did:web:acme.com"
}
}<appSettings>
<add key="Checkpoint:ProjectId" value="your_project_id" />
<add key="Checkpoint:ApiKey" value="your_api_key" />
<add key="Checkpoint:EnableComposedPolicy" value="true" />
<add key="Checkpoint:EnableDelegationChallengeWire" value="true" />
<add key="Checkpoint:DelegationChallengeScopes" value="payment:process,data:export" />
<add key="Checkpoint:DelegationChallengeMode" value="Negotiated" />
<add key="Checkpoint:AuthorizationHostUrl" value="https://kya.vouched.id" />
<add key="Checkpoint:ResourceOrgDid" value="did:web:acme.com" />
</appSettings>What You Learned
- How to install
KyaOs.Checkpointand connect it to your project withProjectId+ApiKey - That your app enforces the Cedar policy you deploy in the dashboard — no rules live in code
- How to point cooperative agents at a branded consent screen with
AuthorizationHostUrl - That the built-in
challengeverdict is the standards-based delegation challenge by default (1.8.0+): scope it withDelegationChallengeScopes, bind it to your org withResourceOrgDid, and knowEnableDelegationChallengeWire = falseis a time-boxed opt-out, not a feature you turn on - How
DelegationChallengeMode(Negotiated/Spec401/Always200) controls whether cooperative fetchers get a body-readable200or the spec401
The .NET middleware emits the spec delegation challenge itself (via its composed-policy engine),
so a CHALLENGE verdict becomes a real 401 step-up rather than falling back to a redirect.
Challenge support varies by SDK — see Policies.
Next Steps
| Goal | Where to go |
|---|---|
| Detect-only .NET setup first | .NET Integration |
| Fine-tune the policy verdicts | Policies |
| Brand the consent screen | Govern: Consent |
Related Documentation
- .NET Integration — Base middleware, install, and detection
- Policies — Authoring Cedar and the verdict reference
- Govern: Consent — Consent flows and screen configuration
