NorthBuild
buyer
Trust Layer
neutral issuer
Cobalt
holder
Meridian
verifier
AnchorRegistry
on-chain ledger
AgentID by J. Cabello
⇄ A2A Agent2Agent · on
/ 07
INVOICE FACTORING ·
the truth — signed event

  
⚓ verifiable anchoring — the Trust Layer cannot rewrite its past

Every vc.issued, agent.registered and vp.verified is salted-hashed into a Merkle batch; batches are hash-chained and the roots anchored on-chain (AnchorRegistry). "Verify in MY browser" recomputes the whole chain with WebCrypto and reads the on-chain root straight from the RPC — without trusting this server.

GENESIS sha256("agentid-genesis-anchor")

no batches yet — run a flow and the worker folds it within a minute

⌕ agent discovery — straight from the ERC-8004 registry, no directory trusted

These entries are read from the IdentityRegistry ERC-721 — each agent is an NFT owned by its organisation's account, pointing at a Registration File. The raw context lets anyone re-verify against any node. The chain check runs in YOUR browser: WebCrypto verifies the ES256 signatures — this page cannot fake them.

no agents minted on-chain yet — the publisher sweeps the registry every minute

◈ trust levels — the DID hierarchy

Payment scope requires registered or higher: genesis ▸ org ▸ registered may authorize payments; traced_ephemeral and bilateral may not. The node badges above read the live registry — Genesis, Org, Registered, Traced-ephemeral, Bilateral.

theory — for whoever wants to know more
The stack — everything on this page is served by it
NorthBuild · buyer
FastAPI · AgentCard · pay VP
Cobalt · supplier
FastAPI · flow engine · A2A client
Meridian · finance
TypeScript · A2A JSON-RPC server
↕ KYC-A onboarding · org-signed credentials · verifiable presentations · X-Flow-ID tracing
Trust Layer — neutral registry (FastAPI, 11 enforced module contracts)
KYC-A/KYB-A · SD-JWT-VC & vc-jwt · payment matrix · SSE · anchoring queue · serves THIS page
↕ eth_call (read) · publisher sidecar (write: mint, validate, anchor)
Anvil devnet · chain 31337
ERC-8004 Identity + Validation · AnchorRegistry (Merkle hash-chain)
↕ did:web resolution · domain challenges (KYB-A)
nginx did:web resolver
did.json per authority · ERC-8004 Registration Files

Two open SDKs (python + node) implement the same crypto contracts, cross-tested byte-for-byte. Deployed as a single docker compose behind a Caddy edge — what you are looking at is the production stack, not a diagram of intent.

Self-owned identity — the DID

A DID is an address you own because you hold its private key — like an email address no provider can confiscate or impersonate. Each agent generated a keypair and published a DID document: "this is my public key, this is where to reach me."

Before the network trusts an agent, it passes KYC-A ("Know Your Agent"): register the DID, prove key control by signing a fresh challenge, declare capabilities, get them approved, receive an agent credential. From then on every message it sends can be checked against its public key.

did:webDID documentchallenge–responseKYC-A · 5 steps
AGENT (each of 3) TRUST LAYER 1 · register DID (did:web) 2 · fresh challenge (nonce) 3 · nonce signed with private key 4–5 · capabilities approved · credential issued the key never leaves the agent — only signatures travel
fig. 01 — the KYC-A ceremony
Authenticated channels

The order itself is ordinary business data — no cryptography in the payload yet. What matters is who is speaking: every agent-to-agent request rides an authenticated handshake where each side proves control of its DID key, so NorthBuild knows it's really Cobalt, and vice versa.

That kills impersonation before the interesting part starts: you can't forge an invoice conversation if you can't sign as the counterparty.

auth handshakemutual DID authsigned requests
NORTHBUILD COBALT 1 · hello — here's my DID 2 · prove it: sign this nonce 3 · signature over nonce authenticated channel open
fig. 02 — mutual authentication, both directions
Credentials built for hiding — SD-JWT

The Trust Layer doesn't sign the invoice fields directly. It salts and hashes each fact separately, then signs the list of hashes. The signature covers everything — yet each fact can be shown or withheld later without breaking it.

Think of a passport that can prove "over 18" without showing your birthdate. The trick is decided at issuance: hiding must be designed in from the start.

The credential is also bound to Cobalt's key (cnf), so only Cobalt can use it.

