├── .github └── CODEOWNERS ├── DIDDocument.schema.json ├── DIDMessage.schema.json ├── DIDOwner.schema.json ├── LICENSE ├── README.md ├── Service.schema.json ├── VerificationMethod.schema.json ├── VerificationRelationship.schema.json ├── hedera-did-method-specification.md └── images ├── crud.flow.drawio.svg └── read.flow.drawio.svg /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | ######################### 2 | ##### General Rule ###### 3 | ######################### 4 | * @hashgraph/product-management 5 | 6 | ######################### 7 | ##### Core Files ###### 8 | ######################### 9 | 10 | # NOTE: Must be placed last to ensure enforcement over all other rules 11 | 12 | # Protection Rules for Github Configuration Files and Actions Workflows 13 | /.github/ @hashgraph/platform-ci @hashgraph/release-engineering-managers @hashgraph/product-management 14 | /.github/workflows/ @hashgraph/platform-ci @hashgraph/platform-ci-committers @hashgraph/release-engineering-managers 15 | 16 | # Self-protection for root CODEOWNERS files (this file should not exist and should definitely require approval) 17 | /CODEOWNERS @hashgraph/release-engineering-managers 18 | 19 | # Protect the repository root files 20 | /README.md @hashgraph/platform-ci @hashgraph/release-engineering-managers @hashgraph/product-management 21 | **/LICENSE @hashgraph/release-engineering-managers 22 | 23 | # CodeCov configuration 24 | **/codecov.yml @hashgraph/platform-ci @hashgraph/release-engineering-managers @hashgraph/product-management 25 | 26 | # Git Ignore definitions 27 | **/.gitignore @hashgraph/platform-ci @hashgraph/release-engineering-managers @hashgraph/product-management 28 | **/.gitignore.* @hashgraph/platform-ci @hashgraph/release-engineering-managers @hashgraph/product-management 29 | -------------------------------------------------------------------------------- /DIDDocument.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "type": "object", 4 | "title": "DIDDocument HCS Event Schema", 5 | "description": "The schema describing event payload for a DIDDocument object inside a Hedera DID HCS message.", 6 | "required": ["DIDDocument"], 7 | "properties": { 8 | "DIDDocument": { 9 | "$id": "#/properties/message", 10 | "type": "object", 11 | "title": "The DID Document reference", 12 | "required": ["id", "cid"], 13 | "properties": { 14 | "id": { "type": "string" }, 15 | "type": { "type": "string" }, 16 | "cid": { "type": "string" }, 17 | "url": { "type": "string" } 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /DIDMessage.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "type": "object", 4 | "title": "Hedera DID Message Schema", 5 | "description": "The schema describing Hedera HCS DID message.", 6 | "required": [ 7 | "message", 8 | "signature" 9 | ], 10 | "properties": { 11 | "message": { 12 | "$id": "#/properties/message", 13 | "type": "object", 14 | "title": "The DID message", 15 | "description": "The DID message content", 16 | "default": {}, 17 | "additionalProperties": false, 18 | "required": [ 19 | "operation", 20 | "did", 21 | "event", 22 | "timestamp" 23 | ], 24 | "properties": { 25 | "operation": { 26 | "$id": "#/properties/message/properties/operation", 27 | "type": "string", 28 | "title": "The DID operation name", 29 | "description": "An operation name to be performed on the DID.", 30 | "default": "", 31 | "examples": [ 32 | "create", 33 | "update", 34 | "delete", 35 | "revoke" 36 | ] 37 | }, 38 | "did": { 39 | "$id": "#/properties/message/properties/did", 40 | "type": "string", 41 | "title": "The DID", 42 | "description": "The Decentralized Identifier", 43 | "default": "", 44 | "examples": [ 45 | "did:hedera:mainnet:7Prd74ry1Uct87nZqL3ny7aR7Cg46JamVbJgk8azVgUm__0.0.12345" 46 | ] 47 | }, 48 | "event": { 49 | "$id": "#/properties/message/properties/event", 50 | "type": "string", 51 | "title": "The DID Event", 52 | "description": "The Base64-encoded list of events in JSON notation", 53 | "default": "", 54 | "examples": [ 55 | "ewogICJAY29udGV...9tL3ZjLyIKICAgIH0KICBdCn0=" 56 | ] 57 | }, 58 | "timestamp": { 59 | "$id": "#/properties/message/properties/timestamp", 60 | "type": "string", 61 | "title": "The message generation timestamp", 62 | "description": "The timestamp when the message was generated on the appnet", 63 | "default": "", 64 | "examples": [ 65 | "2020-04-23T14:37:43.511Z" 66 | ] 67 | } 68 | } 69 | }, 70 | "signature": { 71 | "$id": "#/properties/signature", 72 | "type": "string", 73 | "title": "Message signature", 74 | "description": "The base64-encoded signature of the message attribute", 75 | "default": "", 76 | "examples": [ 77 | "QNB13Y7Q9...1tzjn4w==" 78 | ] 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /DIDOwner.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "type": "object", 4 | "title": "DIDOwner Schema", 5 | "properties": { 6 | "DIDOwner": { 7 | "type": "object", 8 | "properties": { 9 | "id": { "type": "string" }, 10 | "type": { "type": "string" }, 11 | "controller": { "type": "string" }, 12 | "publicKeyMultibase": { "type": "string" } 13 | }, 14 | "required": ["id", "type", "controller", "publicKeyMultibase"] 15 | } 16 | }, 17 | "required": ["DIDOwner"] 18 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2020 Hedera Hashgraph LLC 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hedera™ Hashgraph DID Method 2 | 3 | [![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-green)](LICENSE) 4 | 5 | This repository contains the Hedera Hashgraph DID method specification. 6 | 7 | ## DID Method Specification 8 | 9 | The current version of the Hedera Hashgraph DID Method Specification can be found [here](hedera-did-method-specification.md). 10 | 11 | Older versions can be viewed from tagged versions of this repo; 12 | * [v0.1](https://github.com/Meeco/hedera-did-method/releases/tag/v0.1) 13 | * [v0.9](https://github.com/Meeco/hedera-did-method/releases/tag/v0.9) 14 | 15 | Note the specification markdown file uses [pandoc `title block` syntax](https://pandoc.org/MANUAL.html#extension-pandoc_title_block) for the title and meta data so the table of content did not include these headers. 16 | 17 | To create a PDF of the document run 18 | ``` 19 | pandoc hedera-did-method-specification.md -o hedera-did-method-specification.pdf 20 | ``` 21 | 22 | Dependencies are: 23 | ``` 24 | sudo apt install pandoc librsvg2-bin texlive-latex-extra 25 | ``` 26 | 27 | ## SDKs supporting the Hedera Hashgraph DID Method & Verifiable Credentials 28 | 29 | - JavaScript SDK is maintained in a separate repository at [did-sdk-js](https://github.com/hashgraph/did-sdk-js). 30 | - Java SDK is maintained in a separate repository at [did-sdk-java](https://github.com/hashgraph/did-sdk-java). 31 | 32 | 33 | ## License Information 34 | 35 | Licensed under Apache License, Version 2.0 – see [LICENSE](LICENSE) in this repo or on the official Apache page 36 | -------------------------------------------------------------------------------- /Service.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "type": "object", 4 | "title": "Service Schema", 5 | "properties": { 6 | "Service": { 7 | "type": "object", 8 | "properties": { 9 | "id": { "type": "string" }, 10 | "type": { "type": "string" }, 11 | "serviceEndpoint": { "type": "string" } 12 | }, 13 | "required": ["id", "type", "serviceEndpoint"] 14 | } 15 | }, 16 | "required": ["Service"] 17 | } -------------------------------------------------------------------------------- /VerificationMethod.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "type": "object", 4 | "title": "VerificationMethod Schema", 5 | "properties": { 6 | "VerificationMethod": { 7 | "type": "object", 8 | "properties": { 9 | "id": { "type": "string" }, 10 | "type": { "type": "string" }, 11 | "controller": { "type": "string" }, 12 | "publicKeyMultibase": { "type": "string" } 13 | }, 14 | "required": ["id", "type", "controller", "publicKeyMultibase"] 15 | } 16 | }, 17 | "required": ["VerificationMethod"] 18 | } -------------------------------------------------------------------------------- /VerificationRelationship.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "type": "object", 4 | "title": "VerificationRelationship Schema", 5 | "properties": { 6 | "VerificationRelationship": { 7 | "type": "object", 8 | "properties": { 9 | "id": { "type": "string" }, 10 | "relationshipType": { "type": "string" }, 11 | "type": { "type": "string" }, 12 | "controller": { "type": "string" }, 13 | "publicKeyMultibase": { "type": "string" } 14 | }, 15 | "required": ["id", "relationshipType", "type", "controller", "publicKeyMultibase"] 16 | } 17 | }, 18 | "required": ["VerificationRelationship"] 19 | } -------------------------------------------------------------------------------- /hedera-did-method-specification.md: -------------------------------------------------------------------------------- 1 | % Hedera Hashgraph DID Method Specification 2 | % Authors: Paul Madsen, Jo Vercammen, Derek Munneke 3 | % Version: 1.0 4 | 5 | 6 | **Table of Contents** 7 | 8 | - [1. About](#1-about) 9 | - [1.1. Status of This Document](#11-status-of-this-document) 10 | - [1.2. About Hedera Hashgraph](#12-about-hedera-hashgraph) 11 | - [1.3. Motivation](#13-motivation) 12 | - [2. Hedera Hashgraph DID Method](#2-hedera-hashgraph-did-method) 13 | - [2.1. Namespace Specific Identifier (NSI)](#21-namespace-specific-identifier-nsi) 14 | - [2.2. Method-Specific DID URL Parameters](#22-method-specific-did-url-parameters) 15 | - [3. CRUD Operations](#3-crud-operations) 16 | - [3.1. Operations](#31-operations) 17 | - [3.1.1. Create](#311-create) 18 | - [3.1.2. Read](#312-read) 19 | - [3.1.3. Update](#313-update) 20 | - [3.1.4. Revoke](#314-revoke) 21 | - [3.1.5. Delete](#315-delete) 22 | - [3.2. Event Payload](#32-event-payload) 23 | - [3.2.1. DID Document](#321-did-document) 24 | - [3.2.2. DID Owner](#322-did-owner) 25 | - [3.2.3. Verification Method](#323-verification-method) 26 | - [3.2.4. Verification Relationship](#324-verification-relationship) 27 | - [3.2.5. Services](#325-services) 28 | - [4. Security Considerations](#4-security-considerations) 29 | - [5. Privacy Considerations](#5-privacy-considerations) 30 | - [6. Reference Implementations](#6-reference-implementations) 31 | - [7. References](#7-references) 32 | 33 | # 1. About 34 | 35 | The Hedera DID method specification conforms to the requirements of the [Decentralized Identifiers (DIDs) v1.0](https://www.w3.org/TR/2022/REC-did-core-20220719/) [W3C Recommendation](https://www.w3.org/standards/types#REC), published 19 July 2022. 36 | 37 | The following DID Method is registered in the [DID Method Registry](https://w3c-ccg.github.io/did-method-registry/). 38 | 39 | ## 1.1. Status of This Document 40 | 41 | This document is published as a Draft for feedback. 42 | 43 | ## 1.2. About Hedera Hashgraph 44 | 45 | [Hedera](https://hedera.com/) [Hashgraph](https://github.com/hashgraph) is a multi-purpose open public ledger that uses hashgraph consensus - a fast, fair, and secure alternative to blockchains. 46 | 47 | ## 1.3. Motivation 48 | 49 | This document defines a binding of the Decentralized Identifier architecture to Hedera Hashgraph - specifically how to use the Hedera Consensus Service (HCS) for CRUD mechanisms to construct and resolve a DID document from a DID. 50 | 51 | # 2. Hedera Hashgraph DID Method 52 | 53 | The namestring that shall identify this DID method is: `hedera` 54 | 55 | A DID that uses this method MUST begin with the following prefix: `did:hedera`. Per the DID specification, this string MUST be in lowercase. The remainder of the DID, after the prefix, is the NSI specified below. 56 | 57 | ## 2.1. Namespace Specific Identifier (NSI) 58 | 59 | The `did:hedera` namestring is defined by the following ABNF: 60 | 61 | ```abnf 62 | hedera-did = "did:hedera:" hedera-specific-idstring "_" hedera-specific-parameters 63 | hedera-specific-idstring = hedera-network ":" hedera-base58-key 64 | hedera-specific-parameters = did-topic-id 65 | did-topic-id = 1*DIGIT "." 1*DIGIT "." 1*DIGIT 66 | 67 | hedera-network = "mainnet" / "testnet" 68 | hedera-base58-key = 32*44(base58) 69 | base58 = "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" / "A" / "B" / 70 | "C" / "D" / "E" / "F" / "G" / "H" / "J" / "K" / "L" / "M" / "N" / 71 | "P" / "Q" / "R" / "S" / "T" / "U" / "V" / "W" / "X" / "Y" / "Z" / 72 | "a" / "b" / "c" / "d" / "e" / "f" / "g" / "h" / "i" / "j" / "k" / 73 | "m" / "n" / "o" / "p" / "q" / "r" / "s" / "t" / "u" / "v" / "w" / 74 | "x" / "y" / "z" 75 | ``` 76 | 77 | Example: 78 | 79 | ```text 80 | did:hedera:mainnet:z52k2w6rFF9xxzvmSiuyqwJS8b7oFnDtk8S3bhY4YbnJq_0.0.3474905 81 | ``` 82 | 83 | The method specific identifier `hedera-specific-idstring` is composed of a Hedera network identifier with a `:` separator followed by a `hedera-base58-key` identifier which is a base58 Encoded of a DID root public key and a `did-topic-id` (see details below). 84 | 85 | Every DID document registered on Hedera network MUST contain a public key of id `#did-root-key` and type `Ed25519VerificationKey2018`. The `hedera-base58-key` identifier is a base58 Encoded of this public key. 86 | 87 | Example Hedera DID document: 88 | 89 | ```json 90 | { 91 | "@context": "https://www.w3.org/ns/did/v1", 92 | "id": "did:hedera:testnet:z5pFuTLEhRXiMiWVb1MxBm5ZJNVNVqTgumeMboAy3fCpd_0.0.645701", 93 | "verificationMethod": [ 94 | { 95 | "id": "did:hedera:testnet:z5pFuTLEhRXiMiWVb1MxBm5ZJNVNVqTgumeMboAy3fCpd_0.0.645701#did-root-key", 96 | "type": "Ed25519VerificationKey2018", 97 | "controller": "did:hedera:testnet:z5pFuTLEhRXiMiWVb1MxBm5ZJNVNVqTgumeMboAy3fCpd_0.0.645701", 98 | "publicKeyBase58": "5pFuTLEhRXiMiWVb1MxBm5ZJNVNVqTgumeMboAy3fCpd" 99 | }, 100 | { 101 | "id": "did:hedera:testnet:z87meAWt7t2zrDxo7qw3PVTjexKWReYWS75LH29THy8kb_0.0.29617801#key-1", 102 | "type": "Ed25519VerificationKey2018", 103 | "controller": "did:hedera:testnet:z5pFuTLEhRXiMiWVb1MxBm5ZJNVNVqTgumeMboAy3fCpd_0.0.645701", 104 | "publicKeyBase58": "AvU2AEh8ybRqNwHAM3CjbkjYaYHpt9oA1uugW9EVTg6P" 105 | } 106 | ], 107 | "assertionMethod": [ 108 | "did:hedera:testnet:z5pFuTLEhRXiMiWVb1MxBm5ZJNVNVqTgumeMboAy3fCpd_0.0.645701#did-root-key" 109 | ], 110 | "authentication": [ 111 | "did:hedera:testnet:z5pFuTLEhRXiMiWVb1MxBm5ZJNVNVqTgumeMboAy3fCpd_0.0.645701#did-root-key", 112 | "did:hedera:testnet:z87meAWt7t2zrDxo7qw3PVTjexKWReYWS75LH29THy8kb_0.0.29617801#key-1" 113 | ], 114 | "service": [ 115 | { 116 | "id": "did:hedera:testnet:z6MkubW6fwkWSA97RbKs17MtLgWGHBtShQygUc5SeHueFCaG_0.0.29656231#service-1", 117 | "type": "LinkedDomains", 118 | "serviceEndpoint": "https://test.com/did" 119 | } 120 | ] 121 | } 122 | ``` 123 | 124 | ## 2.2. Method-Specific DID URL Parameters 125 | 126 | There is one method-specific parameter defined for a Hedera DID: 127 | 128 | - `did-topic-id` - an mandatory parameter that defines a TopicID of Hedera Consensus Service topic to which a particular DID document was submitted. This allow us to resolve DIDs publicly through Hedera mirror nodes. 129 | 130 | A Hedera TopicID is a triplet of numbers, e.g. `0.0.29656231` represents a topic identifier `29656231` within realm `0` within shard `0`. 131 | 132 | Realms allow Solidity smart contracts to run in parallel. Realms are not relevant to this DID Method. In the future, when the number of consensus nodes warrants, the Hedera network will be divided up into shards such that a particular transaction will be processed into consensus only by a subset of the full set of nodes. 133 | 134 | # 3. CRUD Operations 135 | 136 | Create, Update and Delete operations against a DID Document are submitted via a Consensus Service (HCS) message. 137 | 138 | ![alt text](./images/crud.flow.drawio.svg "Create, Update and Delete flow") 139 | 140 | The Read operation for resolution of a DID document from a DID happens against a mirror node. 141 | 142 | ![alt text](./images/read.flow.drawio.svg "Read flow") 143 | 144 | A valid Create, Update, Revoke or Delete message must have a JSON structure defined by a [DIDMessage-schema](DIDMessage.schema.json) and contains the following properties: 145 | 146 | - `message` - The message content with the following attributes: 147 | - `operation` - DID method operation to be performed on the DID document. Valid values are: `create` , `update` , `revoke` and `delete`. 148 | - `did` - a hedera DID namestring. 149 | - `event` - A Base64-encoded list of events in JSON notation that conforms the different properties of a DID documents to the [DID Specification](https://w3c.github.io/did-core/), the accepted events are listed within this specification. 150 | - `timestamp` - A message creation time. The value MUST be a valid XML datetime value, as defined in section 3.3.7 of [W3C XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes](https://www.w3.org/TR/xmlschema11-2/). This datetime value MUST be normalized to UTC 00:00, as indicated by the trailing "Z". It is important to note that this timestamp is a system timestamp as a variable part of the message and does not represent a consensus timestamp of a message submitted to the DID topic. 151 | - `signature` - A Base64-encoded signature that is a result of signing a minified JSON string of a message attribute with a private key corresponding to the public key `#did-root-key` in the DID document. 152 | 153 | Neither the Hedera network nor mirror nodes validate the DID Documents against the above requirements - it is business application network members that, as part of their subscription logic, must validate DID Documents based on the above criteria. The messages with duplicate signatures shall be disregarded and only the first one with verified signature is valid (in consensus timestamp order). 154 | 155 | Here is an example of a complete message wrapped in an envelope and signed: 156 | 157 | ```json 158 | { 159 | "message": { 160 | "operation": "update", 161 | "did": "did:hedera:mainnet:7Prd74ry1Uct87nZqL3ny7aR7Cg46JamVbJgk8azVgUm_0.0.12345", 162 | "event": "ewogICJAY29udGV...9tL3ZjLyIKICAgIH0KICBdCn0=", 163 | "timestamp": "2020-04-23T14:37:43.511Z" 164 | }, 165 | "signature": "QNB13Y7Q9...1tzjn4w==" 166 | } 167 | ``` 168 | 169 | It is a responsibility of a DID Controller to decide who can submit messages to their DID topic. Access control of message submission is defined by a `submitKey` property of `ConsensusCreateTopicTransaction` body. If no `submitKey` is defined for a topic, then any party can submit messages against the topic. Detailed information on Hedera Consensus Service APIs can be found in the official [Hedera API documentation](https://docs.hedera.com/hedera-api/consensus/consensusservice). 170 | 171 | ## 3.1. Operations 172 | 173 | ### 3.1.1. Create 174 | 175 | A DID is created by sending a `ConsensusSubmitMessage` transaction to a Hedera network node. It is executed by sending a `submitMessage` RPC call to the HCS API with the `ConsensusSubmitMessageTransactionBody` containing: 176 | 177 | - `topicID` - equal to the `did-topic-id` element of the DID namestring. 178 | - `message` - a JSON DID message envelope described above 179 | - `operation` set to `create` 180 | - `event` payload either a `DIDOwner` or `DIDDocument` object 181 | 182 | ### 3.1.2. Read 183 | 184 | Read, or Resolve, occurs by reading messages from the HCS topic set in the `did-topic-id` element of the DID namestring, and processing messages as below: 185 | 186 | 1. If the most recent valid message has `operation` set to `delete`, the DID document returned MUST be empty. 187 | 2. If the most recent valid message has `operation` set to `create`, and event object is `DIDDocument`, the DID document returned is the document resolve from the IPFS CID reference. 188 | 3. Otherwise 189 | 1. Read valid message until one has `operation` set to `create`, and event object is `DIDOwner`. 190 | 2. Construct DID document by applying message `update` and `revoke` operations in order. 191 | 3. Return constructed DID document. 192 | 193 | ### 3.1.3. Update 194 | 195 | A property or a DID document is updated by sending a `ConsensusSubmitMessage` transaction to a Hedera network node. It is executed by sending a `submitMessage` RPC call to HCS with the `ConsensusSubmitMessageTransactionBody` containing: 196 | 197 | - `topicID` - equal to the `did-topic-id` element of the DID namestring. 198 | - `message` - a JSON DID message envelope described above 199 | - `operation` set to `update` 200 | - `event` payload either a `Service`, `VerificationMethod` or `VerificationRelationship` object 201 | 202 | ### 3.1.4. Revoke 203 | 204 | A property or a DID document is updated by sending a `ConsensusSubmitMessage` transaction to a Hedera network node. It is executed by sending a `submitMessage` RPC call to HCS with the `ConsensusSubmitMessageTransactionBody` containing: 205 | 206 | - `topicID` - equal to the `did-topic-id` element of the DID namestring. 207 | - `message` - a JSON DID message envelope described above 208 | - `operation` set to `revoke` 209 | - `event` payload either a `Service`, `VerificationMethod` or `VerificationRelationship` object with `id` set to the property to remove. 210 | 211 | ### 3.1.5. Delete 212 | 213 | A Whole DID document is deleted/nullified by sending `ConsensusSubmitMessage` transaction to a Hedera network node. It is executed by sending a `submitMessage` RPC call to HCS with the `ConsensusSubmitMessageTransactionBody` containing: 214 | 215 | - `topicID` - equal to the `did-topic-id` element of the DID namestring. 216 | - `message` - a JSON DID message envelope described above 217 | - `operation` set to `revoke` 218 | - `event` payload will be ignored 219 | 220 | ## 3.2. Event Payload 221 | 222 | A Base64-encoded JSON object that conforms the different properties of a DID documents to the [DID Specification](https://w3c.github.io/did-core/), the accepted events are listed within this section. 223 | 224 | ### 3.2.1. DID Document 225 | 226 | A Hedera DID MAY be created by creating a reference to a DID document available in [IPFS](https://ipfs.io/). 227 | 228 | `DIDDocument` event value must have a JSON structure defined by a [DIDDocument-schema](DIDDocument.schema.json) and contains the following properties: 229 | 230 | - `DIDDocument` - The DIDOwner event with the following attributes: 231 | - `id` - The DID id 232 | - `type` - The document type, MAY include the DID document serialisation representation. 233 | - `cid` - The Content Identifiers to point to DID document in IPFS. 234 | - `url` - A URL to the IPFS document MAY be included for convenience. 235 | 236 | ```json 237 | { 238 | "DIDDocument": { 239 | "id": "did:hedera:testnet:z6MknSnvSESWvijDEysG1wHGnaiZSLSkQEXMECWvXWnd1uaJ_0.0.1723780", 240 | "type": "DIDDocument", 241 | "cid": "bafybeifn6wwfs355md56nhwaklgr2uvuoknnjobh2d2suzsdv6zpoxajfa/did-document.json", 242 | "url": "https://ipfs.io/ipfs/bafybeifn6wwfs355md56nhwaklgr2uvuoknnjobh2d2suzsdv6zpoxajfa/did-document.json" 243 | } 244 | } 245 | ``` 246 | 247 | ### 3.2.2. DID Owner 248 | 249 | Each identifier always has a controller address. By default, it is the same as the identifier address, however the resolver must validate this against the DID document. This controller address must be represented in the DID document as a verificationMethod entry with the id set as the DID being resolved and with the fragment `#did-root-key` appended to it. A reference to it must also be added to the authentication and assertionMethod arrays of the DID document. 250 | 251 | If the controller for a particular DID is changed, a `DIDOwner` event is emitted through an DID update message. The event data MUST be used to update the `#did-root-key` entry in the verificationMethod array. 252 | 253 | `DIDOwner` event must have a JSON structure defined by a [DIDOwner-schema](DIDOwner.schema.json) and contains the following properties: 254 | 255 | - `DIDOwner` - The DIDOwner event with the following attributes: 256 | - `id` - The Id property of the verification method. 257 | - `type` - reference to the verification method type. 258 | - `controller` - The DID of the entity that is authorized to make the change. 259 | - `publickeyMultibase` - Mutlibase encoded public key. 260 | 261 | ```json 262 | { 263 | "DIDOwner": { 264 | "id": "did:hedera:mainnet:7Prd74ry1Uct87nZqL3ny7aR7Cg46JamVbJgk8azVgUm_0.0.12345", 265 | "type": "Ed25519VerificationKey2018", 266 | "controller": "did:hedera:mainnet:a06295ce870b07029bfcdb2dce28d959f2815b16f81798", 267 | "publicKeyMultibase": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV", 268 | } 269 | } 270 | ``` 271 | 272 | ### 3.2.3. Verification Method 273 | 274 | A DID document can express verification methods, such as cryptographic public keys, which can be used to authenticate or authorize interactions with the DID subject or associated parties. 275 | 276 | VerificationMethod event must have a JSON structure defined by a [VerificationMethod-schema](VerificationMethod.schema.json) and contains the following properties: 277 | 278 | - `VerificationMethod` - The VerificationMethod event with the following attributes: 279 | - `id` - The Id property of the verification method. 280 | - `type` - reference to the verification method type. 281 | - `controller` - The DID of the entity that is authorized to make the change. 282 | - `publickeyMultibase` - Mutlibase encoded public key. 283 | 284 | ```json 285 | { 286 | "VerificationMethod": { 287 | "id":"did:hedera:mainnet:7Prd74ry1Uct87nZqL3ny7aR7Cg46JamVbJgk8azVgUm_0.0.12345#delegate-key1", 288 | "type": "Ed25519VerificationKey2018", 289 | "controller": "did:hedera:mainnet:7Prd74ry1Uct87nZqL3ny7aR7Cg46JamVbJgk8azVgUm_0.0.12345", 290 | "publicKeyMultibase": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV", 291 | }, 292 | } 293 | ``` 294 | 295 | ### 3.2.4. Verification Relationship 296 | 297 | A verification relationship expresses the relationship between the DID subject and a verification method. 298 | 299 | Different verification relationships enable the associated verification methods to be used for different purposes. Several useful verification relationship include: 300 | 301 | - `authentication` verification relationship is used to specify how the DID subject is expected to be authenticated, for purposes such as logging into a website or engaging in any sort of challenge-response protocol. 302 | - `assertionMethod` verification relationship allows verifier to check if a verifiable credential contains a proof created by the DID subject. 303 | - `keyAgreement` verification relationship allows the DID subject to specify how an entity can generate encryption material in order to transmit confidential information, such as for the purposes of establishing a secure communication channel with the recipient. 304 | - `capabilityInvocation` verification relationship allows the DID subject to invoke a cryptographic capability for a specific authorisation. 305 | - `capabilityDelegation` verification relationship is used to specify a mechanism that might be used by the DID subject to delegate a cryptographic capability to another party, such as delegating the authority to access a specific HTTP API to a subordinate. 306 | 307 | `VerificationRelationship` event must have a JSON structure defined by a [VerificationRelationship-schema](VerificationRelationship.schema.json) and contains the following properties: 308 | 309 | - `VerificationRelationship` - The VerificationRelationship event with the following attributes: 310 | - `id` - The Id property of the verification method. 311 | - `relationshipType` - Relationship type that is linked to specific verification method. to be performed on the DID document. Valid values are: `authentication` , `assertionMethod` , `keyAgreement` , `capabilityInvocation` and `capabilityDelegation`. 312 | - `type` - reference to the verification method type. 313 | - `controller` - The DID of the entity that is authorized to make the change. 314 | - `publickeyMultibase` - Multibase encoded public key. 315 | 316 | ```json 317 | { 318 | "VerificationRelationship": { 319 | "id":"did:hedera:mainnet:7Prd74ry1Uct87nZqL3ny7aR7Cg46JamVbJgk8azVgUm_0.0.12345#delegate-key1", 320 | "relationshipType": "authentication", 321 | "type": "Ed25519VerificationKey2018", 322 | "controller": "did:hedera:mainnet:7Prd74ry1Uct87nZqL3ny7aR7Cg46JamVbJgk8azVgUm_0.0.12345", 323 | "publicKeyMultibase": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV", 324 | }, 325 | } 326 | ``` 327 | 328 | ### 3.2.5. Services 329 | 330 | Services are used in DID documents to express ways of communicating with the DID subject or associated entities. A service can be any type of service the DID subject wants to advertise, including decentralized identity management services for further discovery, authentication, authorization, or interaction. 331 | 332 | Service event must have a JSON structure defined by a [service-schema](Service.schema.json) and contains the following properties: 333 | 334 | - `Service` - The Service event with the following attributes: 335 | - `id` - The Id property of the service. 336 | - `type` - reference to the service type. 337 | - `serviceEndpoint` - valid urn to the service endpoint. 338 | 339 | ```json 340 | { 341 | "Service": 342 | { 343 | "id": "did:hedera:mainnet:7Prd74ry1Uct87nZqL3ny7aR7Cg46JamVbJgk8azVgUm_0.0.12345#vcs", 344 | "type": "VerifiableCredentialService", 345 | "serviceEndpoint": "https://example.com/vc/" 346 | }, 347 | } 348 | ``` 349 | 350 | # 4. Security Considerations 351 | 352 | Security of Hedera DID Documents inherits the security properties of Hedera Hashgraph network itself. 353 | 354 | Hedera Hashgraph uses the hashgraph algorithm for the consensus timestamping and ordering of transactions. Hashgraph is Asynchronous Byzantine Fault Tolerant (ABFT) and fair, in that no particular node has the sole authority to decide the order of transactions, even if only for a short period of time. 355 | 356 | Hedera uses a proof of stake (POS) model to mitigate Sybil attacks. The influence of a particular node towards consensus is weighted by the amount of HBARs, the network's native coin, they control. 357 | 358 | Hedera charges fees for the processing of transactions into consensus and to partially mitigate Denial of Service attacks. 359 | 360 | In the HCS model, messages are submitted to the Hedera network nodes, which collectively assign them a consensus timestamp and order within a topic, and then are deleted from those network consensus nodes. Consensus network nodes do not persist HCS messages beyond 3 minutes. 361 | 362 | The messages are persisted only on mirror nodes, and appnet members that are subscribed to the corresponding topic. 363 | 364 | A public DID Document is sent unencrypted. Public DIDs/DID Documents include public keys and service endpoints. 365 | 366 | Write access to Hedera Consensus Service DID Topics can be controlled by stipulating a list of public keys for the topic by the DID Controller. Only HCS messages signed by the corresponding private keys will be accepted. A key can be a "threshold key", which means a list of M keys, any N of which must sign in order for the threshold signature to be considered valid. The keys within a threshold signature may themselves be threshold signatures, to allow complex signature requirements. 367 | 368 | # 5. Privacy Considerations 369 | 370 | A DID Document should not include Personally Identifiable Information (PII). 371 | 372 | The identifiers used to identify a subject create a greater risk of correlation when those identifiers are long-lived or used across more than one application domain as those domains could use that shared handle for the subject to share information about that subject without their express consent. 373 | 374 | The resolution process may leak PII as the resolver can infer that the Subject presenting the DID is interacting with the verifier resolving the DID. 375 | 376 | If DID Controllers want to mitigate the risk of correlation, they should use unique DIDs for every interaction and the corresponding DID Documents should contain a unique public key. 377 | 378 | # 6. Reference Implementations 379 | 380 | The code at [hashgraph/did-sdk-js](https://github.com/hashgraph/did-sdk-js) is intended to provide a JavaScript SDK for this DID method specification. A set of unit tests and example script commands within this repository present a reference implementation of this DID method. 381 | 382 | # 7. References 383 | 384 | - [DID Primer](https://github.com/WebOfTrustInfo/rwot5-boston/blob/master/topics-and-advance-readings/did-primer.md) 385 | - [DID Spec](https://w3c.github.io/did-core/) 386 | - 387 | - [Hedera docs](https://docs.hedera.com) 388 | - [Hedera website](https://www.hedera.com) 389 | -------------------------------------------------------------------------------- /images/crud.flow.drawio.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 |
13 | DID Owner 14 |
15 |
16 |
17 |
18 | 19 | DID O... 20 | 21 |
22 |
23 | 24 | 25 | 26 | 27 |
28 |
29 |
30 | Hedera Network Node 31 |
32 |
33 |
34 |
35 | 36 | Hedera Network Node 37 | 38 |
39 |
40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 |
48 | HCS API 49 |
50 |
51 |
52 |
53 | 54 | HCS API 55 | 56 |
57 |
58 | 59 | 60 | 61 | 62 |
63 |
64 |
65 | Hedera 66 | 67 | %3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22Hedera%20Network%20Node%22%20style%3D%22rounded%3D1%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22240%22%20y%3D%22542.5%22%20width%3D%22100%22%20height%3D%2285%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E 68 | 69 |
70 | Mirror Node 71 |
72 |
73 |
74 |
75 | 76 | Hedera %3CmxGraphMod... 77 | 78 |
79 |
80 | 81 | 82 | 83 | 84 | 85 |
86 |
87 |
88 | gossip 89 |
90 |
91 |
92 |
93 | 94 | gossip 95 | 96 |
97 |
98 |
99 | 100 | 101 | 102 | 103 | Text is not SVG - cannot display 104 | 105 | 106 | 107 |
-------------------------------------------------------------------------------- /images/read.flow.drawio.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 |
13 | Resolver 14 |
15 |
16 |
17 |
18 | 19 | Resol... 20 | 21 |
22 |
23 | 24 | 25 | 26 | 27 |
28 |
29 |
30 | Hedera 31 |
32 | Mirror Node 33 |
34 |
35 |
36 |
37 | 38 | Hedera... 39 | 40 |
41 |
42 | 43 | 44 | 45 | 46 | 47 |
48 |
49 |
50 | HTTP/gRPC API 51 |
52 |
53 |
54 |
55 | 56 | HTTP/gRPC API 57 | 58 |
59 |
60 |
61 | 62 | 63 | 64 | 65 | Text is not SVG - cannot display 66 | 67 | 68 | 69 |
--------------------------------------------------------------------------------