| Internet-Draft | A2WP | October 2026 |
| Senarath | Expires 20 April 2027 | [Page] |
- Workgroup:
- Network Working Group
- Internet-Draft:
- draft-senarath-a2wp-01
- Published:
- Intended Status:
- Standards Track
- Expires:
Agent-to-Wallet Protocol for Digital Credentials (A2WP)
Abstract
AI Agents acting for people and organizations meet credential offers and presentation requests, for example when a website asks the Agent to prove an attribute before it continues. An AI Agent can be misled by the content it processes, so it should not possess credentials or keys, or decide what to disclose.¶
This document defines the Agent-to-Wallet Protocol (A2WP), with which an AI Agent passes such an offer or request to a Wallet exactly as it received it. The Wallet decides whether to act, obtains approval when needed, and performs the issuance or presentation with the Issuer or Verifier. The AI Agent learns the outcome and receives any continuation the Issuer or Verifier returns, so it can resume its task. Credentials, presentations and keys never reach the AI Agent.¶
Status of This Memo
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 20 April 2027.¶
Copyright Notice
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
1. Introduction
AI Agents increasingly act for people and organizations: they browse, buy and sign up on a Principal's behalf. Along the way they meet digital credentials. An Issuer may offer the Agent a credential, and a Verifier, such as a website at checkout, may ask the Agent to prove an attribute before it continues. These offers and requests arrive as links, QR codes or HTTP challenges.¶
An AI Agent is a poor place to keep credentials. It acts on content it does not control, and instructions hidden in that content can steer it. An Agent that possesses credentials and keys can be talked into disclosing them, or into presenting them to the wrong party.¶
A2WP separates the two roles. The Agent finds the offer or request and passes it to a Wallet exactly as it received it. The Wallet decides whether to act, asks the Principal when its policy requires, and runs OpenID4VCI or OpenID4VP with the Issuer or Verifier. The Agent sees only the operation's status, any link it must pass to the Principal, and the continuation. The continuation is the value the Issuer or Verifier returns so the Agent can resume its task, such as a redirect back into the checkout.¶
request, as received
Agent -------------------------> Wallet <-----------> Issuer or
<------------------------- OpenID4VCI Verifier
continuation, as received OpenID4VP
¶
A2WP passes data through at both ends: the request goes in unchanged and the continuation comes out unchanged. It does not replace OpenID4VCI or OpenID4VP. The Wallet speaks those protocols; A2WP only connects the Agent to the Wallet.¶
1.1. Scope
This document defines the messages and calls between an Agent and a Wallet (Section 3), and how OpenID4VCI and OpenID4VP requests map onto them (Section 4).¶
The Agent is the Holder of the credentials the Wallet keeps for it. The Wallet does not keep the Principal's own credentials or keys; Appendix A.4 shows how a Principal can delegate a credential for a single presentation.¶
The following are out of scope:¶
-
bindings, meaning how the calls are carried and how the Wallet authenticates the Agent;¶
-
Wallet policy, meaning which Issuers and Verifiers it trusts and when it asks the Principal;¶
-
the interaction user interface;¶
-
credential formats and contents;¶
-
delegation mechanisms;¶
-
Wallet internals, such as storage and key management.¶
2. Terminology
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
- AI Agent (Agent):
-
Software that uses a language model to plan and carry out tasks for a Principal. It is the A2WP client.¶
- Principal:
-
The person or organization an Agent acts for. The Principal approves the Agent's operations when the Wallet asks.¶
- Wallet:
-
The A2WP service that keeps credentials and keys for Agents, decides whether to act on a request, and runs the external credential protocol.¶
- Issuer and Verifier:
-
The Issuer issues credentials. The Verifier requests presentations.¶
- counterparty:
-
The Issuer or Verifier that produced a request.¶
- Holder:
-
The entity on whose behalf a credential is held and presented. In A2WP the Holder is the Agent; the Wallet holds its keys.¶
- request:
-
A credential offer or presentation request, as the Agent received it.¶
- operation:
-
The Wallet's processing of one request: an issuance or a presentation.¶
- interaction:
-
A step in which the Wallet involves the Principal, such as approval or entering a transaction code.¶
- continuation:
-
A value the counterparty returns to the Wallet so the Agent can resume its task, such as a redirect URI.¶
- commit point:
-
The step after which an operation can no longer be cancelled: redeeming the pre-authorized code, or sending the presentation (Section 4).¶
- binding:
-
A specification that carries the calls over a transport and defines how the Wallet authenticates the Agent.¶
3. Protocol
3.1. Overview
The Agent submits a request and receives an operation. It calls Get
until the operation is terminal. While the operation is pending, the
Wallet may need the Principal; the operation then carries an
interaction, which the Agent relays. When the operation ends, the
Agent resumes its task, using the continuation if there is one.¶
Submit
|
v
+---------+ Cancel, before the commit point
| pending |----------------------------------> cancelled
+---------+
| |
v v
completed failed
¶
Two rules apply to every call:¶
-
The Wallet MUST NOT return to the Agent private keys, credentials, or the presentations it sends.¶
-
The Wallet MUST scope operations to the Agent that submitted them, and MUST use credentials it acquired for an Agent only in that Agent's operations.¶
Messages are JSON objects [RFC8259]. Recipients MUST ignore members they do not recognize.¶
3.2. Calls
- Submit:
-
Takes a submission and returns an operation, new or existing (Section 3.8). Rejected with
unsupported-requestif the submission has norequeststring.¶ - Get:
-
Takes an operation
idand returns the operation. Rejected withnot-found. A binding can let the Agent wait for a change.¶ - Cancel:
-
Takes an operation
idand returns the operation (Section 3.5). Rejected withnot-foundornot-cancellable.¶
A binding defines how calls and rejections are carried.¶
3.3. Submission
-
request: -
REQUIRED string. The request exactly as the Agent received it, such as a link, the content of a QR code, or the value of an HTTP challenge.¶
The Agent MUST NOT modify the request and MUST NOT dereference it or anything in it. The Wallet identifies the request and MAY dereference it to do so.¶
3.4. Operation
-
id: -
REQUIRED string. Unique among the Wallet's operations for the Agent.¶
-
status: -
REQUIRED string:
pending,completed,failedorcancelled(Section 3.5).¶ -
interaction: -
OPTIONAL object (Section 3.6). Present only while
statusispendingand the Wallet needs the Principal.¶ -
continuation: -
OPTIONAL string (Section 3.7). Present only when
statusiscompletedorfailed.¶ -
error: -
Object with a REQUIRED
codemember (Section 5). REQUIRED whenstatusisfailed, absent otherwise.¶
3.5. Lifecycle
-
pending: -
The Wallet is working on the operation or waiting for the Principal.¶
-
completed: -
The completion condition of the mapping (Section 4) is met.¶
-
failed: -
The Wallet stopped without completing. The
errorsays why.¶ -
cancelled: -
The Agent cancelled the operation before the commit point.¶
The pending status is the only nonterminal status. A terminal status
does not change. While an operation is pending, the Agent SHOULD keep
calling Get until it is terminal.¶
Cancel before the commit point stops the operation and returns it as
cancelled; cancelling a cancelled operation returns it again. After
the commit point, or once the operation is completed or failed,
Cancel is rejected with not-cancellable.¶
If the request, the interaction or a time limit set by the Wallet
expires before the commit point, the operation fails with expired.
If the counterparty rejects the exchange, or the Wallet fails for a
reason of its own, the operation fails with processing-error. If the
Wallet stops after the commit point without knowing the outcome, the
operation fails with outcome-unknown.¶
3.6. Interaction
When the Wallet needs the Principal, for approval or for a secret such
as a transaction code, the operation stays pending and carries an
interaction object:¶
-
uri: -
OPTIONAL string. An HTTPS URI where the Principal completes the interaction.¶
-
expires_at: -
OPTIONAL string. An [RFC3339] date-time when the interaction ends.¶
The Agent SHOULD relay the URI to the Principal. If no URI is given, the Wallet reaches the Principal another way. The Agent does not take part in the interaction.¶
The Wallet MUST obtain any secret the external protocol needs from the Principal, such as a transaction code, through interaction, never from the Agent.¶
3.7. Continuation
If the counterparty returns a continuation, the Wallet MUST put it in the operation unchanged, whether the operation completed or failed. The Agent SHOULD use it where it received the request:¶
-
for a request shown in a user agent, open the continuation in that same user agent session;¶
-
for a request returned as an HTTP challenge, send the continuation back to that resource as the resource specifies.¶
Without a continuation, the Agent continues as the counterparty directs.¶
3.8. Repeated Submissions
If an Agent submits a request string it has submitted before, the Wallet MUST return the most recent operation for it, unless that operation ended before its commit point; the Wallet then MUST create a new operation. The Wallet SHOULD keep an operation that passed its commit point for as long as the request could be submitted again.¶
4. Protocol Mappings
A mapping fixes, for one external protocol, what the Agent can observe. The Wallet follows the external protocol itself. This document maps OpenID4VCI [OPENID4VCI] and OpenID4VP [OPENID4VP]; other specifications can define further mappings.¶
| OpenID4VCI | OpenID4VP | |
|---|---|---|
| Request | Credential Offer with a pre-authorized code | Authorization Request |
| Operation | issuance | presentation |
| Commit point | redeeming the pre-authorized code | sending the presentation |
| Completed when | every requested credential is obtained, validated and kept | the Verifier accepts the Authorization Response |
| Continuation | none | the redirect URI the Verifier returns |
Other requests are unsupported-request. Under deferred issuance, the
operation stays pending until the credentials arrive. Returning the
Verifier's redirect URI to the Agent is how the Wallet redirects the
user agent that showed the request.¶
5. Errors
| Code | Meaning |
|---|---|
unsupported-request
|
The Wallet does not recognize or support the request. |
denied
|
The Wallet or the Principal refused, or the counterparty is not trusted. |
no-matching-credential
|
No permitted credential satisfies the request. |
expired
|
The request, the interaction or a Wallet time limit expired before the commit point. |
processing-error
|
The counterparty rejected the exchange, or the Wallet failed. |
outcome-unknown
|
The Wallet stopped after the commit point without knowing the outcome. |
not-found
|
No such operation exists for this Agent. |
not-cancellable
|
The operation is past its commit point or has completed or failed. |
Section 3.2 lists the rejections; every other failure appears in an
operation's error. An Agent treats an unrecognized code as
processing-error.¶
Error codes can reveal what the Wallet holds. A Wallet MAY report
denied in place of no-matching-credential.¶
After outcome-unknown, the Agent MUST NOT submit a request for the
same transaction again without the Principal's agreement; the issuance
or presentation may already have happened.¶
6. Security Considerations
6.1. Manipulated Agents
An AI Agent can be steered by instructions hidden in the content it processes. A2WP limits the damage: the Agent never receives credentials, presentations or keys. The Agent does decide which requests to submit, and so, indirectly, what of its credentials is disclosed and to whom. Wallet policy and, where policy requires it, the Principal's approval bound those choices. A Wallet that approves every request automatically lets a manipulated Agent disclose anything its trust list allows.¶
6.2. Agent Authentication
A2WP relies on the binding to authenticate the Agent. Operations, credentials and approvals are scoped to the authenticated Agent, so a binding that authenticates weakly lets one Agent act as another.¶
6.3. Trusted Counterparties
The Wallet decides which Issuers and Verifiers it trusts, for example
by a trust list, and refuses the others with denied. Without that
check, an Agent could be led to accept credentials from, or present
them to, any party.¶
6.4. Relayed Requests
An Agent submits whatever request it meets. A page can show a request taken from another party's session with the same Verifier; presenting then completes that other session. The continuation defends against this when the Verifier completes a session only once the continuation is redeemed in the session that showed the request, as with an OpenID4VP response code. A Verifier that completes its session in another way, such as by polling, has no such protection.¶
6.5. Interaction URIs
The interaction URI passes through the Agent and messaging services. The Wallet MUST authenticate the Principal during the interaction, and dereferencing the URI MUST NOT approve anything. A compromised Agent can also send the Principal a look-alike page; Wallets SHOULD use phishing-resistant authentication.¶
6.6. Continuations
A continuation can be a capability for the counterparty's session. An Agent that sends it anywhere other than where the request came from hands that session to the recipient (Section 3.7).¶
6.7. Untrusted URIs
Requests contain URIs from untrusted parties. Wallets SHOULD NOT let these URIs reach internal networks.¶
7. IANA Considerations
This document has no IANA actions.¶
8. References
8.1. Normative References
- [OPENID4VCI]
- Lodderstedt, T., Yasuda, K., Looker, T., and P. Bastian, "OpenID for Verifiable Credential Issuance 1.0", , <https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html>.
- [OPENID4VP]
- Terbu, O., Lodderstedt, T., Yasuda, K., Fett, D., and J. Heenan, "OpenID for Verifiable Presentations 1.0", , <https://openid.net/specs/openid-4-verifiable-presentations-1_0.html>.
- [RFC2119]
- Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/rfc/rfc2119>.
- [RFC3339]
- Klyne, G. and C. Newman, "Date and Time on the Internet: Timestamps", RFC 3339, DOI 10.17487/RFC3339, , <https://www.rfc-editor.org/rfc/rfc3339>.
- [RFC8174]
- Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/rfc/rfc8174>.
- [RFC8259]
- Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, , <https://www.rfc-editor.org/rfc/rfc8259>.
8.2. Informative References
- [I-D.gco-oauth-delegate-sd-jwt]
- Oliver, G., "Delegate SD-JWT", Work in Progress, Internet-Draft, draft-gco-oauth-delegate-sd-jwt-00, , <https://datatracker.ietf.org/doc/html/draft-gco-oauth-delegate-sd-jwt-00>.
Appendix A. Examples
Line breaks and indentation within string values are for display only.¶
A.1. Issuance
The Principal gives the Agent a credential offer link in chat. The Agent submits it:¶
{
"request": "openid-credential-offer://?credential_offer_uri=
https%3A%2F%2Fissuer.example%2Foffers%2F9F4E"
}
¶
The Wallet trusts the Issuer, and the offer requires a transaction code, so the operation waits for the Principal:¶
{
"id": "op_7Hq2Lm",
"status": "pending",
"interaction": { "uri": "https://wallet.example/i/Tx41Ka" }
}
¶
The Principal enters the code on the Wallet's page. The Wallet redeems the pre-authorized code, then obtains, validates and keeps the credential:¶
{ "id": "op_7Hq2Lm", "status": "completed" }
¶
An issuance has no continuation; the Agent carries on with its task.¶
A.2. Presentation in a Browser
The Agent browses a ticket site, which shows a presentation link. The Agent submits it:¶
{
"request": "openid4vp://?client_id=x509_san_dns%3Atickets.example
&request_uri=https%3A%2F%2Ftickets.example%2Freq%2F4187"
}
¶
The Wallet authenticates the Verifier and needs the Principal's approval:¶
{
"id": "op_x2p9E4",
"status": "pending",
"interaction": {
"uri": "https://wallet.example/i/Qm7vT2",
"expires_at": "2026-10-16T10:25:00Z"
}
}
¶
The Agent relays the URI and keeps calling Get. The Principal approves, the Wallet sends the presentation, and the Verifier accepts it and returns a redirect URI:¶
{
"id": "op_x2p9E4",
"status": "completed",
"continuation": "https://tickets.example/cb
?response_code=091535f699ea575c7937fa5f0f454aee"
}
¶
The Agent opens the continuation in its browser session. The site redeems the response code for that session and continues the checkout.¶
If the Principal had declined and the Wallet had sent an error response, a redirect URI the Verifier returned would still reach the Agent:¶
{
"id": "op_x2p9E4",
"status": "failed",
"error": { "code": "denied" },
"continuation": "https://tickets.example/cb?error=access_denied"
}
¶
A.3. Presentation for an HTTP Resource
The Agent calls an API. The API answers with an HTTP challenge whose value carries an OpenID4VP request. The Agent submits the challenge value unchanged. If the Wallet recognizes the request it carries, it presents directly to the Verifier, and the operation completes with a continuation. The Agent retries the API call with the continuation, as the API specifies, and the API redeems it with the Verifier.¶
A.4. Presentation with a Delegated Credential
The Verifier asks for a claim only the Principal's own credential
holds, such as a date of birth. The Agent submits the request as in
the browser presentation example. The Agent's view does not change: an operation that
is pending with an interaction, then completed with a continuation.¶
Inside the Wallet, using delegated SD-JWT [I-D.gco-oauth-delegate-sd-jwt]:¶
-
The Wallet finds no credential of its own that satisfies the request.¶
-
Acting as a Verifier, it builds an OpenID4VP request to the Principal's own wallet. The request asks for the claims the original request needs and carries a delegation transaction. The delegate payload names the Wallet's key in
cnf, the original Verifier, and a short expiry.¶ -
The interaction URI shows that request as a QR code or a same-device link. The Principal opens it in their own wallet, which authenticates them and shows who is asking, for which claims, for which Verifier and until when.¶
-
The Principal's wallet presents a dSD-JWT to the Wallet: the Principal's credential, with a delegate payload signed by the Principal's key.¶
-
The Wallet verifies the chain, adds its own Key Binding JWT for the original Verifier's nonce, and sends the dSD-JWT+KB to the original Verifier. This is the commit point.¶
-
The Verifier returns a redirect URI, which becomes the continuation. The Wallet discards the delegation.¶
The original Verifier needs to accept dSD-JWT+KB presentations. The Principal's wallet needs to support delegation and to trust the Wallet as a Verifier.¶