Agent Trust End-to-End Example¶
| Field | Value |
|---|---|
| Level | Intermediate |
| Maturity | Preview |
| Runnable | Conceptual (paste into a console app) |
| Packages | AgentTrust.Core, Policy, Maf, AspNetCore |
| Source | Inline |
Preview boundary: This example uses Agent Trust preview packages. Agent Trust is a project-defined pattern for scoped agent/tool authorization. It is not an IETF, OpenID Foundation, MCP, or OWF standard.
This example demonstrates an end-to-end path:
- Agent runtime evaluates policy and mints a capability SD-JWT.
- Agent sends the token to a tool API.
- Tool API verifies token + policy and authorizes endpoint execution.
sequenceDiagram
participant Agent as Agent Runtime
participant Policy as Policy Engine
participant Issuer as Token Issuer
participant Tool as Tool API
Agent->>Policy: Evaluate (agent, tool, action)
Policy-->>Agent: Allow + constraints
Agent->>Issuer: Mint SD-JWT capability
Issuer-->>Agent: Signed token (exp=45s)
Agent->>Tool: HTTP GET + Bearer token
Tool->>Tool: Verify signature, aud, exp, jti
Tool->>Tool: Evaluate inbound policy
Tool-->>Agent: 200 OK (authorized)
1. Shared Setup¶
using Microsoft.IdentityModel.Tokens;
using SdJwt.Net.AgentTrust.Core;
using SdJwt.Net.AgentTrust.Policy;
using System.Security.Cryptography;
var signingKey = new SymmetricSecurityKey(RandomNumberGenerator.GetBytes(32));
// NOTE: This example uses a symmetric key for brevity.
// Production deployments should use asymmetric keys (e.g. ES256)
// so the tool server never holds the signing key.
var nonceStore = new MemoryNonceStore();
var policyEngine = new DefaultPolicyEngine(
new PolicyBuilder()
.Deny("*", "ledger", "Delete")
.Allow("agent://finance-*", "ledger", "Read", c =>
{
c.MaxLifetime(TimeSpan.FromSeconds(45));
c.Limits(new CapabilityLimits { MaxResults = 100 });
c.RequireDisclosure("ctx.correlationId");
})
.Build());
2. Agent Runtime (Outbound)¶
// McpTrustAdapter lives in the AgentTrust.Maf package (MAF/MCP adapter layer)
using SdJwt.Net.AgentTrust.Maf;
var issuer = new CapabilityTokenIssuer(
signingKey,
SecurityAlgorithms.HmacSha256,
nonceStore);
var mcpAdapter = new McpTrustAdapter(
issuer,
policyEngine,
"agent://finance-eu",
new Dictionary<string, string> { ["ledger"] = "https://tools.example.com" });
var token = await mcpAdapter.MintForToolCallAsync(
toolName: "ledger",
arguments: new Dictionary<string, object> { ["action"] = "Read" },
context: new CapabilityContext
{
CorrelationId = Guid.NewGuid().ToString("N"),
WorkflowId = "wf-ledger-sync"
});
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("Authorization", $"Bearer {token.Token}");
var response = await http.GetAsync("https://tools.example.com/ledger/entries");
3. Tool API (Inbound)¶
using Microsoft.IdentityModel.Tokens;
using SdJwt.Net.AgentTrust.AspNetCore;
using SdJwt.Net.AgentTrust.Policy;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddSingleton<IPolicyEngine>(policyEngine);
builder.Services.AddAgentTrustVerification(options =>
{
options.Audience = "https://tools.example.com";
options.TrustedIssuers = new Dictionary<string, SecurityKey>
{
["agent://finance-eu"] = signingKey
};
options.EmitReceipts = true;
});
var app = builder.Build();
app.UseAgentTrustVerification();
app.MapControllers();
app.Run();
Controller:
using Microsoft.AspNetCore.Mvc;
using SdJwt.Net.AgentTrust.AspNetCore;
[ApiController]
[Route("ledger")]
public sealed class LedgerController : ControllerBase
{
[HttpGet("entries")]
[RequireCapability("ledger", "Read")]
public IActionResult GetEntries()
{
var issuer = HttpContext.GetAgentIssuer();
var context = HttpContext.GetCapabilityContext();
return Ok(new
{
issuer,
correlationId = context?.CorrelationId,
entries = new[] { "entry-1", "entry-2" }
});
}
}
4. Expected Outcomes¶
- Token missing/invalid:
401or403 - Capability mismatch:
403 - Policy deny:
403 - Valid token + allowed action:
200
Related¶
- MCP Tool Governance Demo -- full runnable demo
- Demo Scenarios -- scenario catalogue
- Agent Trust Integration Guide
- Agent Trust Kits
5. Hardening Notes¶
- Replace in-memory nonce store in production.
- Keep capability token TTL short.
- Scope audiences per tool endpoint, not per environment.
- Persist receipts in centralized observability stack.
- Use
AgentTrustSecurityMode.Productionto enforce asymmetric keys and proof-of-possession. - Use
AttenuationValidatorwhen delegating between agents to prevent privilege escalation.