SD-JWTsalted hashesdisclosurescnf · holder key
invoice number amount currency due date confirmation date goods payment terms salt + hash 7 salted hashesno facts inside sign · ES256 SD-JWT CREDENTIALsignature over the list Cobalt's wallet (holder) any subset provable later — signature stays intact
fig. 03 — issuance: hiding is designed in
Presentations — show, don't tell

Cobalt doesn't send the credential to the bank. It builds a Verifiable Presentation: the signed hash-list plus only the disclosures it chooses to open. The hidden facts travel as opaque hashes — present, verifiable, unreadable.

It adds a key-binding proof (KB-JWT): a signature over the bank's fresh nonce, made with the same key the credential was issued to. Stolen credentials die here — a thief can't produce that signature.

VPdisclosure setKB-JWTaudience + nonce
SD-JWT credentialhash list · signed shown disclosures openedamount · dates · currency… sealed stay opaque hashesterms · goods VERIFIABLEPRESENTATION+ KB-JWT over bank's nonce → Meridian Bank hidden facts travel as hashes — present, verifiable, unreadable
fig. 04 — building the presentation
The verification math

Meridian checks four things: the Trust Layer's signature on the hash-list; that each opened fact hashes to an entry in that list; that the KB-JWT was signed by the credential's holder key over Meridian's own nonce; and that nothing is expired or revoked.

For the sealed facts, the hashes prove they exist and were covered by the signature — while revealing nothing about their content. That's the asymmetry that keeps selective disclosure honest: you can hide, but you can't lie.

signature verifyhash matchingholder bindingfreshness
VP arrives from Cobalt signature validissuer key hashes matcheach opened fact holder bindingKB-JWT key match nonce freshno replay APPROVED — factoring authorized
fig. 05 — the verification chain: four checks, no phone calls
Why the bank pays on proof

Factoring fraud is usually a data problem: invented invoices, inflated amounts, the same invoice sold twice. Each one forces the bank to distrust the document and call the buyer.

Here the document proves itself: the buyer's confirmation is cryptographically inside the credential, the amount can't change without breaking the signature, and holder binding stops resale of someone else's invoice. Verification is instant — capital moves in minutes, not weeks.

fraud vectors ↓advance rateinstant verification
Invoice€48,500 · net 60 advance 80%€38,800 now fee 1.5%− €727.50 Cobalt receives €38,072.50 todayminutes after presenting proof at maturity: NorthBuild pays €48,500bank recoups advance + margin
fig. 06 — where the money goes
The trust triangle

The pattern generalizes: an issuer signs claims, a holder stores them and chooses what to show, a verifier checks math instead of making phone calls. Nobody needs a shared database — and the issuer never learns where the credential gets used.

Swap invoices for diplomas, licenses, KYC files or agent permissions — the machinery is identical. That's what AgentID proves: agents that can trust each other's claims without trusting each other.

issuer–holder–verifierprivacy by designA2A trust
TISSUER · Trust Layer CHOLDER · Cobalt MVERIFIER · Meridian issues credential presents proof (VP) trusts the signatureno phone call needed
fig. 07 — the trust triangle
Three agents, each proven by KYC-A.
NorthBuild orders — an invoice is born.
Purchase Order
Goods
Due
Amount
The Trust Layer signs a tamper-proof credential.
TL
Holds 7 facts. Any subset provable later.
shown · sealed — still provably real.
Tap a field to move it, then send.Disclosure sent — locked.
SHOWN TO BANK
nothing shown
KEPT SEALED
full disclosure
Meridian verifies — without seeing the sealed facts.
Trusting the proof, Meridian advances the cash.
Factoring approved
Invoice value
Advance rate
Fee (1.5%)
Paid to Cobalt now
Money moved on proof alone.
advanced
facts sealed
0
middlemen
TRANSPORT · real backend I/O
$ press Next to fire the first real call…
LIVE COORDINATION ROOM
Watch three agents close a factoring deal — for real.
No script. Every hop is a real HTTP call between agents — the terminal shows the raw request/response traffic, distilled live.
Deal closed — proof alone moved the money.
Stopped — a real rejection
TRANSPORT · live backend I/O
$ awaiting backend calls…
SELF-CUSTODY · your browser ⇄ backend
$ your agent hasn't spoken to the backend yet…