-
Notifications
You must be signed in to change notification settings - Fork 47
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
Refactor presentation endpoints into exchange endpoints #258
Changes from 4 commits
1680068
86fcb9e
fdf675e
748d5be
83e0bf2
a172d81
fc195cd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
openapi: 3.0.0 | ||
info: | ||
version: "0.0.3-unstable" | ||
title: VC HTTP API | ||
description: This is an Experimental Open API Specification for the [VC Data Model](https://www.w3.org/TR/vc-data-model/). | ||
license: | ||
name: W3C Software and Document License | ||
url: http://www.w3.org/Consortium/Legal/copyright-software. | ||
contact: | ||
name: GitHub Source Code | ||
url: https://github.com/w3c-ccg/vc-api | ||
paths: | ||
components: | ||
schemas: | ||
ErrorResponse: | ||
type: object | ||
description: A response that denotes that an error has occurred. | ||
properties: | ||
id: | ||
type: "string" | ||
pattern: "[a-z0-9\\-]{8,}" | ||
message: | ||
type: "string" | ||
minLength: 10 | ||
maxLength: 100 | ||
details: | ||
type: "object" | ||
required: ["id", "message"] | ||
example: | ||
{ | ||
"id": "invalid-json", | ||
"message": "The provided JSON data was malformed." | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
name: exchange-id | ||
description: A potentially human-readable identifier for an exchange. | ||
in: path | ||
required: true | ||
schema: | ||
type: string | ||
minimum: 3 | ||
pattern: "[a-z0-9][a-z0-9\\-]{2,}" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
in: path | ||
name: transaction-uuid | ||
required: true | ||
schema: | ||
type: string | ||
pattern: "([0-9a-f]{8}\b-[0-9a-f]{4}\b-[0-9a-f]{4}\b-[0-9a-f]{4}\b-[0-9a-f]{12}){0,1}" |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,60 +56,90 @@ paths: | |
description: invalid input! | ||
"500": | ||
description: error! | ||
/presentations/available: | ||
/exchanges/{exchange-id}: | ||
post: | ||
summary: Notifies a holder of an available presentation. | ||
operationId: notifyPresentationAvailable | ||
summary: Initiates an exchange of information. | ||
operationId: initiateExchange | ||
description: | ||
This API is the first part of a holder to holder credential exchange over http. | ||
Notifies this server-holder that the client-holder (caller) is prepared to deliver a presentation compliant with the provided Verifiable Presentation Request query. This is the first part of a presentation exchange over this HTTP API. This server-holder MUST return the required 'domain' and 'challenge' parameters for the Presentation. This server-holder MAY reply with an alternate Verifiable Presentation Request query if it requires something different than the one proposed by the client-holder. The client-holder MUST return a Presentation in accordance with the response parameters. | ||
A client can use this endpoint to initiate an exchange of a particular | ||
type. The client can include HTTP POST information related to the | ||
details of exchange it would like to initiate. If the server understands | ||
the request, it returns a Verifiable Presentation Request. A request | ||
that the server cannot understand results in an error. | ||
parameters: | ||
- $ref: "./components/parameters/path/ExchangeId.yml" | ||
requestBody: | ||
description: Details the client provides to the server to help it decide if the presentation should be made. | ||
description: | ||
Information related to the type of exchange the client would like | ||
to start. | ||
content: | ||
application/json: | ||
schema: | ||
$ref: "#/components/schemas/NotifyPresentationAvailableRequest" | ||
anyOf: | ||
- | ||
{ | ||
"type": "object", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's not add this... since you just destroyed the ability to know the shape of the data... of course if you have a new shape you want to define I would be happy to see it defined and added but this harmful for interop as is. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If the server doesn't understand the POST data, they return a 400 error code (as described in the PR). Accepting an arbitrary object with arbitrary fields is exactly what DB needs here (we have customers that require exchange types to be set up, where they take arbitrary JSON input for a defined exchange type, and then use that to drive VPR logic). We discussed this on the last VC API call and there wasn't push back on it. You need to show up on the next VC API call and make your point (or clearly articulate it here). Please refer to the (very long and fruitful) discussion that you missed here: https://w3c-ccg.github.io/meetings/2022-02-01-vcapi/#topic-2 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I doubt very much that your customers like reading API docs that say "just give us any JSON you can imagine"... However, I would bet they would be happy to see a schema defined that accepted some additional properties. You can set There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Clearly, that is not the case. The case is this: The customers are the ones that define what is valid to send to a particular exchange endpoint... the /customer/ supplies the JSON Schema and then what to do with the input JSON. So, to clarify for the endpoint: Do you understand the use case? We can't limit the JSON Schema for our use case because the input set is unbounded for our servers (but the Traceability folks are free to limit the input set to what makes sense to them).
No, they really don't want us to define any JSON Schema. They want to do it.
Not really, see above. |
||
"description": "Data necessary to initiate the exchange." | ||
} | ||
- | ||
$ref: "#/components/schemas/NotifyPresentationAvailableRequest" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I kept this here for the time being, we could probably keep it here -- but I do want to have a chat w/ the Traceability folks to understand why they're approaching the problem in this way. There might be a simpler way. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there is always a simpler way, but it must be defined in a schema to be accepted :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's discuss on next VC API call -- it's not clear to me why the Traceability folks chose to use a VPR here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We chose to support VPR in the hopes that eventually browser and HTTP APIs would support the same request / respond query data model. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. VPR is supported in the response format for this call (so there would be no drop in support for VPR). What I'm wondering is why /POST/ a VPR. What you get in return is a VPR. So, with the traceability stuff (IIUC) you POST a VPR and then get a VPR in response. |
||
responses: | ||
"200": | ||
description: Proceed with presentation | ||
description: Proceed with exchange. | ||
content: | ||
application/json: | ||
schema: | ||
$ref: "#/components/schemas/NotifyPresentationAvailableResponse" | ||
$ref: "#/components/schemas/VerifiablePresentationRequest" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice! |
||
"400": | ||
description: Request for presentation is malformed | ||
description: Request is malformed. | ||
content: | ||
application/json: | ||
schema: | ||
$ref: "#/components/schemas/ErrorResponse" | ||
"501": | ||
description: Not implemented | ||
description: Service not implemented. | ||
"500": | ||
description: internal error | ||
/presentations/submissions: | ||
description: Internal server error. | ||
/exchanges/{exchange-id}/{transaction-uuid}: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @msporny @mkhraisha -- I'm not sure if this is what you guys were talking about wrt. two IDs to track a particular exchange or not? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not a fan of this ... I am pretty sure these are values that are inside VPs or VCs for the purposes of relating them (intentional correlation fields). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This is not what I heard @mkhraisha and @mprorock request on the call. It was not entirely clear to me, but these were the ACTIONS that were taken on the last VC API call and what I implemented. This was the "We need to follow REST principles" argument that @mprorock was making throughout the call, which I agree with, so we really need to sort this out as it was this approach that enabled us to merge the presentation/workflow endpoints in the first place. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current endpoints support It's not clear to me that adding another URL parameter does anything helpful wrt presentation exchange, given we don't need it currently. Controller style endpoints are defined in the style guide we agreed to use. https://restfulapi.net/resource-naming/ for example:
Since this PR is attempting to merge the existing endpoints with a new proposed one, I suggest only adding 1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
See this comment for detail: https://github.com/w3c-ccg/vc-api/pull/258/files#r801205266 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So some clarification: In the case of REST we SHOULD have the IDs for objects in both URI and in @msporny does that make sense There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This article on the topic may help clarify what I mean https://restfulapi.net/rest-put-vs-post/ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. following normal collection style naming convention, I would assume:
I don't know what There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mprorock wrote:
Yes, I think what you want is for However, it seems like @mprorock and @OR13 disagree? Still hard for me to tell. To be clear, Digital Bazaar would like to be able to identify different types of exchanges at different endpoints (load balancing via URL instead of having to look into each message -- useful at scale). We would also like to be able to refer to individual instances of each exchange (again, load balancing via URL instead of having to look into each message -- also useful at scale). Remember that the age verification system does >40 million individual interactions per day, and the number of HTTP calls are multiples of that... so, not having to look into the payload body is of significant importance at scale. Moving these things into the payload body doesn't allow us to use some of the faster load balancing frameworks out there that only have to look at the first few lines of the HTTP Headers instead of having to consume the entire message. |
||
post: | ||
msporny marked this conversation as resolved.
Show resolved
Hide resolved
|
||
summary: Provide a presentation for a holder to store. | ||
operationId: storePresentation | ||
description: "Delivery endpoint for a client-holder to provide a presentation in compliance with the Verifiable Presentation Request provided in the Notification call. This server-holder MUST match the 'domain' and 'challenge' to a 'domain' and 'challenge' previously sent in a Notification Response, and not already received. The server-holder MUST verify the Presentation. The server MUST store the Presentation if verification passes." | ||
summary: Receives information related to an existing exchange. | ||
operationId: receiveExchangeData | ||
description: | ||
A client can use this endpoint to continue the exchange of information | ||
associated with an initiated exchange. A Verifiable Presentation is | ||
sent to this endpoint. If the server has received all of the information | ||
it needs, a 200 OK is returned with either an empty response or a | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. a bit of a nit, but your description is redundant to the description for the supported statuses. You can keep the description focused on defining the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @OR13 wrote:
Does this work for you? https://github.com/w3c-ccg/vc-api/pull/258/files#r801206879 |
||
Verifiable Presentation containing requested credentials by the client. | ||
If the server requires more information, it returns a Verifiable | ||
Presentation Request. A request that the server cannot understand | ||
results in an error. | ||
msporny marked this conversation as resolved.
Show resolved
Hide resolved
|
||
parameters: | ||
- $ref: "./components/parameters/path/ExchangeId.yml" | ||
- $ref: "./components/parameters/path/TransactionUuid.yml" | ||
requestBody: | ||
description: Details the client provides to the server to help it decide if the presentation should be made. | ||
description: | ||
A Verifiable Presentation. | ||
content: | ||
application/json: | ||
schema: | ||
$ref: "#/components/schemas/StorePresentationRequest" | ||
$ref: "#/components/schemas/VerifiablePresentation" | ||
responses: | ||
"202": | ||
description: Presentation accepted | ||
"200": | ||
description: Received data was accepted. | ||
content: | ||
application/json: | ||
schema: | ||
$ref: "#/components/schemas/VerifiablePresentationRequest" | ||
"400": | ||
description: Presentation is malformed | ||
"401": | ||
description: Presentation did not contain a proof | ||
"402": | ||
description: Payment required | ||
"403": | ||
description: Presentation verification failed | ||
"425": | ||
description: Server is unwilling to risk processing a request that might be replayed | ||
"501": | ||
description: Not implemented | ||
description: Received data is malformed. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see how this could ever be the case given https://github.com/w3c-ccg/vc-api/pull/258/files#r799493530 Implementers should be throwing 400 as soon as they have validated the request data according to a schema, per OWASP best practices... https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @OR13 wrote:
Please see this for a more detailed explanation with a use case: https://github.com/w3c-ccg/vc-api/pull/258/files#r801201273 |
||
content: | ||
application/json: | ||
schema: | ||
$ref: "#/components/schemas/ErrorResponse" | ||
"500": | ||
description: internal error | ||
description: Internal server error. | ||
"501": | ||
description: Service not implemented. | ||
components: | ||
schemas: | ||
DeriveCredentialRequest: | ||
|
@@ -213,5 +243,11 @@ components: | |
"domain": "jobs.example.com", | ||
"challenge": "3182bdea-63d9-11ea-b6de-3b7c1404d57f", | ||
} | ||
ErrorResponse: | ||
$ref: "./components/ErrorResponse.yml#/components/schemas/ErrorResponse" | ||
StorePresentationRequest: | ||
$ref: "./components/VerifiablePresentation.yml#/components/schemas/VerifiablePresentation" | ||
VerifiablePresentation: | ||
$ref: "./components/VerifiablePresentation.yml#/components/schemas/VerifiablePresentation" | ||
VerifiablePresentationRequest: | ||
$ref: "./components/VerifiablePresentationRequest.yml#/components/schemas/VerifiablePresentationRequest" |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -555,21 +555,21 @@ <h4>Prove Presentation</h4> | |
</section> | ||
|
||
<section> | ||
<h4>Presentation Availability</h4> | ||
<h4>Initiate Exchange</h4> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jandrieu I waffled back and forth on "Initiate Presentation Exchange" and what I ended up using above. Any ideas? Is this what you were going for? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Initiate exchange sounds pretty good to me |
||
<p> | ||
</p> | ||
|
||
<div class="api-detail" | ||
data-api-endpoint="post /presentations/available"></div> | ||
data-api-endpoint="post /exchanges/{exchange-id}"></div> | ||
</section> | ||
|
||
<section> | ||
<h4>Submit Presentation</h4> | ||
<h4>Continue Exchange</h4> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jandrieu same here -- "continue exchange" seems strange... maybe? I don't know. Any suggestions? |
||
<p> | ||
</p> | ||
|
||
<div class="api-detail" | ||
data-api-endpoint="post /presentations/submissions"></div> | ||
data-api-endpoint="post /exchanges/{exchange-id}/{transaction-uuid}"></div> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe this needs to be updated to the put route There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in a172d81. |
||
</section> | ||
|
||
</section> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
finally! real and potentially useful errors! <3
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If people like this, I'll apply it to all 4xx error codes. This standard object also enables us to define standard error code responses more specifically in the spec.