Building DRS: verifiable delegation receipts for AI agents (UCAN v1 / DAG-CBOR) - drowning in spec edges and could use sane eyes

Hi everyone, I'm working on DRS (Delegation Receipt Standard) and I'm basically a lost sheep right now: I know roughly where the pasture is, but I could really use people who've actually shipped capability systems to sanity-check the design and poke holes before I write the first line of implementation code.

What I'm building

AI agents are increasingly calling tools, delegating to other agents, and acting on behalf of users. When something goes wrong, the question is always the same: who authorized this action, with what limits, and can we prove it?

DRS is a portable, verifiable "receipt" for delegation - not "trust our logs," but cryptographic proof of who delegated what to whom, with clear bounds and room for consent and compliance metadata. Think: agents calling tools and other services, with auditors able to reconstruct the full chain of authority in a standard format.

What it is technically

DRS is a UCAN Profile - a constrained, extended use of UCAN v1.0.0-rc.1; not a parallel authorization scheme. I'm building on top of UCAN rather than reinventing delegation chains from scratch (I already tried that; it was a bad idea).

Concretely, the boring spec parts matter a lot:

  • Encoding: v1 is DAG-CBOR / IPLD, not JWT-era v0.x. Mental model "UCAN = JWT + att" is outdated.
  • Delegation: sub, cmd, pol (subject, command path, policy with jq-style selectors and operators like ==, like, all, any).
  • Proofs: prf lives on invocations, not on each delegation -- the chain is assembled at invocation time.
  • Policies: the spec expects runtime evaluation of every delegation's policy against the invocation args (conjunctive across the chain), not a neat "child policy always structurally tightens parent" check.

Why the planned stack looks like this

I'm aiming for infrastructure-grade verification performance, so the design splits across three languages by responsibility:

  • Rust (drs-core) for the hot path: Ed25519 signatures (via ed25519-dalek 2.x with S < L enforced by default), CID computation, DAG-CBOR canonicalization (via serde_ipld_dagcbor, not the deprecated libipld), and capability indexing. Compiles to native + WASM so the browser/TS path never does naive crypto in JavaScript.
  • Go (drs-verify) for the verification service: bounded LRU caches for DID resolution (hard cap 10k entries), status-list cache with TTL and sync.Once concurrency guard, and middleware-shaped integration targeting MCP and A2A interceptor patterns. Single static binary deployment.
  • TypeScript (@drs/sdk) for issuance ergonomics only. Low-frequency path. All crypto delegated to the Rust WASM module.

Where I am now: architecture, language/algorithms doc, technical audit against UCAN v1.0.0-rc.1, diagrams - no implementation code yet. I'll open-source the docs and start coding soon; happy to share drafts

What would help

  • Spec review: prf, pol semantics, CID/canonicalization - catch anywhere I'm still thinking v0.x by accident.
  • Production war stories: UCAN-like systems at scale , caching, revocation/status lists, DID resolution.
  • Contributors for Rust / Go / TS, tests, docs, adversarial review.

If you've touched UCAN, capabilities, SPIFFE-ish identity, or agent middleware, I'd love comments

Interesting project. We've been exploring a similar problem but with a simpler receipt format: Ed25519-signed JSON receipts for tool calls, optional server co-signing, and a local hash-chained audit log (GitHub - Prismer-AI/signet: Cryptographic action receipts for AI agents — sign, audit, verify. · GitHub). We avoided UCAN/DAG-CBOR mostly to keep implementation and debugging simpler, but the delegation semantics in UCAN are obviously attractive.

We ended up sketching delegation chains too, and the hard part we keep running into is root trust: even if the chain verifies, who vouches for the delegation issuer in the first place? Curious how you're thinking about anchoring that.

Thanks for sharing Signet, the Ed25519 + hash-chained local log approach is clean and the simplicity argument is real. Debugging a CBOR-encoded IPLD DAG
is not fun.

The way I anchor it depends on the DID method:

  • did:key: Self-authenticating, the public key is cryptographically embedded
    in the identifier itself. No third party vouches; only the holder of the
    corresponding private key can produce a valid signature. If the DID string is
    in the chain, the issuer is already proven.
  • did:web: Falls back to TLS/PKI. The resolver fetches the DID document over
    HTTPS and the certificate chain does the vouching. Not ideal for all contexts,
    but pragmatic for enterprise deployments where a domain is already the
    identity anchor.
  • Human-rooted delegations: The root DR must carry explicit consent evidence,
    method (explicit-ui-click, etc.), timestamp, session ID, and a SHA-256 of the
    policy text shown to the user. That binds the cryptographic chain to a human
    decision record an auditor can actually inspect.

The did:key needs no vouching because the key is the identity. The trust problem only resurfaces when you want named/mutable identities (did:web), at which point you inherit PKI.

Still a work in progress -- happy to compare notes:
GitHub - OkeyAmy/DRS: Research project showing cryptographic, per-step delegation proofs for accountable AI agent actions. · GitHub