From 135b1d669b32b42f883c2794a89a946e3ad5436d Mon Sep 17 00:00:00 2001 From: Gabe <7622243+decentralgabe@users.noreply.github.com> Date: Mon, 20 Nov 2023 22:24:21 +0100 Subject: [PATCH] update api, add openapi doc (#53) --- spec/api.yaml | 247 ++++++++++++++++++++++++++++++++++++++++++++++++++ spec/spec.md | 116 ++++++++++++++++-------- 2 files changed, 326 insertions(+), 37 deletions(-) create mode 100644 spec/api.yaml diff --git a/spec/api.yaml b/spec/api.yaml new file mode 100644 index 00000000..327054a1 --- /dev/null +++ b/spec/api.yaml @@ -0,0 +1,247 @@ +openapi: 3.0.1 +info: + title: DID DHT Gateway API + description: "The [DID DHT API](https://did-dht.com)" + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + version: Working Draft +paths: + /{id}: + get: + tags: + - Pkarr Relay + summary: Get Pkarr records from the DHT + description: Get a Pkarr record set from the DHT + parameters: + - name: id + in: path + description: ID to get + required: true + schema: + type: string + responses: + "200": + description: "64 bytes sig, 8 bytes u64 big-endian seq, 0-1000 bytes of v." + content: + application/octet-stream: + schema: + type: array + items: + type: integer + "400": + description: Bad request + content: + application/json: + schema: + type: string + "404": + description: Not found + content: + application/json: + schema: + type: string + "500": + description: Internal server error + content: + application/json: + schema: + type: string + put: + tags: + - Pkarr Relay + summary: Put a Pkarr record set into the DHT + description: Put a Pkarr record set into the DHT + parameters: + - name: id + in: path + description: ID to put + required: true + schema: + type: string + requestBody: + description: "64 bytes sig, 8 bytes u64 big-endian seq, 0-1000 bytes of v." + content: + application/octet-stream: + schema: + type: array + items: + type: integer + required: true + responses: + "200": + description: OK + "400": + description: Bad request + content: + application/json: + schema: + type: string + "500": + description: Internal server error + content: + application/json: + schema: + type: string + /did: + put: + tags: + - DID + summary: Register or Update a DID + description: Register or Updte a DID in the DHT + requestBody: + description: A deconstructed Pkarr request object + content: + application/json: + schema: + type: object + properties: + did: + type: string + description: The DID to register or update. + sig: + type: string + descrption: A base64URL-encoded signature of the BEP44 payload. + seq: + type: integer + description: A sequence number for the request, recommended to be a unix timestamp in seconds. + v: + type: string + descrption: A base64URL-encoded bencoded DNS packet containing the DID Document. + retention_proof: + type: string + description: A retention proof calculated according to the spec-defined retention proof algorithm. + required: [did, sig, seq, v] + responses: + "202": + description: Accepted. The server has accepted the request as valid and will publish it to the + content: + application/json: + schema: + type: string + "400": + description: Invalid request body. + content: + application/json: + schema: + type: string + "401": + description: Invalid signature. + content: + application/json: + schema: + type: string + "409": + description: DID already exists with a higher sequence number. May still be accepted if the Gateway supports historical resolution. + content: + application/json: + schema: + type: string + /did/{id}: + get: + tags: + - DID + summary: Resolve a DID + description: Resolve a DID from the DHT first, with a fallback to local storage. + parameters: + - name: id + in: path + description: DID to resolve. + required: true + schema: + type: string + format: did:dht:* + - name: seq + in: query + description: Sequence number of the DID to resolve. + required: false + schema: + type: integer + responses: + "200": + description: The resolved DID Document. + content: + application/json: + schema: + type: object + "404": + description: DID could not be resolved. + content: + application/json: + schema: + type: string + /did/types: + get: + tags: + - DID + summary: Retrieve a list of supported types for indexing. + description: Retrieve a list of supported indexing types, according to the spec-defined type list. + responses: + "200": + description: A list of types support, alongisde their human-readable description. + content: + application/json: + schema: + type: array + items: + type: object + properties: + type: + type: integer + description: + type: string + required: [type, description] + "404": + description: Type indexing not supported by this gateway. + content: + application/json: + schema: + type: string + /did/types/{id}: + get: + tags: + - DID + summary: Retrieve a list of DIDs indexed under a given type. + description: Retrieve a list of DIDs indexed under a given type, according to the spec-defined type index. + parameters: + - name: id + in: path + description: Type to query. + required: true + schema: + type: integer + responses: + "200": + description: A list of DIDs indexed under the given type. + content: + application/json: + schema: + type: array + items: + type: string + format: did:dht:* + /difficulty: + get: + tags: + - DID + summary: Get information about the current difficulty. + description: Get information needed to calculate a retention proof for DID PUT operations. + responses: + "200": + description: The current hash and difficulty to calculate a retention proof against. + content: + application/json: + schema: + type: object + properties: + hash: + type: string + difficulty: + type: integer + required: [hash, difficulty] + "404": + description: Retention proofs not supported by this gateway. + content: + application/json: + schema: + type: string \ No newline at end of file diff --git a/spec/spec.md b/spec/spec.md index 13094f04..1060ba3c 100644 --- a/spec/spec.md +++ b/spec/spec.md @@ -436,21 +436,23 @@ Consider moving gateway registries to a seprate document. At a minimum, a gateway ****MUST**** support the [Relay API defined by Pkarr](https://github.com/Nuhvi/pkarr/blob/main/design/relays.md). -Expanding on this API, a Gateway ****MUST**** support the following API endpoints: +Expanding on this API, a Gateway ****MUST**** support the following API, which is also made available via an [OpenAPI document](#open-api-definition). #### Get the Current Difficulty +Difficulty is exposed as an **OPTIONAL** endpoint based on support of [retention proofs](#retained-did-set). + - **Method:** `GET` - **Path:** `/difficulty` -- **Returns**: - _ `200` - Success. - - `block_hash` - **string** - The most recent block hash. +- **Returns:** + - `200` - Success. + - `hash` - **string** - The current hash. - `difficulty` - **integer** - The current difficulty. - `404` - Not found. Difficulty not supported by this gateway. ```json { - "block_hash": "000000000000000000022be0c55caae4152d023dd57e8d63dc1a55c1f6de46e7", + "hash": "000000000000000000022be0c55caae4152d023dd57e8d63dc1a55c1f6de46e7", "difficulty": 26 } ``` @@ -460,17 +462,17 @@ Expanding on this API, a Gateway ****MUST**** support the following API endpoint - **Method:** `PUT` - **Path:** `/did` - **Request Body:** A JSON payload constructed as follows... - - `did` - **string** - **REQUIRED** - The DID to register. - - `sig` - **string** - **REQUIRED** - A base64URL-encoded signature of the [[ref:BEP44]] payload - - `seq` - **integer** - **REQUIRED** - A sequence number for the DID. This number ****MUST**** be unique for each DID operation, - recommended to be a unix timestamp. - - `v` - **string** - **REQUIRED** -A base64URL-encoded bencoded DNS packet containing the DID Document. + - `did` - **string** - **REQUIRED** - The DID to register or update. + - `sig` - **string** - **REQUIRED** - A base64URL-encoded signature of the [[ref:BEP44]] payload. + - `seq` - **integer** - **REQUIRED** - A sequence number for the request. This number ****MUST**** be unique for each DID operation, + recommended to be a unix timestamp in seconds. + - `v` - **string** - **REQUIRED** - A base64URL-encoded bencoded DNS packet containing the DID Document. - `retention_proof` - **string** – **OPTIONAL** - A retention proof calculated according to the [retention proof algorithm](#generating-a-retention-proof). -- **Returns**: - - `200` - Success. +- **Returns:** + - `202` - Accepted. The server has accepted the request as valid and will publish to the DHT. - `400` - Invalid request body. - `401` - Invalid signature. - - `409` - DID already exists with a higher sequence number. + - `409` - DID already exists with a higher sequence number. DID may be accepted if the [[ref:Gateway]] supports [historical resolution](#historical-resolution). ```json { @@ -482,17 +484,19 @@ Expanding on this API, a Gateway ****MUST**** support the following API endpoint ``` Upon receiving a request to register a DID, the Gateway ****MUST**** verify the signature of the request and if valid -publish the DID Document to the DHT. If the DNS Packets contains a `_typ._did` record, the Gateway ****MUST**** index the +publish the DID Document to the DHT. If the DNS Packets contains a `_typ._did.` record, the Gateway ****MUST**** index the DID by its type. #### Resolving a DID - **Method:** `GET` - **Path:** `/did/:id` -- **Returns**: + - `id` - **string** - **REQUIRED** - ID of the DID to resolve. +- **Returns:** - `200` - Success. - `did` - **object** - A JSON object representing the DID's Document. - - `types` - **array** - An array of type strings for the DID. + - `types` - **array** - An array of [type strings](#type-indexing) for the DID. + - `sequence_numbers` - **array** - An sorted array of seen sequence numbers, used with [historical resolution](#historical-resolution). - `404` - DID not found. ```json @@ -516,7 +520,8 @@ DID by its type. "authentication": ["#0"], "assertionMethod": ["#0"] }, - "types": [1, 4] + "types": [1, 4], + "sequence_numbers": [1700356854, 1700461736] } ``` @@ -532,11 +537,22 @@ packet, with its signature data, is required it is ****RECOMMENDED**** to use th ##### Historical Resolution -::: issue -[](https://github.com/TBD54566975/did-dht-method/issues/42) -Specify historical resolution API. -::: +[[ref:Nodes]] ****MAY**** choose to support historical resolution, which is to surface different version of the same [[ref:DID Document]], +sorted by sequence number, according to the rules set out in the section on [conflict resolution](#conflict-resolution). + +Upon [resolving a DID](#resolving-a-did), the Gateway will return the parameter `sequence_numbers` if there exists historical state for +a given [[ref:DID]]. The following API can be used with specific sequence numbers to fetch historical state: + +- **Method:** `GET` +- **Path:** `/did/:id?seq=:sequence_number` + - `id` - **string** - **REQUIRED** - ID of the DID to resolve + - `seq` - **integer** - **OPTIONAL** - Sequence number of the DID to resolve +- **Returns**: + - `200` - Success. + - `did` - **object** - A JSON object representing the DID's Document. + - `types` - **array** - An array of [type strings](#type-indexing) for the DID. + - `404` - DID not found for the given sequence number. #### Deactivating a DID @@ -549,32 +565,50 @@ stop republishing the DHT. If the DNS Packets contains a `_typ._did.` record, th #### Type Indexing +**Get Info** + - **Method:** `GET` -- **Path:** `/did/types?id=:id` - - `id` - **string** - **REQUIRED** -The type to query from the index. -- **Returns**: +- **Path:** `/did/types` +- **Returns:** + - `200` - Success. + - **array** - An array of objects describing the known types. + - `404` - Type indexing not supported. + +```json +[ + { + "type": 1, + "description": "Organization" + }, + { + "type": 7, + "description": "Financial Institution" + } +] +``` + +**Get a Specific Type** + +- **Method:** `GET` +- **Path:** `/did/types/:id` + - `id` - **integer** - **REQUIRED** - The type to query from the index. + - `offset` - **integer** - **OPTIONAL** - Specifies the starting position from where the type records should be retrieved (Default: `0`). + - `limit` - **integer** - **OPTIONAL** - Specifies the maximum number of type records to retrieve (Default: `100`). +- **Returns:** - `200` - Success. - - `dids` - **array** - An array of DIDs matching the associated type. + - **array** - An array of DID Identifiers matching the associated type. - `404` - Type not found. ```json -{ - "dids": [ - "did:dht:i9xkp8ddcbcg8jwq54ox699wuzxyifsqx4jru45zodqu453ksz6y", - "did:dht:uodqi99wuzxsz6yx445zxkp8ddwj9q54ocbcg8yifsqru45x63kj" - ] -} +[ + "did:dht:i9xkp8ddcbcg8jwq54ox699wuzxyifsqx4jru45zodqu453ksz6y", + "did:dht:uodqi99wuzxsz6yx445zxkp8ddwj9q54ocbcg8yifsqru45x63kj" +] ``` A query to the type index returns an array of DIDs matching the associated type. If the type is not found, a `404` is returned. If no DIDs match the type, an empty array is returned. -::: issue -[](https://github.com/TBD54566975/did-dht-method/issues/49) - -Support pagination. -::: - ## Implementation Considerations ### Conflict Resolution @@ -646,6 +680,14 @@ It is ****RECOMMENDED**** that [[ref:Gateways]] implement measures supporting th The security of data within the [[ref:Mainline DHT]] which relies on mutable records using [[ref:Ed25519]] keys—is intrinsically tied to the strength of these keys and their underlying algorithms, as outlined in [[spec:RFC8032]]. Should vulnerabilities be discovered in [[ref:Ed25519]] or if advancements in quantum computing compromise its cryptographic foundations, the [[ref:Mainline]] method could become obsolete. +## Appendix + +### Open API Definition + +```yaml +[[insert: api.yaml]] +``` + ## References [[def:Ed25519]]