ZcapLd.AspNetCore
6.0.0
dotnet add package ZcapLd.AspNetCore --version 6.0.0
NuGet\Install-Package ZcapLd.AspNetCore -Version 6.0.0
<PackageReference Include="ZcapLd.AspNetCore" Version="6.0.0" />
<PackageVersion Include="ZcapLd.AspNetCore" Version="6.0.0" />
<PackageReference Include="ZcapLd.AspNetCore" />
paket add ZcapLd.AspNetCore --version 6.0.0
#r "nuget: ZcapLd.AspNetCore, 6.0.0"
#:package ZcapLd.AspNetCore@6.0.0
#addin nuget:?package=ZcapLd.AspNetCore&version=6.0.0
#tool nuget:?package=ZcapLd.AspNetCore&version=6.0.0
ZcapLd.AspNetCore
Optional ASP.NET Core adapter for ZcapLd.Core signed revocation workflows.
Features
- Minimal API endpoint rail for signed revocation requests
- DI registration helpers for default and custom
IRevocationStorebackends - Works with pluggable stores (database, contract client, oracle bridge, cache)
Quick Start
using ZcapLd.AspNetCore.DependencyInjection;
using ZcapLd.AspNetCore.Endpoints;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddZcapServices();
builder.Services.AddZcapRevocationSupport();
// Configure an IRootCapabilityResolver for delegated-capability revocation.
var app = builder.Build();
app.MapZcapRevocationEndpoints();
app.Run();
For a custom backend, register your own IRevocationStore implementation:
builder.Services.AddZcapRevocationSupport<MyRevocationStore>();
Setup Revocation Endpoints
MapZcapRevocationEndpoints() exposes:
POST /zcaps/revocations/{*capabilityId}— revoke from a signed request (proof-of-possession). Body:{ capability, signedRevocation }(the latter fromISigningService.SignRevocationAsync). Returns403when unauthenticated/unauthorized. RequiresAddZcapServices()(it resolvesIVerificationService), notAddZcapRevocationSupport()alone.
There is no status GET. The ZCAP specification and the Digital Bazaar stack define only the POST,
and a bare id has no single status once records are scoped (#158). Holders learn of revocation
from a Revoked verification outcome; expose IRevocationService behind your own authorization
if you need status queries.
{*capabilityId} is encodeURIComponent(capabilityId): one level of percent-encoding, which the
endpoint decodes exactly once (Uri.EscapeDataString output is accepted too). A root id already
contains escapes (urn:zcap:root:https%3A%2F%2F…), so it appears encoded twice in the URL; that is
correct. The id is read from the raw request target, so an id containing / is unambiguous on
Kestrel. The in-memory TestServer exposes no raw target; there the endpoint falls back to the route
value, in which an encoded / (%2F) stays encoded — send such ids with literal slashes on that host.
Intermediaries must forward the request target byte-for-byte: a proxy that decodes and re-encodes
the path turns %2541 into %41 and reintroduces the double decode.
Revoking a root over POST authorizes against the root the configured IRootCapabilityResolver
returns for that id, never the body's copy, so a root the server cannot resolve is not revocable.
Delegated capabilities are recorded under the delegator that signed them, so a forged copy of an
id under another chain lands in the forger's scope and cannot revoke the genuine capability, even
across roots or verifiers sharing a store. A custom IRevocationStore keys rows by
RevocationRecord.Key, never by the capability id, and migrates 5.x rows to unscoped records. See
Revocation scope.
To customize route prefix:
app.MapZcapRevocationEndpoints("/wallet/revocations");
Expose Revocation in a Different Manner
If you do not want HTTP endpoints, use ZcapLd.Core directly and expose IRevocationService via your preferred transport:
- gRPC
- worker/message-driven services
- admin CLI flows
- contract relayer/oracle processes
Persistence Strategies for Revocation Registries
Register persistence strategy through AddZcapRevocationSupport(...):
- Default in-memory:
builder.Services.AddZcapRevocationSupport();
- Custom type:
builder.Services.AddZcapRevocationSupport<MyRevocationStore>();
- Custom factory (for advanced composition/hybrid stores):
builder.Services.AddZcapRevocationSupport(sp =>
new HybridRevocationStore(/* dependencies from sp */));
See docs/REVOCATION-INTEGRATION.md for full guidance.
Target restrictions
Using ZcapLd.Core.Services, register VerificationPolicy before AddZcapServices() to permit target narrowing:
builder.Services.AddSingleton(new VerificationPolicy { AllowTargetAttenuation = true });
builder.Services.AddZcapServices();
The default requires exact target matches. Applications enforce path/query semantics.
Without registered caveat types, incoming caveat fields are rejected. Version 6
restores AddZcapCaveatType<T>(type) for the opt-in caveat extension profile (#157).
Add AddZcapCaveatHandler<T>() for each type the resource enforces, and register both
before the ZCAP services are first resolved:
builder.Services.AddZcapServices();
builder.Services.AddZcapCaveatType<EpsilonBudgetCaveat>("EpsilonBudget");
builder.Services.AddZcapCaveatHandler<EpsilonBudgetLedger>();
The revocation endpoint accepts caveat-bearing capabilities whose types are registered.
AddZcapValidWhileTrueSupport stays removed: no capability-supplied URL is fetched.
Submit signed revocations to the target verifier and use shared durable revocation state
across replicas.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- ZcapLd.Core (>= 6.0.0)
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 |
|---|---|---|
| 6.0.0 | 43 | 11/3/2026 |
| 5.0.0 | 225 | 10/25/2026 |
| 4.2.0 | 656 | 7/28/2026 |
| 4.1.0 | 148 | 7/14/2026 |
| 4.0.0 | 151 | 6/19/2026 |
| 3.0.0 | 140 | 6/6/2026 |
| 2.1.1 | 130 | 5/2/2026 |
| 2.0.0 | 141 | 4/29/2026 |
| 1.2.0 | 375 | 3/27/2026 |
| 1.1.0 | 311 | 3/18/2026 |
| 1.0.0 | 145 | 3/9/2026 |
| 0.3.3 | 536 | 3/4/2026 |
| 0.3.2 | 222 | 3/1/2026 |
| 0.3.1 | 143 | 3/1/2026 |
| 0.3.0 | 146 | 2/28/2026 |
| 0.2.1 | 209 | 2/26/2026 |
| 0.2.0 | 148 | 2/26/2026 |
| 0.1.1 | 138 | 2/24/2026 |
| 0.1.0 | 142 | 2/24/2026 |