Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wallet notifying the Issuer of (un)successful issuance of credential(s) #70

Merged
merged 61 commits into from
Dec 22, 2023
Merged
Changes from 35 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
2d05938
migrate PR608 from bitbucket
Sep 7, 2023
dd001bf
Apply suggestions from code review
Sakurann Sep 28, 2023
0f50200
modify issuer_state
Sep 29, 2023
f4159a5
Apply suggestions from Giuseppe's code review
Sakurann Sep 29, 2023
789280f
Apply suggestions from Giuseppe's code review
Sakurann Sep 29, 2023
ec74329
add callback_id
Sep 29, 2023
c412351
pull from remote
Sep 29, 2023
f8199af
align batch to credential endpoint
Sep 29, 2023
2e49036
Merge branch 'main' of https://github.com/openid/OpenID4VCI into wall…
Sep 29, 2023
a9b395a
Apply suggestions from code review
Sakurann Sep 29, 2023
28ef6d5
Revert "modify issuer_state"
Sep 29, 2023
43ab8c5
Merge branch 'wallet-callback' of https://github.com/openid/OpenID4VC…
Sep 29, 2023
832d02e
typo
Sakurann Sep 30, 2023
3072d9a
remove issuer_state
Sakurann Oct 2, 2023
33883e9
change status values to success, failure and rejected
Sakurann Oct 2, 2023
80e0925
callback endpoint is protected by the AT
Oct 4, 2023
2d3a8ba
Cla
Sakurann Oct 4, 2023
b9f78cc
add section on successful and error responses
Oct 4, 2023
0fe3bcd
resolve merge conflict
Oct 4, 2023
c8abe73
typos
Sakurann Oct 5, 2023
ae5cafe
capitalize Credential
Sakurann Oct 5, 2023
2acd3f0
removing media type requirements
Sakurann Oct 5, 2023
e817440
clarify three `status` values
Sakurann Oct 5, 2023
61a822a
change example to 204 No Content
Sakurann Oct 5, 2023
0c579cc
clean-up of the intro text
Sakurann Oct 5, 2023
f61190d
updating example to be access token authentication
Sakurann Oct 10, 2023
03590bd
Apply wording based on the suggestions from code review
Sakurann Oct 25, 2023
535af99
Merge branch 'main' of https://github.com/openid/OpenID4VCI into wall…
Oct 26, 2023
8d45c70
draft PR on how callback_session could work
Oct 26, 2023
7cdd683
Revert "draft PR on how callback_session could work"
Oct 26, 2023
d47ac70
resolve merge conflicts
Nov 16, 2023
baee859
replace callback with acknowledgement
Nov 16, 2023
ff44971
removes a surplus `
Sakurann Nov 22, 2023
1deaab6
clean up
Sakurann Nov 23, 2023
2ff050e
Apply suggestions from code review
Sakurann Nov 30, 2023
0dac2ce
Apply suggestions from code review
Sakurann Dec 11, 2023
a3cb647
resolve merge conflicts
Dec 12, 2023
90d2da7
fix error message
Dec 12, 2023
d51c053
change to delete signal and make this endpoint optional to the wallet
Sakurann Dec 13, 2023
7d56d73
Apply suggestions from Torsten's code review
Sakurann Dec 13, 2023
60fdf99
rename issuer metadata to ack_endpoint
Sakurann Dec 13, 2023
f28c7fc
clarify error behavior
Sakurann Dec 14, 2023
d6f83fe
fix merge conflicts
Dec 18, 2023
dfc43a8
fix references
Dec 18, 2023
2497a0b
change from acknowledgement to notification
Dec 18, 2023
6a28ceb
editorial
Dec 18, 2023
6dd2602
The Wallet MUST send one Notification Request per Credential issued
Dec 18, 2023
3151a41
update language
tplooker Dec 19, 2023
f40e6fe
Update openid-4-verifiable-credential-issuance-1_0.md
tplooker Dec 19, 2023
1032ceb
Update openid-4-verifiable-credential-issuance-1_0.md
tplooker Dec 19, 2023
50ec2b4
Apply suggestions from code review
Sakurann Dec 21, 2023
6943429
Merge branch 'main' into wallet-callback
Sakurann Dec 21, 2023
458ab77
add document history
Dec 21, 2023
43f9cfc
Merge branch 'wallet-callback' of https://github.com/openid/OpenID4VC…
Dec 21, 2023
4d95136
fix typo to make file compile
Dec 21, 2023
f3a0d7b
Apply suggestions from code review
Sakurann Dec 21, 2023
1ffd4d9
Apply suggestions from code review
Sakurann Dec 21, 2023
33a451c
networking error can cause request not received
Sakurann Dec 21, 2023
fe4892d
clarify this endpoint is optional for the wallet
Sakurann Dec 22, 2023
b9caf63
Merge branch 'main' into wallet-callback
Sakurann Dec 22, 2023
3085621
Merge branch 'main' into wallet-callback
Sakurann Dec 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 102 additions & 9 deletions openid-4-verifiable-credential-issuance-1_0.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ This specification defines an API for credential issuance provided by a Credenti
* An optional Batch Credential Endpoint from which multiple Credentials can be issued in one request (see (#batch-credential-endpoint)).
* An optional Deferred Credential Endpoint to allow for the deferred delivery of credentials (see (#deferred-credential-issuance)).
* An optional mechanism for the Credential Issuer to make a Credential Offer to the Wallet to encourage the Wallet to start the issuance flow (see (#credential_offer_endpoint)).
* An optional mechanism for the Credential Issuer to receive from the Wallet the status of the Credential that it issued.
Sakurann marked this conversation as resolved.
Show resolved Hide resolved
* A mechanism for the Credential Issuer to publish metadata about the Credentials it is capable of issuing (see (#credential-issuer-metadata)).

Both the Credential and the Batch Credential Endpoints have the (optional) ability to bind an issued Credential to certain cryptographic key material. Both requests therefore enable conveying proof of possession for the key material. Multiple key proof types are supported.
Expand Down Expand Up @@ -207,7 +208,7 @@ The diagram shows how a Wallet-initiated flow use case as described in (#use-cas
| | (5) Credential Request (access_token, proof(s)) |
| |--------------------------------------------------->|
| | Credential Response |
| | (credential(s) OR transaction_id) |
| | (credential(s) OR transaction_id) |
| |<---------------------------------------------------|
~~~
!---
Expand Down Expand Up @@ -686,7 +687,7 @@ This specification also uses the error codes `authorization_pending` and `slow_d

