From bd4de07f0554697d1bf058ef6e79c407a10e003a Mon Sep 17 00:00:00 2001 From: Rein Krul Date: Sun, 5 Nov 2023 14:08:54 +0100 Subject: [PATCH 1/7] UseCase: OpenAPI spec for list maintainer and client --- docs/_static/usecase/v1.yaml | 157 +++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 docs/_static/usecase/v1.yaml diff --git a/docs/_static/usecase/v1.yaml b/docs/_static/usecase/v1.yaml new file mode 100644 index 0000000000..9754a81166 --- /dev/null +++ b/docs/_static/usecase/v1.yaml @@ -0,0 +1,157 @@ +openapi: "3.0.0" +info: + title: Nuts Use Case List Service API spec + description: API specification for use case list services available within nuts node + version: 1.0.0 + license: + name: GPLv3 +servers: + - url: http://localhost:1323 +paths: + /usecase/{listName}: + parameters: + - name: listName + in: path + required: true + schema: + type: string + get: + summary: Retrieves a use case list + description: | + An API provided by the use case maintainer to retrieve a use case list, starting at the given lamport timestamp. + The client should provide the timestamp it was returned in the last response. + If no timestamp is given or it is 0, it will return the full list. + + error returns: + * 400 - incorrect input + operationId: getList + tags: + - usecase + parameters: + - name: timestamp + in: query + schema: + type: integer + minimum: 0 + responses: + "200": + description: Requested list is returned, alongside the timestamp which should be provided at the next query. + content: + application/json: + schema: + type: object + required: + - timestamp + - entries + properties: + timestamp: + type: integer + minimum: 0 + entries: + type: array + items: + $ref: "#/components/schemas/VerifiablePresentation" + default: + $ref: "../common/error_response.yaml" + post: + summary: Adds a presentation to the list + description: | + An API provided by the use case maintainer that adds a presentation to the list. + The presentation must be signed by subject of the credentials it contains. + + error returns: + * 400 - incorrect input; e.g. unsupported presentation or credential type, invalid signature, unresolvable credential subject, etc. + operationId: addPresentation + tags: + - usecase + requestBody: + description: The presentation to add to the list + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/VerifiablePresentation" + responses: + "201": + description: Presentation was added to the list + "400": + $ref: "../common/error_response.yaml" + default: + $ref: "../common/error_response.yaml" + /usecase/{listName}/search: + parameters: + - name: listName + in: path + required: true + schema: + type: string + # Way to specify dynamic query parameters + # See https://stackoverflow.com/questions/49582559/how-to-document-dynamic-query-parameter-names-in-openapi-swagger + - in: query + name: query + schema: + type: object + additionalProperties: + type: string + style: form + explode: true + get: + summary: Searches a for presentations on the usecase list. + description: | + An API of the use case client that searches a for presentations on the usecase list, + whose credentials match the given query parameter. + The query parameters are interpreted as JSON path expressions, evaluated on the verifiable credentials. + The following features and limitations apply: + - only simple child-selectors are supported (so no arrays selectors, script expressions etc). + - only JSON string values can be matched, no numbers, booleans, etc. + - wildcard (*) are supported at the start and end of the value + - a single wildcard (*) means: match any (non-nil) value + - matching is case-insensitive + - expressions must not include the '$.' prefix, which is added by the API. + - all expressions must match a single credential, for the credential to be included in the result. + - if there are multiple credentials in the presentation, the presentation is included in the result if any of the credentials match. + + Valid examples: + * `credentialSubject.givenName=John` + * `credentialSubject.organization.city=Arnhem` + * `credentialSubject.organization.name=Hospital*` + * `credentialSubject.organization.name=*clinic` + * `issuer=did:web:example.com` + + Search results are + operationId: searchList + tags: + - usecase + responses: + "200": + description: Search results are returned, if any. + content: + application/json: + schema: + type: array + items: + type: object + required: + - id + - credential + properties: + id: + type: string + description: The ID of the Verifiable Presentation. + credential: + type: object + description: The Verifiable Credential that matched the query. + default: + $ref: "../common/error_response.yaml" +components: + schemas: + VerifiablePresentation: + $ref: "../common/ssi_types.yaml#/components/schemas/VerifiablePresentation" + securitySchemes: + jwtBearerAuth: + type: http + scheme: bearer + +security: + - { } + - jwtBearerAuth: [ ] From 06d2ac146a25fd15b17e0787b4ae0f811febd6fe Mon Sep 17 00:00:00 2001 From: Rein Krul Date: Sun, 5 Nov 2023 14:10:59 +0100 Subject: [PATCH 2/7] tombstone set --- docs/_static/usecase/v1.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/_static/usecase/v1.yaml b/docs/_static/usecase/v1.yaml index 9754a81166..4e26e58647 100644 --- a/docs/_static/usecase/v1.yaml +++ b/docs/_static/usecase/v1.yaml @@ -43,6 +43,7 @@ paths: required: - timestamp - entries + - tombstones properties: timestamp: type: integer @@ -51,6 +52,14 @@ paths: type: array items: $ref: "#/components/schemas/VerifiablePresentation" + tombstones: + description: | + List of timestamps of entries that were removed from the list. + The client should remove these entries from its local copy of the list. + type: array + items: + type: integer + description: Timestamp of the entry that was removed from the list. default: $ref: "../common/error_response.yaml" post: From 6099981440d32e99063665bcb212975f75a7e88f Mon Sep 17 00:00:00 2001 From: Rein Krul Date: Mon, 6 Nov 2023 09:36:29 +0100 Subject: [PATCH 3/7] tombstones presentation IDs --- docs/_static/usecase/v1.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/_static/usecase/v1.yaml b/docs/_static/usecase/v1.yaml index 4e26e58647..d77b2abd3c 100644 --- a/docs/_static/usecase/v1.yaml +++ b/docs/_static/usecase/v1.yaml @@ -54,12 +54,12 @@ paths: $ref: "#/components/schemas/VerifiablePresentation" tombstones: description: | - List of timestamps of entries that were removed from the list. + List of presentation IDs that were removed from the list. The client should remove these entries from its local copy of the list. type: array items: - type: integer - description: Timestamp of the entry that was removed from the list. + type: string + description: ID of the presentation that was removed from the list. default: $ref: "../common/error_response.yaml" post: From 7357bf8616f86391ee1bcaf03a69d8cf3a9ee7e4 Mon Sep 17 00:00:00 2001 From: Rein Krul Date: Mon, 6 Nov 2023 09:37:16 +0100 Subject: [PATCH 4/7] list style --- docs/_static/usecase/v1.yaml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/_static/usecase/v1.yaml b/docs/_static/usecase/v1.yaml index d77b2abd3c..721f329eab 100644 --- a/docs/_static/usecase/v1.yaml +++ b/docs/_static/usecase/v1.yaml @@ -121,13 +121,11 @@ paths: - if there are multiple credentials in the presentation, the presentation is included in the result if any of the credentials match. Valid examples: - * `credentialSubject.givenName=John` - * `credentialSubject.organization.city=Arnhem` - * `credentialSubject.organization.name=Hospital*` - * `credentialSubject.organization.name=*clinic` - * `issuer=did:web:example.com` - - Search results are + - `credentialSubject.givenName=John` + - `credentialSubject.organization.city=Arnhem` + - `credentialSubject.organization.name=Hospital*` + - `credentialSubject.organization.name=*clinic` + - `issuer=did:web:example.com` operationId: searchList tags: - usecase From 0a4640062ff9d427177fecfa08ecc5d373fecac4 Mon Sep 17 00:00:00 2001 From: Rein Krul Date: Mon, 6 Nov 2023 09:45:50 +0100 Subject: [PATCH 5/7] delete operation --- docs/_static/usecase/v1.yaml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/docs/_static/usecase/v1.yaml b/docs/_static/usecase/v1.yaml index 721f329eab..36c9de7d2b 100644 --- a/docs/_static/usecase/v1.yaml +++ b/docs/_static/usecase/v1.yaml @@ -87,6 +87,32 @@ paths: $ref: "../common/error_response.yaml" default: $ref: "../common/error_response.yaml" + delete: + summary: Delete a credential subject from list. + description: | + An API provided by the use case maintainer that removes all presentations of a specific credential subject from the list. + The presentation must be signed by credential subject which' presentations should be removed. + The presentation should not contain any credentials but if there are, they are ignored. + + error returns: + * 400 - incorrect input; e.g. unsupported presentation, invalid signature, etc. + operationId: removePresentations + tags: + - usecase + requestBody: + description: Presentation identifying the credential subject to remove from the list. + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/VerifiablePresentation" + responses: + "201": + description: Presentation was added to the list + "400": + $ref: "../common/error_response.yaml" + default: + $ref: "../common/error_response.yaml" /usecase/{listName}/search: parameters: - name: listName From d8a1239449b15b925facbfdb909c8dd832fbb399 Mon Sep 17 00:00:00 2001 From: Rein Krul Date: Tue, 5 Dec 2023 06:59:47 +0100 Subject: [PATCH 6/7] feedback --- docs/_static/{usecase => discovery}/v1.yaml | 87 ++++++--------------- 1 file changed, 25 insertions(+), 62 deletions(-) rename docs/_static/{usecase => discovery}/v1.yaml (61%) diff --git a/docs/_static/usecase/v1.yaml b/docs/_static/discovery/v1.yaml similarity index 61% rename from docs/_static/usecase/v1.yaml rename to docs/_static/discovery/v1.yaml index 36c9de7d2b..1514c7b4f7 100644 --- a/docs/_static/usecase/v1.yaml +++ b/docs/_static/discovery/v1.yaml @@ -1,41 +1,40 @@ openapi: "3.0.0" info: - title: Nuts Use Case List Service API spec - description: API specification for use case list services available within nuts node + title: Nuts Discovery Service API spec + description: API specification for discovery services available within Nuts node version: 1.0.0 license: name: GPLv3 servers: - url: http://localhost:1323 paths: - /usecase/{listName}: + /discovery/{serviceID}: parameters: - - name: listName + - name: serviceID in: path required: true schema: type: string get: - summary: Retrieves a use case list + summary: Retrieves the presentations of a discovery service. description: | - An API provided by the use case maintainer to retrieve a use case list, starting at the given lamport timestamp. + An API provided by the discovery server to retrieve the presentations of a discovery service, starting at the given timestamp. The client should provide the timestamp it was returned in the last response. - If no timestamp is given or it is 0, it will return the full list. + If no timestamp is given, it will return all presentations. error returns: - * 400 - incorrect input - operationId: getList + * 404 - unknown service ID + operationId: getPresentations tags: - - usecase + - discovery parameters: - name: timestamp in: query schema: - type: integer - minimum: 0 + type: string responses: "200": - description: Requested list is returned, alongside the timestamp which should be provided at the next query. + description: Presentations are returned, alongside the timestamp which should be provided at the next query. content: application/json: schema: @@ -43,64 +42,28 @@ paths: required: - timestamp - entries - - tombstones properties: timestamp: - type: integer - minimum: 0 + type: string entries: type: array items: $ref: "#/components/schemas/VerifiablePresentation" - tombstones: - description: | - List of presentation IDs that were removed from the list. - The client should remove these entries from its local copy of the list. - type: array - items: - type: string - description: ID of the presentation that was removed from the list. default: $ref: "../common/error_response.yaml" post: - summary: Adds a presentation to the list + summary: Register a presentation on the discovery service. description: | - An API provided by the use case maintainer that adds a presentation to the list. + An API provided by the use case maintainer that adds a presentation to the service. The presentation must be signed by subject of the credentials it contains. error returns: * 400 - incorrect input; e.g. unsupported presentation or credential type, invalid signature, unresolvable credential subject, etc. - operationId: addPresentation - tags: - - usecase - requestBody: - description: The presentation to add to the list - required: true - content: - application/json: - schema: - $ref: "#/components/schemas/VerifiablePresentation" - responses: - "201": - description: Presentation was added to the list - "400": - $ref: "../common/error_response.yaml" - default: - $ref: "../common/error_response.yaml" - delete: - summary: Delete a credential subject from list. - description: | - An API provided by the use case maintainer that removes all presentations of a specific credential subject from the list. - The presentation must be signed by credential subject which' presentations should be removed. - The presentation should not contain any credentials but if there are, they are ignored. - - error returns: - * 400 - incorrect input; e.g. unsupported presentation, invalid signature, etc. - operationId: removePresentations + operationId: registerPresentation tags: - - usecase + - discovery requestBody: - description: Presentation identifying the credential subject to remove from the list. + description: The presentation to register to the discovery service. required: true content: application/json: @@ -108,14 +71,14 @@ paths: $ref: "#/components/schemas/VerifiablePresentation" responses: "201": - description: Presentation was added to the list + description: Presentation was registered on the discovery service. "400": $ref: "../common/error_response.yaml" default: $ref: "../common/error_response.yaml" - /usecase/{listName}/search: + /discovery/{serviceID}/search: parameters: - - name: listName + - name: serviceID in: path required: true schema: @@ -131,9 +94,9 @@ paths: style: form explode: true get: - summary: Searches a for presentations on the usecase list. + summary: Searches for presentations registered on the discovery service. description: | - An API of the use case client that searches a for presentations on the usecase list, + An API of the discovery client that searches for presentations on the discovery service, whose credentials match the given query parameter. The query parameters are interpreted as JSON path expressions, evaluated on the verifiable credentials. The following features and limitations apply: @@ -152,9 +115,9 @@ paths: - `credentialSubject.organization.name=Hospital*` - `credentialSubject.organization.name=*clinic` - `issuer=did:web:example.com` - operationId: searchList + operationId: searchPresentations tags: - - usecase + - discovery responses: "200": description: Search results are returned, if any. From a4a007ead269f5151b2a3ed9c93a2dd70eb62510 Mon Sep 17 00:00:00 2001 From: Rein Krul Date: Tue, 5 Dec 2023 11:16:07 +0100 Subject: [PATCH 7/7] feedback --- docs/_static/discovery/v1.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/_static/discovery/v1.yaml b/docs/_static/discovery/v1.yaml index 1514c7b4f7..a79302af01 100644 --- a/docs/_static/discovery/v1.yaml +++ b/docs/_static/discovery/v1.yaml @@ -54,9 +54,14 @@ paths: post: summary: Register a presentation on the discovery service. description: | - An API provided by the use case maintainer that adds a presentation to the service. + An API provided by the discovery server that adds a presentation to the service. The presentation must be signed by subject of the credentials it contains. + To delete a presentation, the client should send an empty presentation that: + * has a JWT claim 'retracted_jti' indicating the ID of the previous presentation of the same subject + * has no credentials in it + * has the type 'RetractedVerifiablePresentation' + error returns: * 400 - incorrect input; e.g. unsupported presentation or credential type, invalid signature, unresolvable credential subject, etc. operationId: registerPresentation