The problem: agents making payments are cryptographically anonymous
When an AI agent calls a payment tool today, the payment system receives a request authenticated by an API key. It knows the request came from a client. It does not know which agent, acting on whose behalf, under what authority, within what scope. If something goes wrong — an overspend, an erroneous payment, a compliance audit — there is no cryptographic chain of evidence.
This is the agent identity gap. Traditional payment authorization is built around human identity: a card requires physical possession, open banking requires SCA with a bank. As AI agents become economic actors — spending money, executing contracts, managing subscriptions — the same question applies: who, exactly, is doing this?
What KYA-OS provides: three primitives
KYA-OS (Know Your Agent Operating System) is an open standard from the DIF Trust and Agent Authorization Working Group. It describes itself as analogous to TLS: not a transport, but a security layer that transports embed. It does three distinct things:
Every agent holds an Ed25519 key pair encoded as a Decentralized Identifier. Stable, self-certifying, resolvable over HTTPS. No central registry.
Delegation chains root at a Responsible Party. Each hop narrows scope. High-risk tools are gated by consent — a human must issue a signed VC before the tool runs.
Every tool response carries a JSON Web Signature over the SHA-256 hashes of the request and response. Invisible to the LLM. Verifiable by anyone with the public key.
The key insight is that all three work together. A proof without identity is useless — you cannot verify who signed it. Identity without accountability is insufficient — you know who the agent is but not what it did. Accountability without authority is incomplete — you have a record but no proof the agent was permitted to act. KYA-OS binds all three into a single, verifiable chain.
The architecture: four services, one identity
We built a complete end-to-end implementation as four Docker services running in the Bankee.ai dev environment. All four services share a single persistent identity: did:web:bankee.ai.
:3001:3002:3003:3010The payment server is the MCP-facing surface: it exposes five payment tools, wraps every response with a KYA-OS proof, and gates high-value operations behind a consent check. The consent service acts as the Responsible Party — it issues W3C Verifiable Credentials when a human approves a request, maintains a StatusList2021 revocation list, and supports multi-hop sub-delegation. The audit service records every proof from the payment server and can verify any proof offline using a pre-loaded trusted key cache. The web UI aggregates all three into a management dashboard at port 3010 on the Tailscale network.
The identity is anchored at bankee.ai/.well-known/did.json — a standard W3C DID document containing the Ed25519 public key in both multibase and JWK formats. Any external party can resolve this DID, retrieve the public key over HTTPS, and independently verify any proof or credential produced by this infrastructure.
What a proof looks like — and what it proves
Every tool response from the payment server carries a detached JWS proof in the _meta field. The language model never sees it — it lives in the metadata envelope, not the tool content. Here is the structure:
The jws is a detached JSON Web Signature. The signing input is header.payload where the payload is the canonical form of the meta object. The signature is produced with the Ed25519 private key corresponding to did:web:bankee.ai#key-1. To verify: resolve the DID, extract the public key, reconstruct the canonical payload, check the signature. Any party in the world can do this — no callback to Bankee required.
The requestHash and responseHash bind the proof to the specific tool call. If an attacker intercepts the proof and replays it with a different response, the hash mismatch will be detected. The nonce prevents replay of the proof itself — each nonce is stored in a cache and rejected if seen again.
What a Verifiable Credential looks like — and what it authorises
Some tools should not run without a human saying yes. create_payment above £100 is wrapped with wrapWithDelegation. Without a valid delegation credential, the agent receives a structured refusal — not an error, but a specific needs_authorization response with a consent URL:
The human navigates to the consent URL, reviews the request, and approves. The consent service issues a W3C Verifiable Credential:
The VC is stored on the payment server under the resume_token. When the agent retries, the server auto-applies the delegation. The tool executes. The response carries a proof that references the VC — binding identity, authority, and the specific action into a single, non-repudiable record. The credentialStatus field means the VC can be revoked at any time by flipping bit 0 in the StatusList2021 revocation list. Anyone checking revocation fetches the compressed bitstring from the statusListCredential URL and checks the bit — no need to contact the issuer.
The live demo: 11 steps, all verified
We ran the full end-to-end demo against the live Bankee.ai infrastructure. Here is the unedited output, with annotations on what each step proves.
Steps 0–1: Services ready, identity confirmed, session established
The handshake establishes a KYA-OS session: the client sends a nonce, a timestamp, and the server's expected DID. The server validates all three — timestamp within ±120 seconds, nonce not previously seen, audience matches its own DID — and returns a session ID. This session ID is included in every subsequent proof, binding all tool calls to a single authenticated session and preventing cross-session replay.
Steps 2–3: Proof-only tools — every response is signed
These tools require no delegation — they carry only proof. The proof binds the specific question asked (requestHash) and the specific answer given (responseHash) to the server's DID and session. If either is tampered with in transit, the hashes will not match. The LLM sees only the tool result; the infrastructure sees the cryptographic receipt.
Step 4: Autonomous payment — below the consent threshold
The £50 payment is below the £100 high-value threshold. It executes autonomously — no consent required. Notice that did:web:bankee.ai is recorded directly in the payment record as the agent DID. Any downstream AML system can trace this payment back to the identity, verify the signature, and confirm the request/response integrity — all without calling Bankee.
Steps 5–7: Consent gate, VC issuance, and retry
Three things happen in sequence: the gate fires, a human explicitly approves, a credential is issued, and the credential is automatically applied on retry. The delegation VC is stored on the payment server under the resume_token. On retry, the server checks for a stored VC matching the agent's session, verifies it is signed by the trusted Responsible Party DID, checks the scope and expiry, and permits the tool to execute. The response proof then references the delegation chain — creating a complete, verifiable audit record: who asked → who authorised → what was done.
Steps 8–10: Status, history, and the audit trail
Every tool call generates a proof record that is forwarded to the audit service via webhook. Records are append-only and immediately verified on receipt. The audit service uses a pre-loaded trusted key cache — it holds did:web:bankee.ai's Ed25519 public key locally, so it can verify proofs without any outbound network call.
Step 11: Cryptographic proof verification — the final confirmation
This is the critical step. An independent service — the audit service — took a proof from a completely different part of the system (the balance tool response from step 2), resolved the signer's DID using the pre-loaded trusted key, reconstructed the canonical payload from the proof metadata, and verified the Ed25519 signature. It confirmed: the signer was did:web:bankee.ai, the signature was produced at a specific time, and the session is traceable. The entire verification is deterministic and requires no trust in Bankee — only in the mathematics of Ed25519.
Test results: 11/11 steps verified
Unedited results from the live Bankee.ai dev environment:
Why this matters for compliance
PSD2/PSD3 Strong Customer Authentication
PSD2 SCA requires at least two independent authentication factors for payment initiation. KYA-OS's Ed25519 key pair satisfies the possession factor cryptographically — the agent proves it controls the private key by signing the proof. The consent gate + delegation VC provides the human approval factor. Together they produce a PSD3-compatible authentication record for machine-initiated payments, without a human being present in the transaction loop.
AML — beneficial owner tracing
Anti-money laundering monitoring requires knowing the beneficial owner of a transaction. When an AI agent initiates a payment, the did:web:bankee.ai in the proof points to the Responsible Party — the human or organisation ultimately accountable. The delegation chain shows exactly which human approved the specific action. The audit trail is cryptographically non-repudiable.
GDPR Article 22 — automated decision-making
Article 22 requires that automated decisions affecting individuals are subject to human review and explainability. KYA-OS's audit trail provides the explainability record. The consent gate provides the human review intervention point. The signed VC is the documented, verifiable record that a human explicitly approved a specific agent action.
StatusList2021 revocation — revoking authority instantly
If a delegation credential needs to be revoked — agent compromised, scope exceeded, human changes their mind — a single API call flips bit 0 in the StatusList2021 bitstring. The revocation list is publicly accessible at /api/status-list. Any verifier checking the credential can download the compressed list and check the bit in milliseconds. No need to contact the issuer. No centralised revocation oracle.
What makes this different from API key auth
API key authentication answers one question: is this a valid key? KYA-OS answers five:
Run it yourself
The full source, Docker Compose files, and deployment guide are in the public repo. Clone it, generate an identity, and run the 11-step demo against live infrastructure in under 5 minutes.