ASP.NET Core agent verification

ASP.NET Core controller for agent authorization (wallet and JWS/JWT)

Example controller that verifies agents by wallet (Path 1) or by JWS/JWT (Path 2). The real API uses IsDelegateAttestationVerifier (with IsDelegateVerifierConfig and IsDelegateVerifierOptions) and AttestedMerkleExchangeReader with a verification context. See the ProofPack .NET READMEarrow-up-right and EXAMPLES.mdarrow-up-right for config and setup.

using Microsoft.AspNetCore.Mvc;
using Zipwire.ProofPack;
using Zipwire.ProofPack.Ethereum;

[ApiController]
[Route("api")]
public class AgentController : ControllerBase
{
    private readonly IsDelegateAttestationVerifier _delegateVerifier;
    private readonly AttestedMerkleExchangeReader _reader;

    public AgentController(IsDelegateAttestationVerifier delegateVerifier, AttestedMerkleExchangeReader reader)
    {
        _delegateVerifier = delegateVerifier;
        _reader = reader;
    }

    [HttpPost("time-tracking/log")]
    public async Task<IActionResult> LogTime([FromHeader] string xAgentWallet)
    {
        // Verify agent is authorized
        var isAuthorized = await _delegateVerifier.VerifyByWalletAsync(xAgentWallet);

        if (!isAuthorized)
        {
            return Forbid("Agent not authorized by verified human");
        }

        // Process time entry
        return Ok(new { message = "Time logged successfully" });
    }

    [HttpPost("payments/claim")]
    public async Task<IActionResult> ClaimPayment([FromHeader] string authorization)
    {
        if (!authorization?.StartsWith("Bearer ") == true)
        {
            return BadRequest("JWS or JWT required for payment claims");
        }

        var jws = authorization.Substring(7);
        var result = await _reader.ReadAsync(jws, verificationContext);

        if (!result.IsValid)
        {
            return Forbid("Invalid authorization proof");
        }

        var claims = result.Document.MerkleTree.Leaves;

        // Verify claims meet payment requirements
        if (!claims.ContainsKey("verifiedHuman") || !bool.TryParse(claims["verifiedHuman"], out var isHuman) || !isHuman)
        {
            return Forbid("Payment requires human verification");
        }

        // Process payment claim
        return Ok(new { message = "Payment processed", agentWallet = result.AgentWallet });
    }
}

Full guide: ProofPack & Agent Delegation.

Last updated