Writing

Explainer

How an AI agent signs in with a credential of its own

For identity and security engineers. How an AI agent gets an SD-JWT VC over OpenID4VCI, keeps it in a wallet it cannot open, and signs in over OpenID4VP, in eight interaction points.

In An agent with a credential of its own, Ada’s personal agent gets a digital ID from Agent Registry, keeps it in a wallet it cannot open, and uses it to sign in at Lantern Tickets and hold two seats. The point is that the agent doesn’t carry an API key for each site: it proves who it is with one credential of its own, which any site that trusts the registry can check. This is how that works, one interaction at a time. Ada, Agent Registry and Lantern Tickets are made-up names; everything else is real, running software.

The recording above is one real run, sped up where the agent is thinking. Claude is the agent here; the same flow also runs with OpenClaw.

The setup

Agent Registry issues an agent credential to the agent's wallet over OpenID4VCI. The wallet presents it to Lantern Tickets over OpenID4VP. The agent talks to its wallet over A2WP, as an MCP server, and Ada talks to her agent in chat.
  • The agent is Claude, in the Claude desktop app, using its built-in browser. We have also run the same flow with OpenClaw, an open-source personal agent, in its own Linux VM. Either way the agent holds no site API keys, only one API key for its wallet.
  • Agent Registry issues credentials with OpenID4VCI (OpenID for Verifiable Credential Issuance).
  • Lantern Tickets asks for credentials with OpenID4VP (OpenID for Verifiable Presentations).
  • The agent’s wallet is built on the open-source EUDI (EU Digital Identity) wallet libraries. It runs outside the agent’s machine and holds the keys and credentials.
  • Agent and wallet talk with A2WP, our draft agent-to-wallet protocol, carried over MCP (Model Context Protocol), the standard way agents call tools.

The credential is an SD-JWT VC: a signed credential whose fields can be shown one at a time. It has five fields. The agent ID is always shown; the name, runtime, operator (the person responsible for the agent) and accreditation level (how thoroughly the registry checked it) are shown only when asked for. It is valid for 90 days and bound to a key that only the wallet holds. Each time the credential is shown, the wallet signs with that key, so a copied credential is useless.

Getting the credential

1. Ada and Agent Registry

Ada registers the agent and asks for an offer. The registry returns a one-time offer link, valid for ten minutes. Whoever redeems it first gets the credential, so it should reach the wallet quickly. In this demo the link alone is enough; a one-time PIN would tie it to Ada. The registry also has a single operator, Ada, and doesn’t verify who she is; a real registry would sign her in and check before naming her as the operator.

Ada registers her agent at Agent Registry and receives an agent ID. She requests an offer and receives a one-time offer link, valid for ten minutes.

2. Ada and her agent

Ada pastes the link into the chat. The chat carries the link, never the credential or its key. Until the wallet redeems it, anyone who sees the link could claim the credential, which is why it works once and only for ten minutes.

Ada sends the offer link to her agent in chat, and the agent reports that the credential is stored.

3. The agent and its wallet: collect

The agent submits the link to its wallet exactly as it got it, with the same submit call it later uses for the sign-in link. The wallet works out that this is an offer. Every A2WP call carries the agent’s own API key, which tells the wallet whose credentials and policy apply. The answer is an operation with a status, never the credential itself. Submitting the same link again returns the same operation, so a retry cannot redeem the offer twice.

The agent submits the offer link to its wallet and receives a completed operation.

4. The wallet and Agent Registry: OpenID4VCI

The pre-authorized code flow, about a second end to end. Before redeeming the code, the wallet checks that its policy allows this issuer. It makes a fresh key for the credential and proves it holds it. When the credential arrives, it checks the issuer’s signature and certificate chain before storing it.

The wallet fetches the offer and its pre-authorized code, exchanges the code for an access token, gets a nonce, and requests the credential with a proof signed by a new key. The registry returns the agent credential as an SD-JWT VC.

Using the credential

5. The agent and Lantern Tickets

Ada asks for two tickets, and the agent shops in its browser. At checkout it clicks Continue with wallet, and Lantern shows an Open in wallet link. Lantern ties the wallet’s answer to this checkout: when the wallet answers, Lantern hands back a one-time continuation link, and only the browser that started the checkout can use it to finish signing in.

The agent picks seats, checks out and chooses Continue with wallet. Lantern shows an openid4vp sign-in link. After the wallet has answered, the agent opens the continuation link in its browser, Lantern welcomes the agent, the agent holds the seats and Lantern confirms.

6. The agent and its wallet: sign in

The agent submits the sign-in link exactly as it found it, and gets back an operation. It completes once Lantern has accepted the wallet’s answer, and carries Lantern’s continuation link, unchanged.

The agent submits Lantern's sign-in link to its wallet and receives a completed operation with Lantern's continuation link.

7. The wallet and Lantern Tickets: OpenID4VP

The request is signed with a certificate that chains to a root the wallet trusts, and the certificate’s DNS name must match Lantern’s client ID, so the wallet knows who is asking. The wallet’s policy decides which sites may see which fields. Lantern asks for all five fields; another site could ask for the agent ID alone. The wallet adds a key-binding signature over Lantern’s ID, the request’s nonce and exactly what it disclosed, then posts the answer straight to Lantern, not through the agent. Lantern replies with a continuation link carrying a one-time response code.

The wallet fetches Lantern's signed request with its DCQL query, checks that the certificate matches Lantern's domain and that its policy allows the requested fields, then posts the agent credential with the requested fields and a key-binding JWT directly to Lantern. Lantern replies with a continuation link.

8. Lantern Tickets: verify and sign in

Lantern checks everything itself. When the agent’s browser opens the continuation, Lantern redeems the response code for that checkout and opens an account keyed to the agent ID, so the next sign-in finds the same account. Lantern trusts a single registry; a site that trusted several would key accounts to the issuer and the agent ID. Revocation and status checks are out of scope for this demo.

Lantern checks the issuer's signature and dates, that the issuer is allowed and its certificate chains to a trusted root, the key binding, and that every requested field is present. When the agent's browser opens the continuation, it signs that browser in to an account keyed to the agent ID.

What the agent can and cannot do

The agent can ask its wallet to act and ask how it went. It holds only an API key for talking to the wallet. It cannot read the wallet’s signing keys or credentials, and it doesn’t pick the fields: Lantern’s request names them and the wallet’s policy decides. If a web page tricks the agent, it can start a sign-in that the wallet’s policy already allows, or leak the API key the agent uses to talk to its wallet. The credential and its keys stay in the wallet either way, but whoever holds that API key can ask for the same sign-ins the agent can, so the key must be easy to rotate. Without status checks, the credential itself cannot be withdrawn before it expires. The continuation also closes a gap common to cross-device sign-ins. If a page hands the agent a sign-in link that someone else started, the continuation still comes back to the agent’s own browser, so the other person’s checkout never signs in.

What is next

Lantern’s sign-in takes a person’s credential as well as an agent’s. For how an agent can carry a fact Ada delegates to it, such as being over 18, next to its own credential, see Your AI agent can prove you’re over 18 without holding your credential.

The issuer and verifier run on walt.id’s open-source services, the wallet on the EUDI wallet libraries, and the agent is unmodified Claude (or OpenClaw).