# Credential Endpoint {#credential-endpoint}

The Credential Endpoint issues a Credential as approved by the End-User upon presentation of a valid Access Token representing this approval.
The Credential Endpoint issues a Credential as approved by the End-User upon presentation of a valid Access Token representing this approval. Support for this endpoint is REQUIRED.

Communication with the Credential Endpoint MUST utilize TLS.

Expand Down Expand Up @@ -877,9 +878,10 @@ The following claims are used in the JSON-encoded Credential Response body:

* `format`: REQUIRED. String denoting the format of the issued Credential.
* `credential`: OPTIONAL. Contains issued Credential. MUST be present when `transaction_id` is not returned. MAY be a string or an object, depending on the Credential format. See (#format_profiles) for the Credential format specific encoding requirements.
* `transaction_id`: OPTIONAL. A string identifying a Deferred Issuance transaction. This claim is contained in the response if the Credential Issuer was unable to immediately issue the credential. The value is subsequently used to obtain the respective Credential with the Deferred Credential Endpoint (see (#deferred-credential-issuance)). It MUST be present when the `credential` parameter is not returned. It MUST be invalidated after the credential for which it was meant has been obtained by the Wallet.
* `transaction_id`: OPTIONAL. String identifying a Deferred Issuance transaction. This claim is contained in the response if the Credential Issuer was unable to immediately issue the credential. The value is subsequently used to obtain the respective Credential with the Deferred Credential Endpoint (see (#deferred-credential-issuance)). It MUST be present when the `credential` parameter is not returned. It MUST be invalidated after the credential for which it was meant has been obtained by the Wallet.
* `c_nonce`: OPTIONAL. String containing a nonce to be used to create a proof of possession of key material when requesting a Credential (see (#credential_request)). When received, the Wallet MUST use this nonce value for its subsequent credential requests until the Credential Issuer provides a fresh nonce.
* `c_nonce_expires_in`: OPTIONAL. Number denoting the lifetime in seconds of the `c_nonce`.
* `ack_id`: OPTIONAL. String identifying an issued Credential that the Wallet includes in the acknowledgement request as defined in (#acknowledgement).
Sakurann marked this conversation as resolved.
Show resolved Hide resolved

The `format` key determines the Credential format and encoding of the credential in the Credential Response. Details are defined in the Credential Format Profiles in (#format_profiles).

Expand Down Expand Up @@ -974,7 +976,7 @@ Cache-Control: no-store

# Batch Credential Endpoint {#batch-credential-endpoint}

The Batch Credential Endpoint issues multiple Credentials in one Batch Credential Response as approved by the End-User upon presentation of a valid Access Token representing this approval.
The Batch Credential Endpoint issues multiple Credentials in one Batch Credential Response as approved by the End-User upon presentation of a valid Access Token representing this approval. Support for this endpoint is OPTIONAL.

Communication with the Batch Credential Endpoint MUST utilize TLS.

Expand Down Expand Up @@ -1031,7 +1033,7 @@ The following claims are used in the Batch Credential Response:

* `credential_responses`: REQUIRED. Array that contains Credential Response objects as defined in (#credential_request) and/or Deferred Credential Response objects as defined in (#deferred-credential_request). Every entry of the array corresponds to the Credential Request object at the same array index in the `credential_requests` parameter of the Batch Credential Request.
* `c_nonce`: OPTIONAL. The `c_nonce` as defined in (#credential-response).
* `c_nonce_expires_in`: OPTIONAL. The `c_nonce_expires_in` as defined in (#credential-response).
* `c_nonce_expires_in`: OPTIONAL. The `c_nonce_expires_in` as defined in (#credential-response).

Below is a non-normative example of a Batch Credential Response in an immediate issuance flow:

Expand Down Expand Up @@ -1088,7 +1090,7 @@ When the Credential Issuer requires `proof` objects to be present in the Batch C

# Deferred Credential Endpoint {#deferred-credential-issuance}

This endpoint is used to issue a Credential previously requested at the Credential Endpoint or Batch Credential Endpoint in case the Credential Issuer was not able to immediately issue this Credential.
This endpoint is used to issue a Credential previously requested at the Credential Endpoint or Batch Credential Endpoint in case the Credential Issuer was not able to immediately issue this Credential. Support for this endpoint is OPTIONAL.
Sakurann marked this conversation as resolved.
Show resolved Hide resolved

The Wallet MUST present to the Deferred Endpoint an Access Token valid for the issuance of the Credential previously requested at the Credential Endpoint or the Batch Credential Endpoint.

Expand Down Expand Up @@ -1144,6 +1146,96 @@ Cache-Control: no-store
}
```

# Acknowledgement Endpoint {#acknowledgement_endpoint}

This endpoint is used by the Wallet to notify the Credential Issuer whether a Credential has been successfully received or not. It enables the Credential Issuer to take subsequent actions after issuance, depending on whether the Credential has been accepted and successfully stored by the Wallet, rejected by the Wallet, or errors and other unforeseen circumstances have occurred during the Wallet's processing. The Credential Issuer needs to return `ack_id` in the Credential Response or a Batch Credential Response for the Wallet to be able to use this Endpoint. Support for this endpoint by the Credential Issuer is OPTIONAL. The wallet MUST call this endpoint if the Credential Issuer supports it and provides a `ack_id`.
Sakurann marked this conversation as resolved.
Show resolved Hide resolved

The Wallet MUST present to the Acknowledgement Endpoint a valid Access Token issued at the Token Endpoint as defined in (#token_endpoint).

Note: A Credential Issuer that requires a request to the Acknowledgement Endpoint MUST ensure the Access Token issued by the Authorization Server is valid at the Acknowledgement Endpoint.

The acknowledgement from the Wallet is idempotent. The Credential Issuer MUST return success if it receives multiple identical calls from the Wallet for the same `ack_id`s.
Sakurann marked this conversation as resolved.
Show resolved Hide resolved

Sakurann marked this conversation as resolved.
Show resolved Hide resolved
The Wallet MAY retry if the call to this endpoint fails for a temporary reason. The Credential Issuer SHOULD pre-determine the amount of time within which it expects the acknowledgement. Therefore, even a well-formed acknowledgement from the Wallet could fail if received by the Credential Issuer after this time period. The Credential Issuer may not receive the acknowledgement, meaning it is unknown whether the Wallet successfully stored the credential or not - it is left to the Credential Issuer to decide how to proceed in this case.

Communication with the Acknowledgement Endpoint MUST utilize TLS.

## Acknowledgement Request {#acknowledgement}

The Wallet sends an HTTP POST request to the Acknowledgement Endpoint with the following parameters in the entity-body and using the `application/json` media type.

* `credentials`: Array of objects, where each object consists of the following parameters:
* `ack_id`: REQUIRED. String received in Credential Response or Batch Credential Response.
danielfett marked this conversation as resolved.
Show resolved Hide resolved
* `status`: REQUIRED. Status whether the credential issuance was successful or not. It MUST be a case sensitive string whose value is either `success`, `failure` or `rejected`. `rejected` is to be used when the unsuccessful credential issuance was caused by a user action. In all other unsuccessful cases, `failure` is to be used.
Sakurann marked this conversation as resolved.
Show resolved Hide resolved
* `error_description`: OPTIONAL. Human-readable ASCII [@!USASCII] text providing additional information, used to assist the Credential Issuer developer in understanding the error that occurred. Values for the `error_description` parameter MUST NOT include characters outside the set `%x20-21 / %x23-5B / %x5D-7E`.

Below is a non-normative example of an acknowledgement request when credential issuance was successful:

```
POST /acknowledgement HTTP/1.1
Host: server.example.com
Sakurann marked this conversation as resolved.
Show resolved Hide resolved
Content-Type: application/json
Sakurann marked this conversation as resolved.
Show resolved Hide resolved
Authorization: Bearer czZCaGRSa3F0MzpnWDFmQmF0M2JW

{
"credentials": [
{
"ack_id": "3fwe98js",
"status": "success"
}
]
}
```

Below is a non-normative example of an acknowledgement request when credential issuance was unsuccessful:

```
POST /acknowledgement HTTP/1.1
Host: server.example.com
Content-Type: application/json
Sakurann marked this conversation as resolved.
Show resolved Hide resolved
Authorization: Bearer czZCaGRSa3F0MzpnWDFmQmF0M2JW

{
"credentials": [
{
"ack_id": "3fwe98js",
"status": "failure",
"error_description": "..."
}
]
}
```

## Successful Acknowledgement Response

When the Credential Issuer has successfully received the acknowledgement request from the Wallet, it MUST respond with the HTTP status code 2xx. The usage of the HTTP status code 204 (No Content) is RECOMMENDED.

Below is a non-normative example of response to a successful acknowledgement request:

Sakurann marked this conversation as resolved.
Show resolved Hide resolved
```
HTTP/1.1 204 No Content
```

## Acknowledgement Error Response

If the acknowledgement request does not contain an Access Token or contains an invalid Access Token, the Acknowledgement Endpoint returns an authorization error response such as defined in section 3 of [@!RFC6750].

`invalid_request` parameter defined in section 3.1 of [@!RFC6750] SHOULD be used in most cases other than when `ack_id` value is invalid. In the latter case, the following error code SHOULD be used as the value of the `error` parameter:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RFC6750 defines use of the WWW-Authenticate response header field for the error param. Which isn't really the appropriate place for application layer errors like an invalid ack_id. And also isn't what's shown in the example Acknowledgement Error Response.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch - fixed to 400 application/json requirements

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still isn't quite right.


* `invalid_ack_id`: The `ack_id` in the acknowledgement request was invalid.

It is at the discretion of the Wallet whether to retry the request or not.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're now saying this in two different places (line 1206 as well). We should only say it in one place.

I do not think we should encourage or even allow the wallet to retry for a permanent failure, for example I don't think invalid_notification_id or invalid_notification_request should ever be retried.


Sakurann marked this conversation as resolved.
Show resolved Hide resolved
Sakurann marked this conversation as resolved.
Show resolved Hide resolved
Sakurann marked this conversation as resolved.
Show resolved Hide resolved
The following is a non-normative example of an Acknowledgement Error Response where an invalid `ack_id` value was used:

```
HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
{
"error": "invalid_ack_id"
}

# Metadata

## Client Metadata {#client-metadata}
Expand Down Expand Up @@ -1178,9 +1270,10 @@ This specification defines the following Credential Issuer Metadata:

* `credential_issuer`: REQUIRED. The Credential Issuer's identifier, as defined in (#credential-issuer-identifier).
* `authorization_servers`: OPTIONAL. An array of strings, where each string is an identifier of the OAuth 2.0 Authorization Server (as defined in [@!RFC8414]) the Credential Issuer relies on for authorization. If this parameter is omitted, the entity providing the Credential Issuer is also acting as the AS, i.e., the Credential Issuer's identifier is used as the OAuth 2.0 Issuer value to obtain the Authorization Server metadata as per [@!RFC8414]. When there are multiple entries in the array, the Wallet may be able to determine which AS to use by querying the metadata; for example, by examining the `grant_types_supported` values, the Wallet can filter the server to use based on the grant type it plans to use. When the Wallet is using `authorization_server` parameter in the Credential Offer as a hint to determine which AS to use out of multiple, the Wallet MUST NOT proceed with the flow if the `authorization_server` Credential Offer parameter value does not match any of the entries in the `authorization_servers` array.
* `credential_endpoint`: REQUIRED. URL of the Credential Issuer's Credential Endpoint. This URL MUST use the `https` scheme and MAY contain port, path, and query parameter components.
* `batch_credential_endpoint`: OPTIONAL. URL of the Credential Issuer's Batch Credential Endpoint. This URL MUST use the `https` scheme and MAY contain port, path, and query parameter components. If omitted, the Credential Issuer does not support the Batch Credential Endpoint.
* `deferred_credential_endpoint`: OPTIONAL. URL of the Credential Issuer's Deferred Credential Endpoint. This URL MUST use the `https` scheme and MAY contain port, path, and query parameter components. If omitted, the Credential Issuer does not support the Deferred Credential Endpoint.
* `credential_endpoint`: REQUIRED. URL of the Credential Issuer's Credential Endpoint as defined in (#credential_request). This URL MUST use the `https` scheme and MAY contain port, path, and query parameter components.
* `batch_credential_endpoint`: OPTIONAL. URL of the Credential Issuer's Batch Credential Endpoint as defined in (#batch-credential-endpoint). This URL MUST use the `https` scheme and MAY contain port, path, and query parameter components. If omitted, the Credential Issuer does not support the Batch Credential Endpoint.
* `deferred_credential_endpoint`: OPTIONAL. URL of the Credential Issuer's Deferred Credential Endpoint as defined in (#deferred-credential-issuance). This URL MUST use the `https` scheme and MAY contain port, path, and query parameter components. If omitted, the Credential Issuer does not support the Deferred Credential Endpoint.
* `credential_ack_endpoint`: OPTIONAL. URL of the Credential Issuer's Acknowledgement Endpoint as defined in (#acknowledgement_endpoint). This URL MUST use the `https` scheme and MAY contain port, path, and query parameter components. If omitted, the Credential Issuer does not support the Acknowledgement Endpoint.
Sakurann marked this conversation as resolved.
Show resolved Hide resolved
* `credential_response_encryption_alg_values_supported`: OPTIONAL. Array containing a list of the JWE [@!RFC7516] encryption algorithms (`alg` values) [@!RFC7518] supported by the Credential and/or Batch Credential Endpoint to encode the Credential or Batch Credential Response in a JWT [@!RFC7519].
* `credential_response_encryption_enc_values_supported`: OPTIONAL. Array containing a list of the JWE [@!RFC7516] encryption algorithms (`enc` values) [@!RFC7518] supported by the Credential and/or Batch Credential Endpoint to encode the Credential or Batch Credential Response in a JWT [@!RFC7519].
* `require_credential_response_encryption`: OPTIONAL. Boolean value specifying whether the Credential Issuer requires additional encryption on top of TLS for the Credential Response and expects encryption parameters to be present in the Credential Request and/or Batch Credential Request, with `true` indicating support. When the value is `true`, `credential_response_encryption_alg_values_supported` parameter MUST also be provided. If omitted, the default value is `false`.
Expand Down