From cc8d3d86a87c9e690909c4226f0039d485050c7c Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Wed, 10 Apr 2024 16:41:06 -0700 Subject: [PATCH 01/35] added basic structure for ITN DID Method Specification --- README.md | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1367c66..6e848d9 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,77 @@ -# itn-did-spec -ITN DID Method Specification +The DID ITN Method Specification 1.0 +================== + +**Specification Status**: Working Draft + +**Latest Draft:** [ITN DID Specification](https://github.com/itn-trust/itn-did-spec) + +**Draft Created:** April 10, 2024 + +**Latest Update:** April 10, 2024 + +**Contributors & Editors:** + +1. [Andreas Freund](https://github.com/Therecanbeonlyone1969) +2. [Dmitry Zotov](https://github.com/AlexMesser) +3. [Parth Bhatt](https://github.com/bparth24) +4. [Umed Khudoiberdiev](https://github.com/pleerock) + + +## Abstract + +The ITN DID is specified in accordance with the [W3C DID Core specification](https://www.w3.org/TR/did-core/). + +The syntax of the identifier and accompanying data model used by the protocol is conformant with the [DID-CORE](https://www.w3.org/TR/did-core/) specification and shall be registered with the [DID-SPEC-REGISTRIES](https://www.w3.org/TR/did-spec-registries/). + + +## Conformance + +The keywords MAY, MUST, MUST NOT, RECOMMENDED, SHOULD, and SHOULD NOT in this document are to be interpreted... TBD `Not sure if required` + +## Terminology + +1. ITN - Integrated Trust Network `Not sure if required` + +## DID ITN Method Specification + +### Format + +The ITN DID is derived as the sha3-256 hash of a random salt of sufficient entropy. + +The format of ITN DID conforms to the [W3C DID Core specification](https://www.w3.org/TR/did-core/). It consists of `did:itn` prefix followed by `sha3-256(random salt)`. The W3C DID Core specification does not specify how a DID is generated, and leaves it up to the implementation provided it ensures uniqueness to a high degree of confidence. + +**Note:** Format section ensures the ITN DID Format complies with [W3C DID Method Syntax](https://w3c.github.io/did-core/#method-syntax) + +### Operations + +Text - TBD + +#### Create + +Text - TBD + +#### Read + +Text - TBD + +#### Update + +Text - TBD + +#### Deactivate + +Text - TBD + +**Note:** Operations section ensures the ITN DID Method Operations complies with [W3C DID Method Operations](https://w3c.github.io/did-core/#method-operations) + +## Security and Privacy Considerations + +**Note:** Security and Privacy Considerations section ensures the ITN DID Method Security & Privacy considerations complies with [W3C DID Method [Security](https://w3c.github.io/did-core/#security-requirements) and [Privacy](https://w3c.github.io/did-core/#privacy-requirements) Requirements] + +## Apendix + +Text - TBD `Not sure if required` + +## References + +Text - TBD `Not sure if required` \ No newline at end of file From 5865e42a6954f86da6936222d5043b097c9867a2 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Wed, 10 Apr 2024 16:51:24 -0700 Subject: [PATCH 02/35] minor changes --- README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6e848d9..ebc4680 100644 --- a/README.md +++ b/README.md @@ -64,9 +64,17 @@ Text - TBD **Note:** Operations section ensures the ITN DID Method Operations complies with [W3C DID Method Operations](https://w3c.github.io/did-core/#method-operations) -## Security and Privacy Considerations +## Security Considerations -**Note:** Security and Privacy Considerations section ensures the ITN DID Method Security & Privacy considerations complies with [W3C DID Method [Security](https://w3c.github.io/did-core/#security-requirements) and [Privacy](https://w3c.github.io/did-core/#privacy-requirements) Requirements] +Text - TBD + +**Note:** Security Considerations section ensures the ITN DID Method Security considerations complies with [W3C DID Method Security Requirements](https://w3c.github.io/did-core/#security-requirements) + +## Privacy Considerations + +Text - TBD + +**Note:** Privacy Considerations section ensures the ITN DID Method Privacy considerations complies with [W3C DID Method Privacy Requirements](https://w3c.github.io/did-core/#privacy-requirements) ## Apendix From cb34d78204879e870ae60d98b59550088ba23a81 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Wed, 10 Apr 2024 17:38:16 -0700 Subject: [PATCH 03/35] added operation descriptions. --- README.md | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ebc4680..51fbc40 100644 --- a/README.md +++ b/README.md @@ -44,23 +44,42 @@ The format of ITN DID conforms to the [W3C DID Core specification](https://www.w ### Operations -Text - TBD +**Refer** [ITN Identity Protocol](https://github.com/itn-trust/itn/tree/master/packages/sdk/agent/src/protocol/itn.mobi/identity/1.0) for technical details. `DELETE LATER BEFORE CREATING PR` + #### Create -Text - TBD +Description: Based on the DID data schema context file and DID method a ITN process anchors a DID and its DID document and delivers it to the requestor. +Constraints: Compliance with the DID data schema and DID method requirements. Can only be invoked by the DID controller(s). -#### Read -Text - TBD +#### Resolve + +Description: Based on the DID data schema context file and DID method a ITN process delivers a DID document in accordance with the W3C DID standard. +Constraints: Compliance with the DID data schema context file and DID method requirements. Any entity should be able to invoke the process. + #### Update -Text - TBD +Description: Based on the DID data schema context file and DID method a ITN process creates an updated DID document in accordance with the W3C DID standard. +Constraints: Compliance with the DID data schema context file and DID method requirements. Can only be called by the DID controller(s). + + +#### Revoke + +Description: Based on the DID data schema context file and DID method a ITN process revokes an existing DID and its DID document in accordance with the W3C DID standard. +Constraints: Compliance with the DID data schema context file and DID method. Can only be invoked by the DID controller(s). + + +#### Recover + +Description: Based on the DID data schema context file and DID method, an ITN process recovers a DID and its DID document in accordance with the W3C DID standard. +Constraints: Compliance with the DID data schema context file and DID method requirements. Can only be invoked by the DID controller(s). + #### Deactivate -Text - TBD +The ITN DID Method does not have a Deactivate operation. **Note:** Operations section ensures the ITN DID Method Operations complies with [W3C DID Method Operations](https://w3c.github.io/did-core/#method-operations) From bf0e18428fcbd85dd139649c85727573bc146d50 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Wed, 10 Apr 2024 18:05:46 -0700 Subject: [PATCH 04/35] added crypto keys and curves supported related content in appendix section. --- README.md | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 51fbc40..4a930ac 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ The ITN DID Method does not have a Deactivate operation. ## Security Considerations -Text - TBD + **Note:** Security Considerations section ensures the ITN DID Method Security considerations complies with [W3C DID Method Security Requirements](https://w3c.github.io/did-core/#security-requirements) @@ -97,7 +97,75 @@ Text - TBD ## Apendix -Text - TBD `Not sure if required` +ITN SDK has crypto-ld-suite package that provides a set of functions to generate crypto keys for use with [@digitalbazaar/crypto-ld](https://github.com/digitalbazaar/crypto-ld) library, a set of functions to create and verify signatures for use with [@digitalbazaar/jsonld-signatures](https://github.com/digitalbazaar/jsonld-signatures) library and a set of utility functions for use with crypto keys. + +Cryptographic Key Types supported + + Ed25519VerificationKey2018 + Ed25519VerificationKey2020 + X25519KeyAgreementKey2019 + X25519KeyAgreementKey2020 + EcdsaSecp256k1VerificationKey2019 + EcdsaSecp256r1VerificationKey2020 + EcdsaSecp384r1VerificationKey2020 + EcdsaSecp521r1VerificationKey2020 + RsaVerificationKey2018 + Bls12381G1Key2020 + Bls12381G2Key2020 + +Supported curves are: + + Ed25519 + X25519 + RSA + P-256 + P-384 + P-521 + Bls12381G1 + Bls12381G2 + secp256k1 + +Refer: [crypto-ld-suite](https://github.com/itn-trust/itn/tree/master/packages/sdk/crypto-ld-suite) `Not sure where to add and how to explain. Need some guidance.` +____________ + +## Message Encryptor + +Provides a set of functions to encrypt and decrypt DIDComm messages. Message Encryptor supports two forms of message +encryption: Authenticated Sender Encryption (`authcrypt`) and Anonymous Sender Encryption (`anoncrypt`). +Both forms are encrypted to the recipient DID. Only `authcrypt` provides direct assurances of who the sender is. + +#### Message Encryptor supports the following curves for the keys involved in key agreement: + +| Curve | Description | +|--------|---------------------------------------------------------------------------------------------------------------------------------------| +| X25519 | The underlying curve is actually Curve25519, however when used in the context of Diffie-Hellman
the identifier of X25519 is used | +| P-256 | NIST defined P-256 elliptic curve. | +| P-384 | NIST defined P-384 elliptic curve. | +| P-521 | NIST defined P-521 elliptic curve. | + +## +#### The following `AEAD` algorithms are supported for content encryption of the message: + +| Algorithm | Description | +|---------------|---------------------------------------------| +| A256CBC-HS512 | AES256-CBC + HMAC-SHA512 with a 512 bit key | +| A256GCM | AES256-GCM with a 256 bit key | +| XC20P | XChaCha20Poly1305 with a 256 bit key | + +## +#### The following Key Wrapping Algorithms are supported to wrap shared secret key: +| Algorithm | Curve (epk crv) | key type (epk kty) | +|-----------------|------------------|--------------------| +| ECDH-ES+A256KW | P-256 | EC | +| ECDH-ES+A256KW | P-384 | EC | +| ECDH-ES+A256KW | P-521 | EC | +| ECDH-ES+A256KW | X25519 | OKP | +| ECDH-1PU+A256KW | P-256 | EC | +| ECDH-1PU+A256KW | P-384 | EC | +| ECDH-1PU+A256KW | P-521 | EC | +| ECDH-1PU+A256KW | X25519 | OKP | + +Refer: [Agent Services](https://github.com/itn-trust/itn/blob/master/packages/sdk/agent/src/service/README.md#agent-services) `Not sure where to add and how to explain. Need some guidance.` ## References From 3ebc360579f9d8e0bbb525becfa038bace642970 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Thu, 11 Apr 2024 12:55:35 -0700 Subject: [PATCH 05/35] updates to abstract, architecture overview --- README.md | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4a930ac..e3df579 100644 --- a/README.md +++ b/README.md @@ -19,10 +19,36 @@ The DID ITN Method Specification 1.0 ## Abstract -The ITN DID is specified in accordance with the [W3C DID Core specification](https://www.w3.org/TR/did-core/). +Integrated Trust Network (ITN) is a community-built and operated network. The objectove is to build a Federated Trust Layer (Core Services) and Business Automation Interoperability Infrastructure (User Agents) for ITN. The ITN Identifier is specified in accordance with the [W3C DID Core specification](https://www.w3.org/TR/did-core/). + +ITN Identifier = ITN DID The syntax of the identifier and accompanying data model used by the protocol is conformant with the [DID-CORE](https://www.w3.org/TR/did-core/) specification and shall be registered with the [DID-SPEC-REGISTRIES](https://www.w3.org/TR/did-spec-registries/). +For a detailed read on DID and other DID method specifications, one can refer [WebOfTrustInfo - DID Primer](https://github.com/WebOfTrustInfo/rwot5-boston/blob/master/topics-and-advance-readings/did-primer.md) + +## Architecture Overview + +ITN Agent is an implementation of the [Aries Agent RFC](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0004-agents/README.md) +with a flexible plugin architecture. + +Depending on which plugins and [DIDComm protocols](https://didcomm.org/search/?page=1) you use, your instance of ITN Agent can +perform variety of roles: + +* Create and manage cryptographic keys +* Create and manage Decentralized Identifiers +* Issue and verify Verifiable Credentials (VCs) and Presentations (VPs) +* Communicate with other Agents over [DIDComm](https://identity.foundation/didcomm-messaging/spec/#discover-features-protocol-20) + +Agent provides a common interface for plugins to expand its functionality. It is designed to be modular and extensible, +so you can add new protocols, transports, and managers to fit your needs. + +Agent was written in [TypeScript](https://www.typescriptlang.org/) and runs natively in Node.js, Browsers and React Native. + +### ITN SDK + +add image here... + ## Conformance @@ -85,7 +111,7 @@ The ITN DID Method does not have a Deactivate operation. ## Security Considerations - +For all `did:itn` DIDs, the initial asset creation and subsequent updates are executed using `Ed25519` keys, which are widely recognized as a robust and secure cryptographic mechanism. `Confirm With Umed & Andreas - if keys are different. DELETE THIS COMMENT LATER.` **Note:** Security Considerations section ensures the ITN DID Method Security considerations complies with [W3C DID Method Security Requirements](https://w3c.github.io/did-core/#security-requirements) @@ -169,4 +195,4 @@ Refer: [Agent Services](https://github.com/itn-trust/itn/blob/master/packages/sd ## References -Text - TBD `Not sure if required` \ No newline at end of file +[1] W3C Decentralized Identifiers (DIDs) v1.0, https://w3c.github.io/did-core/ \ No newline at end of file From 482353b0fb08d8042cf50d3641dc0818957fed54 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Thu, 11 Apr 2024 13:02:33 -0700 Subject: [PATCH 06/35] Update README.md added ITN SDK image and agent concept. --- README.md | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index e3df579..dfbf840 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ The DID ITN Method Specification 1.0 ## Abstract -Integrated Trust Network (ITN) is a community-built and operated network. The objectove is to build a Federated Trust Layer (Core Services) and Business Automation Interoperability Infrastructure (User Agents) for ITN. The ITN Identifier is specified in accordance with the [W3C DID Core specification](https://www.w3.org/TR/did-core/). +Integrated Trust Network (ITN) is a community-built and operated network. The objective is to build a Federated Trust Layer (Core Services) and Business Automation Interoperability Infrastructure (User Agents) for ITN. The ITN Identifier is specified in accordance with the [W3C DID Core specification](https://www.w3.org/TR/did-core/). ITN Identifier = ITN DID @@ -33,7 +33,7 @@ ITN Agent is an implementation of the [Aries Agent RFC](https://github.com/hyper with a flexible plugin architecture. Depending on which plugins and [DIDComm protocols](https://didcomm.org/search/?page=1) you use, your instance of ITN Agent can -perform variety of roles: +perform a variety of roles: * Create and manage cryptographic keys * Create and manage Decentralized Identifiers @@ -43,12 +43,11 @@ perform variety of roles: Agent provides a common interface for plugins to expand its functionality. It is designed to be modular and extensible, so you can add new protocols, transports, and managers to fit your needs. -Agent was written in [TypeScript](https://www.typescriptlang.org/) and runs natively in Node.js, Browsers and React Native. +The agent was written in [TypeScript](https://www.typescriptlang.org/) and runs natively in Node.js, Browsers, and React Native. -### ITN SDK - -add image here... +## ITN SDK +![ITN_SDK](https://github.com/itn-trust/itn-did-spec/assets/18353464/6135b073-c085-41fd-8ea4-f80e64e0485d) ## Conformance @@ -64,7 +63,7 @@ The keywords MAY, MUST, MUST NOT, RECOMMENDED, SHOULD, and SHOULD NOT in this do The ITN DID is derived as the sha3-256 hash of a random salt of sufficient entropy. -The format of ITN DID conforms to the [W3C DID Core specification](https://www.w3.org/TR/did-core/). It consists of `did:itn` prefix followed by `sha3-256(random salt)`. The W3C DID Core specification does not specify how a DID is generated, and leaves it up to the implementation provided it ensures uniqueness to a high degree of confidence. +The format of ITN DID conform to the [W3C DID Core specification](https://www.w3.org/TR/did-core/). It consists of `did:itn` prefix followed by `sha3-256(random salt)`. The W3C DID Core specification does not specify how a DID is generated, and leaves it up to the implementation provided it ensures uniqueness to a high degree of confidence. **Note:** Format section ensures the ITN DID Format complies with [W3C DID Method Syntax](https://w3c.github.io/did-core/#method-syntax) @@ -75,25 +74,25 @@ The format of ITN DID conforms to the [W3C DID Core specification](https://www.w #### Create -Description: Based on the DID data schema context file and DID method a ITN process anchors a DID and its DID document and delivers it to the requestor. +Description: Based on the DID data schema context file and DID method an ITN process anchors a DID and its DID document and delivers it to the requestor. Constraints: Compliance with the DID data schema and DID method requirements. Can only be invoked by the DID controller(s). #### Resolve -Description: Based on the DID data schema context file and DID method a ITN process delivers a DID document in accordance with the W3C DID standard. +Description: Based on the DID data schema context file and DID method an ITN process delivers a DID document in accordance with the W3C DID standard. Constraints: Compliance with the DID data schema context file and DID method requirements. Any entity should be able to invoke the process. #### Update -Description: Based on the DID data schema context file and DID method a ITN process creates an updated DID document in accordance with the W3C DID standard. +Description: Based on the DID data schema context file and DID method an ITN process creates an updated DID document in accordance with the W3C DID standard. Constraints: Compliance with the DID data schema context file and DID method requirements. Can only be called by the DID controller(s). #### Revoke -Description: Based on the DID data schema context file and DID method a ITN process revokes an existing DID and its DID document in accordance with the W3C DID standard. +Description: Based on the DID data schema context file and DID method an ITN process revokes an existing DID and its DID document in accordance with the W3C DID standard. Constraints: Compliance with the DID data schema context file and DID method. Can only be invoked by the DID controller(s). @@ -111,9 +110,9 @@ The ITN DID Method does not have a Deactivate operation. ## Security Considerations -For all `did:itn` DIDs, the initial asset creation and subsequent updates are executed using `Ed25519` keys, which are widely recognized as a robust and secure cryptographic mechanism. `Confirm With Umed & Andreas - if keys are different. DELETE THIS COMMENT LATER.` +For all `did:itn` DIDs, the initial asset creation, and subsequent updates are executed using `Ed25519` keys, which are widely recognized as a robust and secure cryptographic mechanism. `Confirm With Umed & Andreas - if the keys are different. DELETE THIS COMMENT LATER.` -**Note:** Security Considerations section ensures the ITN DID Method Security considerations complies with [W3C DID Method Security Requirements](https://w3c.github.io/did-core/#security-requirements) +**Note:** Security Considerations section ensures the ITN DID Method Security considerations comply with [W3C DID Method Security Requirements](https://w3c.github.io/did-core/#security-requirements) ## Privacy Considerations @@ -195,4 +194,4 @@ Refer: [Agent Services](https://github.com/itn-trust/itn/blob/master/packages/sd ## References -[1] W3C Decentralized Identifiers (DIDs) v1.0, https://w3c.github.io/did-core/ \ No newline at end of file +[1] W3C Decentralized Identifiers (DIDs) v1.0, https://w3c.github.io/did-core/ From 9f10b604a6871b0c455d5425f1e1493f278fad18 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Thu, 11 Apr 2024 13:16:58 -0700 Subject: [PATCH 07/35] added details to CRUD operations. --- README.md | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 212 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dfbf840..83a6ab2 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,8 @@ The keywords MAY, MUST, MUST NOT, RECOMMENDED, SHOULD, and SHOULD NOT in this do ## Terminology -1. ITN - Integrated Trust Network `Not sure if required` +1. ITN - Integrated Trust Network +2. EDV - Encrypted Data Vault ## DID ITN Method Specification @@ -69,8 +70,49 @@ The format of ITN DID conform to the [W3C DID Core specification](https://www.w3 ### Operations +Identity Protocol provides methods to manage DIDs. + +#### Usage of Identity Protocols + +```typescript +import { IdentityProtocol, Agent } from "@itn-trust/agent" + +const identityProtocol = new IdentityProtocol({ + "create-did": async (message: CreateDIDMessage, next) => { + // handle CreateDIDMessage + }, + "create-did-response": async (message: CreateDIDResponseMessage, next) => { + // handle CreateDIDResponseMessage + }, + "update-did": async (message: UpdateDIDMessage, next) => { + // handle UpdateDIDMessage + }, + "update-did-response": async (message: UpdateDIDResponseMessage, next) => { + // handle UpdateDIDResponseMessage + }, + "revoke-did": async (message: RevokeDIDMessage, next) => { + // handle RevokeDIDMessage + }, + "revoke-did-response": async (message: RevokeDIDResponseMessage, next) => { + // handle RevokeDIDResponseMessage + }, + "recover-did": async (message: RecoverDIDMessage, next) => { + // handle RecoverDIDMessage + }, + "recover-did-response": async (message: RecoverDIDResponseMessage, next) => { + // handle RecoverDIDResponseMessage + }, +}) + +const agent = new Agent({ + // ... + protocols: [identityProtocol], +}) +``` + **Refer** [ITN Identity Protocol](https://github.com/itn-trust/itn/tree/master/packages/sdk/agent/src/protocol/itn.mobi/identity/1.0) for technical details. `DELETE LATER BEFORE CREATING PR` +--- #### Create @@ -78,6 +120,31 @@ Description: Based on the DID data schema context file and DID method an ITN pro Constraints: Compliance with the DID data schema and DID method requirements. Can only be invoked by the DID controller(s). +##### `create()` API + +```ts +create({ + creator: DIDString | DIDDocument, + newDID?: { + didDoc: DIDDocument, + recoveryKey: Ed25519VerificationKey2020, + } +}): Promise +``` +* `creator` - creator of the new DID, can be a DID string or DID document. +* `newDID.didDoc` - (optional) a pre-created DID Document. +* `newDID.recoveryKey` - (optional) a pre-created DID Document's recovery key. + +Sends `CreateDIDMessage` to `creator` and receives `CreateDIDResponseMessage` message in `create-did-response` handler. + +**example:** + +```typescript +await agent.protocol(IdentityProtocol).create({ creator: "did:itn:TW7PbLSe2Ws8FCx675oFUU" }) +``` + +--- + #### Resolve Description: Based on the DID data schema context file and DID method an ITN process delivers a DID document in accordance with the W3C DID standard. @@ -90,17 +157,161 @@ Description: Based on the DID data schema context file and DID method an ITN pro Constraints: Compliance with the DID data schema context file and DID method requirements. Can only be called by the DID controller(s). +##### `update()` API + +```ts +update({ + receiver: DIDString | DIDDocument, + oldDIDDoc: DIDDocument, + newDIDDoc: DIDDocument, +}):Promise +``` +* `receiver` - receiver of the update, can be a DID string or a DID document. +* `oldDIDDoc` - old DID Document to be updated +* `newDIDDoc` - new DID document containing the updates. + +Sends `UpdateDIDMessage` to `receiver` and receives `UpdateDIDResponseMessage` message in `update-did-response` handler. + +**example:** + +```typescript + +const oldDIDDoc = { + "@context": ["https://www.w3.org/ns/did/v1"], + id: "did:itn:8FcBrpSd5PTafaAzThsPbF", + assertionMethod: [ + "did:itn:8FcBrpSd5PTafaAzThsPbF#z6MkvXb9Cv5iaMEtn7PtJA5bg7Fnz3nT3AVU59ViAUJLtRrH", + ], + authentication: [ + "did:itn:8FcBrpSd5PTafaAzThsPbF#z6MkvXb9Cv5iaMEtn7PtJA5bg7Fnz3nT3AVU59ViAUJLtRrH", + ], + keyAgreement: [ + { + id: "did:itn:8FcBrpSd5PTafaAzThsPbF#z6LScBaA4yAZowVqszMCBd5zscDs6Vk4npARXGBw29ewngNX", + type: "X25519KeyAgreementKey2020", + controller: "did:itn:8FcBrpSd5PTafaAzThsPbF", + publicKeyMultibase: + "z6LScBaA4yAZowVqszMCBd5zscDs6Vk4npARXGBw29ewngNX", + }, + ], + verificationMethod: [ + { + id: "did:itn:8FcBrpSd5PTafaAzThsPbF#z6MkvXb9Cv5iaMEtn7PtJA5bg7Fnz3nT3AVU59ViAUJLtRrH", + type: "Ed25519VerificationKey2020", + controller: "did:itn:8FcBrpSd5PTafaAzThsPbF", + publicKeyMultibase: + "z6MkvXb9Cv5iaMEtn7PtJA5bg7Fnz3nT3AVU59ViAUJLtRrH", + }, + { + id: "did:itn:test#key-1", + type: "Ed25519VerificationKey2018", + controller: "did:itn:test", + publicKeyBase58: "FgF1dWCiADqWr97DUxsq6Zf1ZrzJ", + }, + ], + controller: "did:itn:Kmp7sVNtMrXZyiTKwgVWJK", +} + +const newDIDDoc = { + "@context": ["https://www.w3.org/ns/did/v1"], + id: "did:itn:8FcBrpSd5PTafaAzThsPbF", + assertionMethod: [ + "did:itn:8FcBrpSd5PTafaAzThsPbF#z6MkvXb9Cv5iaMEtn7PtJA5bg7Fnz3nT3AVU59ViAUJLtRrH", + ], + authentication: [ + "did:itn:8FcBrpSd5PTafaAzThsPbF#z6MkvXb9Cv5iaMEtn7PtJA5bg7Fnz3nT3AVU59ViAUJLtRrH", + ], + keyAgreement: [ + { + id: "did:itn:8FcBrpSd5PTafaAzThsPbF#z6LScBaA4yAZowVqszMCBd5zscDs6Vk4npARXGBw29ewngNX", + type: "X25519KeyAgreementKey2020", + controller: "did:itn:8FcBrpSd5PTafaAzThsPbF", + publicKeyMultibase: + "z6LScBaA4yAZowVqszMCBd5zscDs6Vk4npARXGBw29ewngNX", + }, + ], + verificationMethod: [ + { + id: "did:itn:8FcBrpSd5PTafaAzThsPbF#z6MkvXb9Cv5iaMEtn7PtJA5bg7Fnz3nT3AVU59ViAUJLtRrH", + type: "Ed25519VerificationKey2020", + controller: "did:itn:8FcBrpSd5PTafaAzThsPbF", + publicKeyMultibase: + "z6MkvXb9Cv5iaMEtn7PtJA5bg7Fnz3nT3AVU59ViAUJLtRrH", + }, + { + id: "did:itn:test#key-1", + type: "Ed25519VerificationKey2018", + controller: "did:itn:test", + publicKeyBase58: "FgF1dWCiADqWr97DUxsq6Zf1ZrzJ", + }, + ], + controller: "did:itn:Kmp7sVNtMrXZyiTKwgVWJK", + service: [ + { + id: "did:itn:info", + type: "Information", + serviceEndpoint: "https://example.com/info", + }, + ], + alsoKnownAs: ["https://itn.example/"], +} + +await agent.protocol(IdentityProtocol).update({ receiver: "did:itn:TW7PbLSe2Ws8FCx675oFUU", oldDIDDoc, newDIDDoc }) +``` + +--- + + #### Revoke Description: Based on the DID data schema context file and DID method an ITN process revokes an existing DID and its DID document in accordance with the W3C DID standard. Constraints: Compliance with the DID data schema context file and DID method. Can only be invoked by the DID controller(s). +##### `revoke()` API + +```ts +revoke({ did: DIDString, receiver: DIDString | DIDDocument }):Promise +``` +* `did` - DID to be revoked. +* `receiver` - receiver of the revocation, can be a DID string or a DID document. + +Sends `RevokeDIDMessage` to `receiver` and receive `RevokeDIDResponseMessage` in `revoke-did-response` handler. + +**example:** + +```typescript + +await agent + .protocol(IdentityProtocol) + .revoke({ did: "did:itn:8FcBrpSd5PTafaAzThsPbF", receiver: "did:itn:TW7PbLSe2Ws8FCx675oFUU" }) +``` + +--- + #### Recover Description: Based on the DID data schema context file and DID method, an ITN process recovers a DID and its DID document in accordance with the W3C DID standard. Constraints: Compliance with the DID data schema context file and DID method requirements. Can only be invoked by the DID controller(s). +##### `recover()` API + +```ts +recover({ did: DIDString, receiver: DIDString | DIDDocument }): Promise +``` +* `did` - DID to be recovered. +* `receiver` - receiver of the recovery, can be a DID string or a DID document. + +Sends `RecoverDIDMessage` to `receiver` and receive `RecoverDIDResponseMessage` in `recover-did-response` handler. + +**example:** + +```typescript + +await agent.protocol(IdentityProtocol).recover({ did: "did:itn:8FcBrpSd5PTafaAzThsPbF", receiver: "did:itn:TW7PbLSe2Ws8FCx675oFUU" }) +``` + +--- #### Deactivate From 7954918f05cc99b0c8600a2016b353f932a986b4 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Thu, 11 Apr 2024 13:39:59 -0700 Subject: [PATCH 08/35] added DID Document Manager in the appendix section --- README.md | 433 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 433 insertions(+) diff --git a/README.md b/README.md index 83a6ab2..3bfbf6f 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,11 @@ The agent was written in [TypeScript](https://www.typescriptlang.org/) and runs ![ITN_SDK](https://github.com/itn-trust/itn-did-spec/assets/18353464/6135b073-c085-41fd-8ea4-f80e64e0485d) +One of the protocols is Identity Protocol provides methods to manage DIDs. +One of the managers is DID Document Manager provide a set of functions to manage DID Documents. + +`Conirm with Umed & Andreas - here I am only providing necessary information related to DIDs & DID Document. Is that okay?` + ## Conformance The keywords MAY, MUST, MUST NOT, RECOMMENDED, SHOULD, and SHOULD NOT in this document are to be interpreted... TBD `Not sure if required` @@ -150,6 +155,50 @@ await agent.protocol(IdentityProtocol).create({ creator: "did:itn:TW7PbLSe2Ws8FC Description: Based on the DID data schema context file and DID method an ITN process delivers a DID document in accordance with the W3C DID standard. Constraints: Compliance with the DID data schema context file and DID method requirements. Any entity should be able to invoke the process. +##### `getDIDDoc()` API + +```ts +getDIDDoc(did: DIDString): Promise +``` +* `did` - DID Document identifier + +Retrieves the DID document for the specified DID. + +**example:** + +```typescript +const didDoc = await agent.managers.didDoc.getDIDDoc("did:itn:RGNQknTkhX6eiFaw38DrLP") + +expect(didDoc).toBe({ + "@context": ["https://www.w3.org/ns/did/v1"], + id: "did:itn:RGNQknTkhX6eiFaw38DrLP", + assertionMethod: [ + "did:itn:RGNQknTkhX6eiFaw38DrLP#z6MkkFbwWFtiXE8ioC293Fzn2hXDR5jpMXDB9iWFwz5t8WF9", + ], + authentication: [ + "did:itn:RGNQknTkhX6eiFaw38DrLP#z6MkkFbwWFtiXE8ioC293Fzn2hXDR5jpMXDB9iWFwz5t8WF9", + ], + keyAgreement: [ + { + id: "did:itn:RGNQknTkhX6eiFaw38DrLP#z6LSf7iSoxWXoRBjEHR3ZSHePgooDjRVZhAih59QUaHchPNB", + type: "X25519KeyAgreementKey2020", + controller: "did:itn:RGNQknTkhX6eiFaw38DrLP", + publicKeyMultibase: "z6LSf7iSoxWXoRBjEHR3ZSHePgooDjRVZhAih59QUaHchPNB", + }, + ], + verificationMethod: [ + { + id: "did:itn:RGNQknTkhX6eiFaw38DrLP#z6MkkFbwWFtiXE8ioC293Fzn2hXDR5jpMXDB9iWFwz5t8WF9", + type: "Ed25519VerificationKey2020", + controller: "did:itn:RGNQknTkhX6eiFaw38DrLP", + publicKeyMultibase: "z6MkkFbwWFtiXE8ioC293Fzn2hXDR5jpMXDB9iWFwz5t8WF9", + }, + ], +}) +``` + +--- + #### Update @@ -319,6 +368,8 @@ The ITN DID Method does not have a Deactivate operation. **Note:** Operations section ensures the ITN DID Method Operations complies with [W3C DID Method Operations](https://w3c.github.io/did-core/#method-operations) + + ## Security Considerations For all `did:itn` DIDs, the initial asset creation, and subsequent updates are executed using `Ed25519` keys, which are widely recognized as a robust and secure cryptographic mechanism. `Confirm With Umed & Andreas - if the keys are different. DELETE THIS COMMENT LATER.` @@ -333,6 +384,388 @@ Text - TBD ## Apendix +### DID Document Manager + +Provides a set of functions to manage DID Documents. + +#### `getDIDDoc()` API + +```ts +getDIDDoc(did: DIDString): Promise +``` +* `did` - DID Document identifier + +Retrieves the DID document for the specified DID. + +**example:** + +```typescript +const didDoc = await agent.managers.didDoc.getDIDDoc("did:itn:RGNQknTkhX6eiFaw38DrLP") + +expect(didDoc).toBe({ + "@context": ["https://www.w3.org/ns/did/v1"], + id: "did:itn:RGNQknTkhX6eiFaw38DrLP", + assertionMethod: [ + "did:itn:RGNQknTkhX6eiFaw38DrLP#z6MkkFbwWFtiXE8ioC293Fzn2hXDR5jpMXDB9iWFwz5t8WF9", + ], + authentication: [ + "did:itn:RGNQknTkhX6eiFaw38DrLP#z6MkkFbwWFtiXE8ioC293Fzn2hXDR5jpMXDB9iWFwz5t8WF9", + ], + keyAgreement: [ + { + id: "did:itn:RGNQknTkhX6eiFaw38DrLP#z6LSf7iSoxWXoRBjEHR3ZSHePgooDjRVZhAih59QUaHchPNB", + type: "X25519KeyAgreementKey2020", + controller: "did:itn:RGNQknTkhX6eiFaw38DrLP", + publicKeyMultibase: "z6LSf7iSoxWXoRBjEHR3ZSHePgooDjRVZhAih59QUaHchPNB", + }, + ], + verificationMethod: [ + { + id: "did:itn:RGNQknTkhX6eiFaw38DrLP#z6MkkFbwWFtiXE8ioC293Fzn2hXDR5jpMXDB9iWFwz5t8WF9", + type: "Ed25519VerificationKey2020", + controller: "did:itn:RGNQknTkhX6eiFaw38DrLP", + publicKeyMultibase: "z6MkkFbwWFtiXE8ioC293Fzn2hXDR5jpMXDB9iWFwz5t8WF9", + }, + ], +}) +``` + +#### `saveDIDDoc()` API + +```ts +saveDIDDoc(args?: { + did?: DIDString + controller?: DIDDocument + operationId?: UUIDString + recoveryKey?: Ed25519VerificationKey2020 + didDocument?: Partial + metadata?: { + name?: string + description?: string + tags?: string[] + } +}): Promise<{ + recoveryKey: Ed25519VerificationKey2020 + didDoc: DIDDocument +}> +``` +* `args` - (optional) arguments for saving the DID document + +Saves the DID document along with the necessary keys and metadata into the wallet. +If `operationId` provided, saves as a wallet operation until `wallet.commitChanges()` or `wallet.rollbackChanges()` is called. + +**example:** + +```typescript +const { recoveryKey, didDoc } = await agent.managers.didDoc.createDID() + +expect(recoveryKey).toBe({ + "@context": ["https://w3id.org/security/suites/ed25519-2020/v1"], + id: "did:itn:RSF6nsbNFXW1Rpny3pKUuu#z6Mksmhto6EJEHQ97ewZMv6hAcSEvWTw3dBLfu2vDax94qxu", + type: "Ed25519VerificationKey2020", + controller: "did:itn:RSF6nsbNFXW1Rpny3pKUuu", + publicKeyMultibase: "z6Mksmhto6EJEHQ97ewZMv6hAcSEvWTw3dBLfu2vDax94qxu", + privateKeyMultibase: "z3u2i7PnbgcQvCxbBbmEYA4sfXmGhswEiYB5LHUAWsgFXaXW", + name: "Recovery Key", + description: "Used to recover identity.", + tags: [], +}) + + +expect(didDoc).toBe({ + "@context": ["https://www.w3.org/ns/did/v1"], + id: "did:itn:RSF6nsbNFXW1Rpny3pKUuu", + assertionMethod: [ + "did:itn:RSF6nsbNFXW1Rpny3pKUuu#z6MkuFe4dc9njM5uBNQL2rhubLx5jZRjLP8ftuXwz45Mvg5F", + ], + authentication: [ + "did:itn:RSF6nsbNFXW1Rpny3pKUuu#z6MkuFe4dc9njM5uBNQL2rhubLx5jZRjLP8ftuXwz45Mvg5F", + ], + keyAgreement: [ + { + id: "did:itn:RSF6nsbNFXW1Rpny3pKUuu#z6LSpUuyUHWwpjyK59xE9d5ZrtDqN6ya7RzBjyPxgsAT2VNL", + type: "X25519KeyAgreementKey2020", + controller: "did:itn:RSF6nsbNFXW1Rpny3pKUuu", + publicKeyMultibase: "z6LSpUuyUHWwpjyK59xE9d5ZrtDqN6ya7RzBjyPxgsAT2VNL", + }, + ], + verificationMethod: [ + { + id: "did:itn:RSF6nsbNFXW1Rpny3pKUuu#z6MkuFe4dc9njM5uBNQL2rhubLx5jZRjLP8ftuXwz45Mvg5F", + type: "Ed25519VerificationKey2020", + controller: "did:itn:RSF6nsbNFXW1Rpny3pKUuu", + publicKeyMultibase: "z6MkuFe4dc9njM5uBNQL2rhubLx5jZRjLP8ftuXwz45Mvg5F", + }, + ], +}) +``` + +--- + +#### `updateDIDDoc()` API + +```ts + updateDIDDoc( + oldDIDDoc: DIDDocument, + newDIDDoc: DIDDocument, + operationId?: UUIDString, + ): Promise +``` +* `oldDIDDoc` - old DID Document +* `newDIDDoc` - new DID Document +* `operationId` - (optional) if provided, saves DID Document update as a wallet operation until `wallet.commitChanges()` or `wallet.rollbackChanges()` is called. + +Updates the DID Document. + +**example:** + +```typescript +const oldDIDDoc = { + "@context": ["https://www.w3.org/ns/did/v1"], + id: "did:itn:X9ns1DteHSXCL8AjgCvDhF", + assertionMethod: [ + "did:itn:X9ns1DteHSXCL8AjgCvDhF#z6Mkn1HjxP4C9sq6P6ruemWe8eQZa3jPLAADLJUYJnZ9g5xj", + ], + authentication: [ + "did:itn:X9ns1DteHSXCL8AjgCvDhF#z6Mkn1HjxP4C9sq6P6ruemWe8eQZa3jPLAADLJUYJnZ9g5xj", + ], + keyAgreement: [ + { + id: "did:itn:X9ns1DteHSXCL8AjgCvDhF#z6LSenEkHyRX5sqDX7KsPFta9daxNNWNuNV9nZPHFLiF6343", + type: "X25519KeyAgreementKey2020", + controller: "did:itn:X9ns1DteHSXCL8AjgCvDhF", + publicKeyMultibase: "z6LSenEkHyRX5sqDX7KsPFta9daxNNWNuNV9nZPHFLiF6343", + }, + ], + verificationMethod: [ + { + id: "did:itn:X9ns1DteHSXCL8AjgCvDhF#z6Mkn1HjxP4C9sq6P6ruemWe8eQZa3jPLAADLJUYJnZ9g5xj", + type: "Ed25519VerificationKey2020", + controller: "did:itn:X9ns1DteHSXCL8AjgCvDhF", + publicKeyMultibase: "z6Mkn1HjxP4C9sq6P6ruemWe8eQZa3jPLAADLJUYJnZ9g5xj", + }, + ], +} + +const newDIDDoc = { + ...didDoc, + service: [ + { + id: "did:itn:info", + type: "Information", + serviceEndpoint: "https://example.com/info", + }, + ], +} + +await agent.managers.didDoc.updateDIDDoc(oldDIDDoc, newDIDDoc) +``` + +--- + +#### `revokeDID()` API + +```ts +revokeDID(did: DIDString, operationId?: UUIDString): Promise +``` +* `did` - DID to be revoked +* `operationId` - (optional) if provided, saves DID Document revoke as a wallet operation until "wallet.commitChanges()" or "wallet.rollbackChanges()" is called. + +Revoke a DID by updating its associated DID Document. + +**example:** + +```typescript +await agent.managers.didDoc.revokeDID("did:itn:4wqjsfTA8jghZK9Xw6TQDL") +``` + +--- + +#### `recoverDID()` API + +```ts +recoverDID(did: DIDString, operationId?: UUIDString): Promise<{ + recoveryKey: Ed25519VerificationKey2020 + didDocContent: DIDDocContent +}> +``` +* `did` - DID to be recovered +* `operationId` - (optional) if provided, saves DID Document revoke as a wallet operation until "wallet.commitChanges()" or "wallet.rollbackChanges()" is called. + +Recovers a DID by creating a new DID document, signing and encryption keys, and updating the existing DID document content +in the wallet. + + +**example:** + +```typescript +const { + recoveryKey, + didDocContent, +} = await wallet.didDocManager.recoverDID( + "did:itn:Aw8tt7G1AhSCHfBrsuzrJG") + +// new recovery key +expect(recoveryKey).toBe( + { + "@context": ["https://w3id.org/security/suites/ed25519-2020/v1"], + id: "did:itn:Aw8tt7G1AhSCHfBrsuzrJG#z6MkjsGqthRZLsYW3EaYW63iRbXFeGJftFmsA3Z1uJziSPq7", + type: "Ed25519VerificationKey2020", + controller: "did:itn:Aw8tt7G1AhSCHfBrsuzrJG", + publicKeyMultibase: "z6MkjsGqthRZLsYW3EaYW63iRbXFeGJftFmsA3Z1uJziSPq7", + privateKeyMultibase: "z3u2W6p14p2mTmCCozMZqqdiSjYYtfFXfDjcutQDRTyDQjY7", + name: "Recovery Key", + description: "Used to recover identity.", + tags: [], + }, +) + +// new did document content +expect(didDocContent).toBe( + { + id: "63caefb9-1af2-48e9-9f22-9cf04ed7558e", + type: "DIDDocument", + body: { + tags: [], + didDocument: { + "@context": [ + "https://www.w3.org/ns/did/v1", + ], + id: "did:itn:Aw8tt7G1AhSCHfBrsuzrJG", + assertionMethod: [ + "did:itn:Aw8tt7G1AhSCHfBrsuzrJG#z6Mkuz76zmSj8Fb6PeE4AThcVTUeVADfBw4xQcGf6tYPx2SK", + ], + authentication: [ + "did:itn:Aw8tt7G1AhSCHfBrsuzrJG#z6Mkuz76zmSj8Fb6PeE4AThcVTUeVADfBw4xQcGf6tYPx2SK", + ], + keyAgreement: [ + { + id: "did:itn:Aw8tt7G1AhSCHfBrsuzrJG#z6LSquqPkSUf9YHjoNYmuD6Jn5HxZihvXnXi9YrcJm42rMGT", + type: "X25519KeyAgreementKey2020", + controller: "did:itn:Aw8tt7G1AhSCHfBrsuzrJG", + publicKeyMultibase: "z6LSquqPkSUf9YHjoNYmuD6Jn5HxZihvXnXi9YrcJm42rMGT", + }, + ], + verificationMethod: [ + { + id: "did:itn:Aw8tt7G1AhSCHfBrsuzrJG#z6Mkuz76zmSj8Fb6PeE4AThcVTUeVADfBw4xQcGf6tYPx2SK", + type: "Ed25519VerificationKey2020", + controller: "did:itn:Aw8tt7G1AhSCHfBrsuzrJG", + publicKeyMultibase: "z6Mkuz76zmSj8Fb6PeE4AThcVTUeVADfBw4xQcGf6tYPx2SK", + }, + ], + controller: "did:itn:RGNQknTkhX6eiFaw38DrLP", + }, + }, + created: 1699006922350, + updated: 1699006922350, + }, +) +``` + +--- + +#### `getDIDResolutionResultContent()` API + +```ts +getDIDResolutionResultContent(did: DIDString): Promise +``` +* `did` - DID Document to retrieve the resolution result + +Retrieves the content of a DID resolution result based on the provided DID. + +**example:** + +```typescript +const didResolutionContent = await agent.managers.didDoc.getDIDResolutionResultContent("did:itn:BRZ2CKoq2kV1WiuMYZcBwu") + +expect(didResolutionContent).toBe({ + id: "f0967614-8bc2-4f7d-9dba-76ba18205113", + type: "DIDResolutionResult", + body: { + "@context": ["https://w3id.org/did-resolution/v1"], + tags: [], + created: "2023-11-03T10:42:27.093Z", + expires: "2023-11-04T10:42:27.093Z", + didDocument: { + "@context": ["https://www.w3.org/ns/did/v1"], + id: "did:itn:B8G98VLFmv1o1h3CVF8fLQ", + assertionMethod: ["did:itn:BRZ2CKoq2kV1WiuMYZcBwu#z6MkgG2CF1h4gcjpxX5wW1z55NzJ6DQMmJnVNcagb4kCggMM"], + authentication: ["did:itn:BRZ2CKoq2kV1WiuMYZcBwu#z6MkgG2CF1h4gcjpxX5wW1z55NzJ6DQMmJnVNcagb4kCggMM"], + keyAgreement: [{ + id: "did:itn:BRZ2CKoq2kV1WiuMYZcBwu#z6LSrGYukPKRADR2GZk25uAYwpZdF2qF75Xgm6dQS3gdEB1F", + type: "X25519KeyAgreementKey2020", + controller: "did:itn:BRZ2CKoq2kV1WiuMYZcBwu", + publicKeyMultibase: "z6LSrGYukPKRADR2GZk25uAYwpZdF2qF75Xgm6dQS3gdEB1F", + }], + verificationMethod: [{ + id: "did:itn:BRZ2CKoq2kV1WiuMYZcBwu#z6MkgG2CF1h4gcjpxX5wW1z55NzJ6DQMmJnVNcagb4kCggMM", + type: "Ed25519VerificationKey2020", + controller: "did:itn:BRZ2CKoq2kV1WiuMYZcBwu", + publicKeyMultibase: "z6MkgG2CF1h4gcjpxX5wW1z55NzJ6DQMmJnVNcagb4kCggMM", + }], + }, + didResolutionMetadata: {}, + didDocumentMetadata: { + created: "2023-11-03T10:42:27.093Z", + }, + }, + created: 1699008147093, + updated: 1699008147093, +}) +``` + +--- + +#### `saveDIDResolutionResult()` API + +```ts +saveDIDResolutionResult(result: DIDResolutionResult): Promise +``` + +* `result` - DID resolution result to be saved + +Saves the DID resolution result to the wallet. + +**example:** + +```typescript + const didResolutionResult = { + didDocument: { + "@context": ["https://www.w3.org/ns/did/v1"], + id: "did:itn:RSF6nsbNFXW1Rpny3pKUuu", + assertionMethod: [ + "did:itn:RSF6nsbNFXW1Rpny3pKUuu#z6MkuFe4dc9njM5uBNQL2rhubLx5jZRjLP8ftuXwz45Mvg5F", + ], + authentication: [ + "did:itn:RSF6nsbNFXW1Rpny3pKUuu#z6MkuFe4dc9njM5uBNQL2rhubLx5jZRjLP8ftuXwz45Mvg5F", + ], + keyAgreement: [ + { + id: "did:itn:RSF6nsbNFXW1Rpny3pKUuu#z6LSpUuyUHWwpjyK59xE9d5ZrtDqN6ya7RzBjyPxgsAT2VNL", + type: "X25519KeyAgreementKey2020", + controller: "did:itn:RSF6nsbNFXW1Rpny3pKUuu", + publicKeyMultibase: "z6LSpUuyUHWwpjyK59xE9d5ZrtDqN6ya7RzBjyPxgsAT2VNL", + }, + ], + verificationMethod: [ + { + id: "did:itn:RSF6nsbNFXW1Rpny3pKUuu#z6MkuFe4dc9njM5uBNQL2rhubLx5jZRjLP8ftuXwz45Mvg5F", + type: "Ed25519VerificationKey2020", + controller: "did:itn:RSF6nsbNFXW1Rpny3pKUuu", + publicKeyMultibase: "z6MkuFe4dc9njM5uBNQL2rhubLx5jZRjLP8ftuXwz45Mvg5F", + }, + ], + }, + contentType: undefined, + created: new Date().toISOString(), +} + +await agent.managers.didDoc.saveDIDResolutionResult(didResolutionResult) +``` + +--- + ITN SDK has crypto-ld-suite package that provides a set of functions to generate crypto keys for use with [@digitalbazaar/crypto-ld](https://github.com/digitalbazaar/crypto-ld) library, a set of functions to create and verify signatures for use with [@digitalbazaar/jsonld-signatures](https://github.com/digitalbazaar/jsonld-signatures) library and a set of utility functions for use with crypto keys. Cryptographic Key Types supported From 7cb4220154411910639a1e7d3b59bb4b3678644b Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Thu, 11 Apr 2024 13:40:43 -0700 Subject: [PATCH 09/35] Updated the last update date. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3bfbf6f..a67161f 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ The DID ITN Method Specification 1.0 **Draft Created:** April 10, 2024 -**Latest Update:** April 10, 2024 +**Latest Update:** April 11, 2024 **Contributors & Editors:** From 58a4f1f8e6960f34b2706995f3b9414148642c02 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Thu, 11 Apr 2024 13:43:57 -0700 Subject: [PATCH 10/35] corrected the spelling. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a67161f..c2d92e8 100644 --- a/README.md +++ b/README.md @@ -382,7 +382,7 @@ Text - TBD **Note:** Privacy Considerations section ensures the ITN DID Method Privacy considerations complies with [W3C DID Method Privacy Requirements](https://w3c.github.io/did-core/#privacy-requirements) -## Apendix +## Appendix ### DID Document Manager From 1b8b342d05c7b573086ce61e0740d1926ccdac0f Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Mon, 15 Apr 2024 15:03:07 -0700 Subject: [PATCH 11/35] Updated the operations section with requirements. Added DID Document sample in the Resolve operation. Improved explanation. --- README.md | 124 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 81 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index c2d92e8..8084983 100644 --- a/README.md +++ b/README.md @@ -49,8 +49,8 @@ The agent was written in [TypeScript](https://www.typescriptlang.org/) and runs ![ITN_SDK](https://github.com/itn-trust/itn-did-spec/assets/18353464/6135b073-c085-41fd-8ea4-f80e64e0485d) -One of the protocols is Identity Protocol provides methods to manage DIDs. -One of the managers is DID Document Manager provide a set of functions to manage DID Documents. +The ITN SDK has an Identity Protocol provides methods to manage DIDs. +The ITN SDK has a DID Document Manager provide a set of functions to manage DID Documents. `Conirm with Umed & Andreas - here I am only providing necessary information related to DIDs & DID Document. Is that okay?` @@ -122,7 +122,15 @@ const agent = new Agent({ #### Create Description: Based on the DID data schema context file and DID method an ITN process anchors a DID and its DID document and delivers it to the requestor. -Constraints: Compliance with the DID data schema and DID method requirements. Can only be invoked by the DID controller(s). +Constraints: Can only be invoked by the DID controller(s). + +Requirements: + +- `creator` input parameter can be a DID String or a DID document. +- The provided DID MUST be compliant with the did:itn method. +- The provided DID document MUST be compliant with the DID V1.0 DID document specification. + +`Note: Question to Umed -- as per below comments - if its just DID string - how & when DID Document is created then??` ##### `create()` API @@ -153,57 +161,73 @@ await agent.protocol(IdentityProtocol).create({ creator: "did:itn:TW7PbLSe2Ws8FC #### Resolve Description: Based on the DID data schema context file and DID method an ITN process delivers a DID document in accordance with the W3C DID standard. -Constraints: Compliance with the DID data schema context file and DID method requirements. Any entity should be able to invoke the process. - -##### `getDIDDoc()` API +Constraints: Any entity should be able to invoke the process. -```ts -getDIDDoc(did: DIDString): Promise -``` -* `did` - DID Document identifier +Requirements: -Retrieves the DID document for the specified DID. +- A DID string MUST be provided as an input parameter. +- The provided DID MUST be compliant with the did:itn method. **example:** ```typescript -const didDoc = await agent.managers.didDoc.getDIDDoc("did:itn:RGNQknTkhX6eiFaw38DrLP") +await agent.resolveDIDDoc("did:itn:NL28Bubaa8xUmhJAARNkNS") +``` -expect(didDoc).toBe({ - "@context": ["https://www.w3.org/ns/did/v1"], - id: "did:itn:RGNQknTkhX6eiFaw38DrLP", - assertionMethod: [ - "did:itn:RGNQknTkhX6eiFaw38DrLP#z6MkkFbwWFtiXE8ioC293Fzn2hXDR5jpMXDB9iWFwz5t8WF9", - ], - authentication: [ - "did:itn:RGNQknTkhX6eiFaw38DrLP#z6MkkFbwWFtiXE8ioC293Fzn2hXDR5jpMXDB9iWFwz5t8WF9", - ], - keyAgreement: [ - { - id: "did:itn:RGNQknTkhX6eiFaw38DrLP#z6LSf7iSoxWXoRBjEHR3ZSHePgooDjRVZhAih59QUaHchPNB", - type: "X25519KeyAgreementKey2020", - controller: "did:itn:RGNQknTkhX6eiFaw38DrLP", - publicKeyMultibase: "z6LSf7iSoxWXoRBjEHR3ZSHePgooDjRVZhAih59QUaHchPNB", - }, - ], - verificationMethod: [ - { - id: "did:itn:RGNQknTkhX6eiFaw38DrLP#z6MkkFbwWFtiXE8ioC293Fzn2hXDR5jpMXDB9iWFwz5t8WF9", - type: "Ed25519VerificationKey2020", - controller: "did:itn:RGNQknTkhX6eiFaw38DrLP", - publicKeyMultibase: "z6MkkFbwWFtiXE8ioC293Fzn2hXDR5jpMXDB9iWFwz5t8WF9", - }, - ], -}) +Response to above code will be a DID Document as below: + +```json +{ + "didDocument": { + "@context": [ + "https://www.w3.org/ns/did/v1" + ], + "assertionMethod": [ + "did:itn:NL28Bubaa8xUmhJAARNkNS#z6MkiYmb7ncfDAAhcxtAAGsm1oySq4KYJtsi2wHaoKAnmVXC" + ], + "authentication": [ + "did:itn:NL28Bubaa8xUmhJAARNkNS#z6MkiYmb7ncfDAAhcxtAAGsm1oySq4KYJtsi2wHaoKAnmVXC" + ], + "id": "did:itn:NL28Bubaa8xUmhJAARNkNS", + "keyAgreement": [ + { + "id": "did:itn:NL28Bubaa8xUmhJAARNkNS#z6LSd76Tk2UJ3RVxcTjYjZ8TfvHMQgZG5HmbKPmCidPXyTGZ", + "type": "X25519KeyAgreementKey2020", + "controller": "did:itn:NL28Bubaa8xUmhJAARNkNS", + "publicKeyMultibase": "z6LSd76Tk2UJ3RVxcTjYjZ8TfvHMQgZG5HmbKPmCidPXyTGZ" + } + ], + "verificationMethod": [ + { + "id": "did:itn:NL28Bubaa8xUmhJAARNkNS#z6MkiYmb7ncfDAAhcxtAAGsm1oySq4KYJtsi2wHaoKAnmVXC", + "type": "Ed25519VerificationKey2020", + "controller": "did:itn:NL28Bubaa8xUmhJAARNkNS", + "publicKeyMultibase": "z6MkiYmb7ncfDAAhcxtAAGsm1oySq4KYJtsi2wHaoKAnmVXC" + } + ] + }, + "didDocumentMetadata": { + "created": "2023-11-10T15:20:59Z", + "updated": "2023-11-10T15:20:59Z", + "deactivated": false, + "recoveryCommitment": "99cdefca761b58664641d3f0b89b4f1e04ad833b7a24a726e3424bc6c17f39a0" + }, + "didResolutionMetadata": { } +} ``` --- - #### Update Description: Based on the DID data schema context file and DID method an ITN process creates an updated DID document in accordance with the W3C DID standard. -Constraints: Compliance with the DID data schema context file and DID method requirements. Can only be called by the DID controller(s). +Constraints: Can only be called by the DID controller(s). + +Requirements: + +- `receiver` input parameter can be a DID string or a DID Document. +- The provided DID string MUST be compliant with the did:itn method. +- The provided DID document MUST be compliant with the DID V1.0 DID document specification. ##### `update()` API @@ -314,7 +338,14 @@ await agent.protocol(IdentityProtocol).update({ receiver: "did:itn:TW7PbLSe2Ws8F #### Revoke Description: Based on the DID data schema context file and DID method an ITN process revokes an existing DID and its DID document in accordance with the W3C DID standard. -Constraints: Compliance with the DID data schema context file and DID method. Can only be invoked by the DID controller(s). +Constraints: Can only be invoked by the DID controller(s). + +Requirements: + +- `did` input parameter MUST be a DID string that has to be revoked. +- `receiver` input parameter can be a DID string or a DID Document. +- The provided DID string MUST be compliant with the did:itn method. +- The provided DID document MUST be compliant with the DID V1.0 DID document specification. ##### `revoke()` API @@ -341,7 +372,14 @@ await agent #### Recover Description: Based on the DID data schema context file and DID method, an ITN process recovers a DID and its DID document in accordance with the W3C DID standard. -Constraints: Compliance with the DID data schema context file and DID method requirements. Can only be invoked by the DID controller(s). +Constraints: Can only be invoked by the DID controller(s). + +Requirements: + +- `did` input parameter MUST be a DID string that has to be recovered. +- `receiver` input parameter can be a DID string or a DID Document. +- The provided DID string MUST be compliant with the did:itn method. +- The provided DID document MUST be compliant with the DID V1.0 DID document specification. ##### `recover()` API @@ -364,7 +402,7 @@ await agent.protocol(IdentityProtocol).recover({ did: "did:itn:8FcBrpSd5PTafaAzT #### Deactivate -The ITN DID Method does not have a Deactivate operation. +The `revoke` operation also deactivate the DID. **Note:** Operations section ensures the ITN DID Method Operations complies with [W3C DID Method Operations](https://w3c.github.io/did-core/#method-operations) From cd99752a49a895f4b02d7e7e73e739e725c89941 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Mon, 15 Apr 2024 15:23:37 -0700 Subject: [PATCH 12/35] added the ITN Architecture Overview --- README.md | 29 ++++++++++++++++++++++ docs/images/ITN Agent.jpg | Bin 0 -> 47745 bytes docs/images/ITN Architecture Overview.jpg | Bin 0 -> 94646 bytes 3 files changed, 29 insertions(+) create mode 100644 docs/images/ITN Agent.jpg create mode 100644 docs/images/ITN Architecture Overview.jpg diff --git a/README.md b/README.md index 8084983..c1be55b 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,35 @@ For a detailed read on DID and other DID method specifications, one can refer [W ## Architecture Overview +The ITN is a permissioned network of nodes operated by ITN Node Operators. + +Each ITN Node is comprised of the following elements depicted in the figure below: +- ITN Agent for Core Services ~ (former name used - Self Sovereign Digital Twin (SSDT) of the Core Services OR Core Services SSDT) +- DLT Gateway: A NodeJS application integrating with the Core Services SSDT, Apache Kafka, and the different DLT networks of the ITN. In the next phase of implementation, the Apache Kafka instances will be connected via message replication to obtain a holistic picture of messages across the network. +- DID Resolver: The DID resolver utilizes the Decentralized Identity Foundation DID resolver and is integrated with the Core Services SSDT. +- Content Addressable Storage Network: Currently utilizing an append-only implementation of a Postgres DB with content-addressable hashes and replication between ITN Nodes. There is an implementation of peer-to-peer replication using the IPFS Cluster. +- DLT Networks: It is comprised of a Hyperledger Fabric network and Arbitrum One EVM equivalent network (with more to follow, in particular, based on Integrated Trust Network (ITN) expansion). + +All applications external to the ITN and wishing to utilize the ITN Core Services must implement an ITN Agent as their abstraction layer through the ITN SDK in the [ITN GitHub repository](https://github.com/itn-trust/itn). An ITN Agent represents a user’s capabilities on ITN and serves as an abstraction and integration layer between ITN and other applications/networks. + +![Getting Started](docs/images/ITN Architecture Overview.jpg) + + +The ITN Agent utilized in each ITN node is implemented in NodeJS and is comprised of the following elements: + +- API Endpoint Service for both REST APIs and [Decentralized Identity Foundation (DIF) DIDcomm](https://identity.foundation/didcomm-messaging/spec/) messaging protocol for integration with ITN Core Services, other Agents, and Legacy Applications via REST APIs +- Authentication service utilizing [OAuth2 for REST APIs](https://oauth.net/2/) and [DIF DID AuthN](https://identity.foundation/working-groups/authentication.html) for DIF DIDcomm messaging +- An implementation of the [W3C Universal Wallet](https://w3c-ccg.github.io/universal-wallet-interop-spec/) for key and document management +- An implementation of the W3C Verifiable Credential Issuance and Verification standard both as REST APIs and as DIDcomm endpoints +- Implementation of ITN Data Sharing APIs both as REST APIs and as DIDcomm endpoints +- An implementation of ITN Core Services functionality via DIF DIDcomm +- An implementation of the [W3C/DIF Encrypted Data Vault](https://identity.foundation/confidential-storage/) for document storage currently utilizing CouchDB with Leader-Leader replication + +Integration of an ITN Agent in any application is achieved through the ITN SDK. + +![Getting Started](docs/images/ITN Agent.jpg) + + ITN Agent is an implementation of the [Aries Agent RFC](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0004-agents/README.md) with a flexible plugin architecture. diff --git a/docs/images/ITN Agent.jpg b/docs/images/ITN Agent.jpg new file mode 100644 index 0000000000000000000000000000000000000000..efed6168cc3612f4319c515f1db4ce6f7d35c181 GIT binary patch literal 47745 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 -t&UJh8vI(bEJlfKhmG1cAR@+!7v{x32nM@A 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 L4Fx;w|K9`vU#`*3 literal 0 HcmV?d00001 diff --git a/docs/images/ITN Architecture Overview.jpg b/docs/images/ITN Architecture Overview.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a833a183ac48828c888a6d22d9ba85eb93b10096 GIT binary patch literal 94646 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 z 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 Pwe{ Date: Mon, 15 Apr 2024 15:30:31 -0700 Subject: [PATCH 13/35] updated the image paths --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c1be55b..f1cd58a 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ The DID ITN Method Specification 1.0 **Draft Created:** April 10, 2024 -**Latest Update:** April 11, 2024 +**Latest Update:** April 15, 2024 **Contributors & Editors:** @@ -40,7 +40,7 @@ Each ITN Node is comprised of the following elements depicted in the figure belo All applications external to the ITN and wishing to utilize the ITN Core Services must implement an ITN Agent as their abstraction layer through the ITN SDK in the [ITN GitHub repository](https://github.com/itn-trust/itn). An ITN Agent represents a user’s capabilities on ITN and serves as an abstraction and integration layer between ITN and other applications/networks. -![Getting Started](docs/images/ITN Architecture Overview.jpg) +![ITN Architecture Overview](./docs/images/ITN%20Architecture%20Overview.jpg) The ITN Agent utilized in each ITN node is implemented in NodeJS and is comprised of the following elements: @@ -55,7 +55,7 @@ The ITN Agent utilized in each ITN node is implemented in NodeJS and is comprise Integration of an ITN Agent in any application is achieved through the ITN SDK. -![Getting Started](docs/images/ITN Agent.jpg) +![ITN Agent](./docs/images/ITN%20Agent.jpg) ITN Agent is an implementation of the [Aries Agent RFC](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0004-agents/README.md) From e568c9a92da390ec890c367a95576197991257e7 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Tue, 16 Apr 2024 08:59:49 -0700 Subject: [PATCH 14/35] Removed the implementation & code details from the CRUD operation section --- README.md | 213 ++---------------------------------------------------- 1 file changed, 7 insertions(+), 206 deletions(-) diff --git a/README.md b/README.md index f1cd58a..5e8edfd 100644 --- a/README.md +++ b/README.md @@ -96,9 +96,14 @@ The keywords MAY, MUST, MUST NOT, RECOMMENDED, SHOULD, and SHOULD NOT in this do ### Format -The ITN DID is derived as the sha3-256 hash of a random salt of sufficient entropy. +The ITN DID is derived as follow: -The format of ITN DID conform to the [W3C DID Core specification](https://www.w3.org/TR/did-core/). It consists of `did:itn` prefix followed by `sha3-256(random salt)`. The W3C DID Core specification does not specify how a DID is generated, and leaves it up to the implementation provided it ensures uniqueness to a high degree of confidence. +- A random 32 byte string is generated +- The seed is hashed using sha512 +- An Ed25519 key pair is generated from the hash. The key pair will be used as the recovery key pair +- The uuid of the did:itn is the base58 encoded value of public keys hexadecimal value + +The format of ITN DID conform to the [W3C DID Core specification](https://www.w3.org/TR/did-core/). The W3C DID Core specification does not specify how a DID is generated, and leaves it up to the implementation provided it ensures uniqueness to a high degree of confidence. **Note:** Format section ensures the ITN DID Format complies with [W3C DID Method Syntax](https://w3c.github.io/did-core/#method-syntax) @@ -106,48 +111,6 @@ The format of ITN DID conform to the [W3C DID Core specification](https://www.w3 Identity Protocol provides methods to manage DIDs. -#### Usage of Identity Protocols - -```typescript -import { IdentityProtocol, Agent } from "@itn-trust/agent" - -const identityProtocol = new IdentityProtocol({ - "create-did": async (message: CreateDIDMessage, next) => { - // handle CreateDIDMessage - }, - "create-did-response": async (message: CreateDIDResponseMessage, next) => { - // handle CreateDIDResponseMessage - }, - "update-did": async (message: UpdateDIDMessage, next) => { - // handle UpdateDIDMessage - }, - "update-did-response": async (message: UpdateDIDResponseMessage, next) => { - // handle UpdateDIDResponseMessage - }, - "revoke-did": async (message: RevokeDIDMessage, next) => { - // handle RevokeDIDMessage - }, - "revoke-did-response": async (message: RevokeDIDResponseMessage, next) => { - // handle RevokeDIDResponseMessage - }, - "recover-did": async (message: RecoverDIDMessage, next) => { - // handle RecoverDIDMessage - }, - "recover-did-response": async (message: RecoverDIDResponseMessage, next) => { - // handle RecoverDIDResponseMessage - }, -}) - -const agent = new Agent({ - // ... - protocols: [identityProtocol], -}) -``` - -**Refer** [ITN Identity Protocol](https://github.com/itn-trust/itn/tree/master/packages/sdk/agent/src/protocol/itn.mobi/identity/1.0) for technical details. `DELETE LATER BEFORE CREATING PR` - ---- - #### Create Description: Based on the DID data schema context file and DID method an ITN process anchors a DID and its DID document and delivers it to the requestor. @@ -161,30 +124,6 @@ Requirements: `Note: Question to Umed -- as per below comments - if its just DID string - how & when DID Document is created then??` - -##### `create()` API - -```ts -create({ - creator: DIDString | DIDDocument, - newDID?: { - didDoc: DIDDocument, - recoveryKey: Ed25519VerificationKey2020, - } -}): Promise -``` -* `creator` - creator of the new DID, can be a DID string or DID document. -* `newDID.didDoc` - (optional) a pre-created DID Document. -* `newDID.recoveryKey` - (optional) a pre-created DID Document's recovery key. - -Sends `CreateDIDMessage` to `creator` and receives `CreateDIDResponseMessage` message in `create-did-response` handler. - -**example:** - -```typescript -await agent.protocol(IdentityProtocol).create({ creator: "did:itn:TW7PbLSe2Ws8FCx675oFUU" }) -``` - --- #### Resolve @@ -258,109 +197,6 @@ Requirements: - The provided DID string MUST be compliant with the did:itn method. - The provided DID document MUST be compliant with the DID V1.0 DID document specification. - -##### `update()` API - -```ts -update({ - receiver: DIDString | DIDDocument, - oldDIDDoc: DIDDocument, - newDIDDoc: DIDDocument, -}):Promise -``` -* `receiver` - receiver of the update, can be a DID string or a DID document. -* `oldDIDDoc` - old DID Document to be updated -* `newDIDDoc` - new DID document containing the updates. - -Sends `UpdateDIDMessage` to `receiver` and receives `UpdateDIDResponseMessage` message in `update-did-response` handler. - -**example:** - -```typescript - -const oldDIDDoc = { - "@context": ["https://www.w3.org/ns/did/v1"], - id: "did:itn:8FcBrpSd5PTafaAzThsPbF", - assertionMethod: [ - "did:itn:8FcBrpSd5PTafaAzThsPbF#z6MkvXb9Cv5iaMEtn7PtJA5bg7Fnz3nT3AVU59ViAUJLtRrH", - ], - authentication: [ - "did:itn:8FcBrpSd5PTafaAzThsPbF#z6MkvXb9Cv5iaMEtn7PtJA5bg7Fnz3nT3AVU59ViAUJLtRrH", - ], - keyAgreement: [ - { - id: "did:itn:8FcBrpSd5PTafaAzThsPbF#z6LScBaA4yAZowVqszMCBd5zscDs6Vk4npARXGBw29ewngNX", - type: "X25519KeyAgreementKey2020", - controller: "did:itn:8FcBrpSd5PTafaAzThsPbF", - publicKeyMultibase: - "z6LScBaA4yAZowVqszMCBd5zscDs6Vk4npARXGBw29ewngNX", - }, - ], - verificationMethod: [ - { - id: "did:itn:8FcBrpSd5PTafaAzThsPbF#z6MkvXb9Cv5iaMEtn7PtJA5bg7Fnz3nT3AVU59ViAUJLtRrH", - type: "Ed25519VerificationKey2020", - controller: "did:itn:8FcBrpSd5PTafaAzThsPbF", - publicKeyMultibase: - "z6MkvXb9Cv5iaMEtn7PtJA5bg7Fnz3nT3AVU59ViAUJLtRrH", - }, - { - id: "did:itn:test#key-1", - type: "Ed25519VerificationKey2018", - controller: "did:itn:test", - publicKeyBase58: "FgF1dWCiADqWr97DUxsq6Zf1ZrzJ", - }, - ], - controller: "did:itn:Kmp7sVNtMrXZyiTKwgVWJK", -} - -const newDIDDoc = { - "@context": ["https://www.w3.org/ns/did/v1"], - id: "did:itn:8FcBrpSd5PTafaAzThsPbF", - assertionMethod: [ - "did:itn:8FcBrpSd5PTafaAzThsPbF#z6MkvXb9Cv5iaMEtn7PtJA5bg7Fnz3nT3AVU59ViAUJLtRrH", - ], - authentication: [ - "did:itn:8FcBrpSd5PTafaAzThsPbF#z6MkvXb9Cv5iaMEtn7PtJA5bg7Fnz3nT3AVU59ViAUJLtRrH", - ], - keyAgreement: [ - { - id: "did:itn:8FcBrpSd5PTafaAzThsPbF#z6LScBaA4yAZowVqszMCBd5zscDs6Vk4npARXGBw29ewngNX", - type: "X25519KeyAgreementKey2020", - controller: "did:itn:8FcBrpSd5PTafaAzThsPbF", - publicKeyMultibase: - "z6LScBaA4yAZowVqszMCBd5zscDs6Vk4npARXGBw29ewngNX", - }, - ], - verificationMethod: [ - { - id: "did:itn:8FcBrpSd5PTafaAzThsPbF#z6MkvXb9Cv5iaMEtn7PtJA5bg7Fnz3nT3AVU59ViAUJLtRrH", - type: "Ed25519VerificationKey2020", - controller: "did:itn:8FcBrpSd5PTafaAzThsPbF", - publicKeyMultibase: - "z6MkvXb9Cv5iaMEtn7PtJA5bg7Fnz3nT3AVU59ViAUJLtRrH", - }, - { - id: "did:itn:test#key-1", - type: "Ed25519VerificationKey2018", - controller: "did:itn:test", - publicKeyBase58: "FgF1dWCiADqWr97DUxsq6Zf1ZrzJ", - }, - ], - controller: "did:itn:Kmp7sVNtMrXZyiTKwgVWJK", - service: [ - { - id: "did:itn:info", - type: "Information", - serviceEndpoint: "https://example.com/info", - }, - ], - alsoKnownAs: ["https://itn.example/"], -} - -await agent.protocol(IdentityProtocol).update({ receiver: "did:itn:TW7PbLSe2Ws8FCx675oFUU", oldDIDDoc, newDIDDoc }) -``` - --- @@ -376,24 +212,6 @@ Requirements: - The provided DID string MUST be compliant with the did:itn method. - The provided DID document MUST be compliant with the DID V1.0 DID document specification. -##### `revoke()` API - -```ts -revoke({ did: DIDString, receiver: DIDString | DIDDocument }):Promise -``` -* `did` - DID to be revoked. -* `receiver` - receiver of the revocation, can be a DID string or a DID document. - -Sends `RevokeDIDMessage` to `receiver` and receive `RevokeDIDResponseMessage` in `revoke-did-response` handler. - -**example:** - -```typescript - -await agent - .protocol(IdentityProtocol) - .revoke({ did: "did:itn:8FcBrpSd5PTafaAzThsPbF", receiver: "did:itn:TW7PbLSe2Ws8FCx675oFUU" }) -``` --- @@ -410,23 +228,6 @@ Requirements: - The provided DID string MUST be compliant with the did:itn method. - The provided DID document MUST be compliant with the DID V1.0 DID document specification. -##### `recover()` API - -```ts -recover({ did: DIDString, receiver: DIDString | DIDDocument }): Promise -``` -* `did` - DID to be recovered. -* `receiver` - receiver of the recovery, can be a DID string or a DID document. - -Sends `RecoverDIDMessage` to `receiver` and receive `RecoverDIDResponseMessage` in `recover-did-response` handler. - -**example:** - -```typescript - -await agent.protocol(IdentityProtocol).recover({ did: "did:itn:8FcBrpSd5PTafaAzThsPbF", receiver: "did:itn:TW7PbLSe2Ws8FCx675oFUU" }) -``` - --- #### Deactivate From 6078fb27e7409eb24ff082200b493ccd22815e2b Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Tue, 16 Apr 2024 09:20:22 -0700 Subject: [PATCH 15/35] removed the DID Document Manager from the Appendix section. --- README.md | 382 ------------------------------------------------------ 1 file changed, 382 deletions(-) diff --git a/README.md b/README.md index 5e8edfd..ae42b6b 100644 --- a/README.md +++ b/README.md @@ -252,388 +252,6 @@ Text - TBD ## Appendix -### DID Document Manager - -Provides a set of functions to manage DID Documents. - -#### `getDIDDoc()` API - -```ts -getDIDDoc(did: DIDString): Promise -``` -* `did` - DID Document identifier - -Retrieves the DID document for the specified DID. - -**example:** - -```typescript -const didDoc = await agent.managers.didDoc.getDIDDoc("did:itn:RGNQknTkhX6eiFaw38DrLP") - -expect(didDoc).toBe({ - "@context": ["https://www.w3.org/ns/did/v1"], - id: "did:itn:RGNQknTkhX6eiFaw38DrLP", - assertionMethod: [ - "did:itn:RGNQknTkhX6eiFaw38DrLP#z6MkkFbwWFtiXE8ioC293Fzn2hXDR5jpMXDB9iWFwz5t8WF9", - ], - authentication: [ - "did:itn:RGNQknTkhX6eiFaw38DrLP#z6MkkFbwWFtiXE8ioC293Fzn2hXDR5jpMXDB9iWFwz5t8WF9", - ], - keyAgreement: [ - { - id: "did:itn:RGNQknTkhX6eiFaw38DrLP#z6LSf7iSoxWXoRBjEHR3ZSHePgooDjRVZhAih59QUaHchPNB", - type: "X25519KeyAgreementKey2020", - controller: "did:itn:RGNQknTkhX6eiFaw38DrLP", - publicKeyMultibase: "z6LSf7iSoxWXoRBjEHR3ZSHePgooDjRVZhAih59QUaHchPNB", - }, - ], - verificationMethod: [ - { - id: "did:itn:RGNQknTkhX6eiFaw38DrLP#z6MkkFbwWFtiXE8ioC293Fzn2hXDR5jpMXDB9iWFwz5t8WF9", - type: "Ed25519VerificationKey2020", - controller: "did:itn:RGNQknTkhX6eiFaw38DrLP", - publicKeyMultibase: "z6MkkFbwWFtiXE8ioC293Fzn2hXDR5jpMXDB9iWFwz5t8WF9", - }, - ], -}) -``` - -#### `saveDIDDoc()` API - -```ts -saveDIDDoc(args?: { - did?: DIDString - controller?: DIDDocument - operationId?: UUIDString - recoveryKey?: Ed25519VerificationKey2020 - didDocument?: Partial - metadata?: { - name?: string - description?: string - tags?: string[] - } -}): Promise<{ - recoveryKey: Ed25519VerificationKey2020 - didDoc: DIDDocument -}> -``` -* `args` - (optional) arguments for saving the DID document - -Saves the DID document along with the necessary keys and metadata into the wallet. -If `operationId` provided, saves as a wallet operation until `wallet.commitChanges()` or `wallet.rollbackChanges()` is called. - -**example:** - -```typescript -const { recoveryKey, didDoc } = await agent.managers.didDoc.createDID() - -expect(recoveryKey).toBe({ - "@context": ["https://w3id.org/security/suites/ed25519-2020/v1"], - id: "did:itn:RSF6nsbNFXW1Rpny3pKUuu#z6Mksmhto6EJEHQ97ewZMv6hAcSEvWTw3dBLfu2vDax94qxu", - type: "Ed25519VerificationKey2020", - controller: "did:itn:RSF6nsbNFXW1Rpny3pKUuu", - publicKeyMultibase: "z6Mksmhto6EJEHQ97ewZMv6hAcSEvWTw3dBLfu2vDax94qxu", - privateKeyMultibase: "z3u2i7PnbgcQvCxbBbmEYA4sfXmGhswEiYB5LHUAWsgFXaXW", - name: "Recovery Key", - description: "Used to recover identity.", - tags: [], -}) - - -expect(didDoc).toBe({ - "@context": ["https://www.w3.org/ns/did/v1"], - id: "did:itn:RSF6nsbNFXW1Rpny3pKUuu", - assertionMethod: [ - "did:itn:RSF6nsbNFXW1Rpny3pKUuu#z6MkuFe4dc9njM5uBNQL2rhubLx5jZRjLP8ftuXwz45Mvg5F", - ], - authentication: [ - "did:itn:RSF6nsbNFXW1Rpny3pKUuu#z6MkuFe4dc9njM5uBNQL2rhubLx5jZRjLP8ftuXwz45Mvg5F", - ], - keyAgreement: [ - { - id: "did:itn:RSF6nsbNFXW1Rpny3pKUuu#z6LSpUuyUHWwpjyK59xE9d5ZrtDqN6ya7RzBjyPxgsAT2VNL", - type: "X25519KeyAgreementKey2020", - controller: "did:itn:RSF6nsbNFXW1Rpny3pKUuu", - publicKeyMultibase: "z6LSpUuyUHWwpjyK59xE9d5ZrtDqN6ya7RzBjyPxgsAT2VNL", - }, - ], - verificationMethod: [ - { - id: "did:itn:RSF6nsbNFXW1Rpny3pKUuu#z6MkuFe4dc9njM5uBNQL2rhubLx5jZRjLP8ftuXwz45Mvg5F", - type: "Ed25519VerificationKey2020", - controller: "did:itn:RSF6nsbNFXW1Rpny3pKUuu", - publicKeyMultibase: "z6MkuFe4dc9njM5uBNQL2rhubLx5jZRjLP8ftuXwz45Mvg5F", - }, - ], -}) -``` - ---- - -#### `updateDIDDoc()` API - -```ts - updateDIDDoc( - oldDIDDoc: DIDDocument, - newDIDDoc: DIDDocument, - operationId?: UUIDString, - ): Promise -``` -* `oldDIDDoc` - old DID Document -* `newDIDDoc` - new DID Document -* `operationId` - (optional) if provided, saves DID Document update as a wallet operation until `wallet.commitChanges()` or `wallet.rollbackChanges()` is called. - -Updates the DID Document. - -**example:** - -```typescript -const oldDIDDoc = { - "@context": ["https://www.w3.org/ns/did/v1"], - id: "did:itn:X9ns1DteHSXCL8AjgCvDhF", - assertionMethod: [ - "did:itn:X9ns1DteHSXCL8AjgCvDhF#z6Mkn1HjxP4C9sq6P6ruemWe8eQZa3jPLAADLJUYJnZ9g5xj", - ], - authentication: [ - "did:itn:X9ns1DteHSXCL8AjgCvDhF#z6Mkn1HjxP4C9sq6P6ruemWe8eQZa3jPLAADLJUYJnZ9g5xj", - ], - keyAgreement: [ - { - id: "did:itn:X9ns1DteHSXCL8AjgCvDhF#z6LSenEkHyRX5sqDX7KsPFta9daxNNWNuNV9nZPHFLiF6343", - type: "X25519KeyAgreementKey2020", - controller: "did:itn:X9ns1DteHSXCL8AjgCvDhF", - publicKeyMultibase: "z6LSenEkHyRX5sqDX7KsPFta9daxNNWNuNV9nZPHFLiF6343", - }, - ], - verificationMethod: [ - { - id: "did:itn:X9ns1DteHSXCL8AjgCvDhF#z6Mkn1HjxP4C9sq6P6ruemWe8eQZa3jPLAADLJUYJnZ9g5xj", - type: "Ed25519VerificationKey2020", - controller: "did:itn:X9ns1DteHSXCL8AjgCvDhF", - publicKeyMultibase: "z6Mkn1HjxP4C9sq6P6ruemWe8eQZa3jPLAADLJUYJnZ9g5xj", - }, - ], -} - -const newDIDDoc = { - ...didDoc, - service: [ - { - id: "did:itn:info", - type: "Information", - serviceEndpoint: "https://example.com/info", - }, - ], -} - -await agent.managers.didDoc.updateDIDDoc(oldDIDDoc, newDIDDoc) -``` - ---- - -#### `revokeDID()` API - -```ts -revokeDID(did: DIDString, operationId?: UUIDString): Promise -``` -* `did` - DID to be revoked -* `operationId` - (optional) if provided, saves DID Document revoke as a wallet operation until "wallet.commitChanges()" or "wallet.rollbackChanges()" is called. - -Revoke a DID by updating its associated DID Document. - -**example:** - -```typescript -await agent.managers.didDoc.revokeDID("did:itn:4wqjsfTA8jghZK9Xw6TQDL") -``` - ---- - -#### `recoverDID()` API - -```ts -recoverDID(did: DIDString, operationId?: UUIDString): Promise<{ - recoveryKey: Ed25519VerificationKey2020 - didDocContent: DIDDocContent -}> -``` -* `did` - DID to be recovered -* `operationId` - (optional) if provided, saves DID Document revoke as a wallet operation until "wallet.commitChanges()" or "wallet.rollbackChanges()" is called. - -Recovers a DID by creating a new DID document, signing and encryption keys, and updating the existing DID document content -in the wallet. - - -**example:** - -```typescript -const { - recoveryKey, - didDocContent, -} = await wallet.didDocManager.recoverDID( - "did:itn:Aw8tt7G1AhSCHfBrsuzrJG") - -// new recovery key -expect(recoveryKey).toBe( - { - "@context": ["https://w3id.org/security/suites/ed25519-2020/v1"], - id: "did:itn:Aw8tt7G1AhSCHfBrsuzrJG#z6MkjsGqthRZLsYW3EaYW63iRbXFeGJftFmsA3Z1uJziSPq7", - type: "Ed25519VerificationKey2020", - controller: "did:itn:Aw8tt7G1AhSCHfBrsuzrJG", - publicKeyMultibase: "z6MkjsGqthRZLsYW3EaYW63iRbXFeGJftFmsA3Z1uJziSPq7", - privateKeyMultibase: "z3u2W6p14p2mTmCCozMZqqdiSjYYtfFXfDjcutQDRTyDQjY7", - name: "Recovery Key", - description: "Used to recover identity.", - tags: [], - }, -) - -// new did document content -expect(didDocContent).toBe( - { - id: "63caefb9-1af2-48e9-9f22-9cf04ed7558e", - type: "DIDDocument", - body: { - tags: [], - didDocument: { - "@context": [ - "https://www.w3.org/ns/did/v1", - ], - id: "did:itn:Aw8tt7G1AhSCHfBrsuzrJG", - assertionMethod: [ - "did:itn:Aw8tt7G1AhSCHfBrsuzrJG#z6Mkuz76zmSj8Fb6PeE4AThcVTUeVADfBw4xQcGf6tYPx2SK", - ], - authentication: [ - "did:itn:Aw8tt7G1AhSCHfBrsuzrJG#z6Mkuz76zmSj8Fb6PeE4AThcVTUeVADfBw4xQcGf6tYPx2SK", - ], - keyAgreement: [ - { - id: "did:itn:Aw8tt7G1AhSCHfBrsuzrJG#z6LSquqPkSUf9YHjoNYmuD6Jn5HxZihvXnXi9YrcJm42rMGT", - type: "X25519KeyAgreementKey2020", - controller: "did:itn:Aw8tt7G1AhSCHfBrsuzrJG", - publicKeyMultibase: "z6LSquqPkSUf9YHjoNYmuD6Jn5HxZihvXnXi9YrcJm42rMGT", - }, - ], - verificationMethod: [ - { - id: "did:itn:Aw8tt7G1AhSCHfBrsuzrJG#z6Mkuz76zmSj8Fb6PeE4AThcVTUeVADfBw4xQcGf6tYPx2SK", - type: "Ed25519VerificationKey2020", - controller: "did:itn:Aw8tt7G1AhSCHfBrsuzrJG", - publicKeyMultibase: "z6Mkuz76zmSj8Fb6PeE4AThcVTUeVADfBw4xQcGf6tYPx2SK", - }, - ], - controller: "did:itn:RGNQknTkhX6eiFaw38DrLP", - }, - }, - created: 1699006922350, - updated: 1699006922350, - }, -) -``` - ---- - -#### `getDIDResolutionResultContent()` API - -```ts -getDIDResolutionResultContent(did: DIDString): Promise -``` -* `did` - DID Document to retrieve the resolution result - -Retrieves the content of a DID resolution result based on the provided DID. - -**example:** - -```typescript -const didResolutionContent = await agent.managers.didDoc.getDIDResolutionResultContent("did:itn:BRZ2CKoq2kV1WiuMYZcBwu") - -expect(didResolutionContent).toBe({ - id: "f0967614-8bc2-4f7d-9dba-76ba18205113", - type: "DIDResolutionResult", - body: { - "@context": ["https://w3id.org/did-resolution/v1"], - tags: [], - created: "2023-11-03T10:42:27.093Z", - expires: "2023-11-04T10:42:27.093Z", - didDocument: { - "@context": ["https://www.w3.org/ns/did/v1"], - id: "did:itn:B8G98VLFmv1o1h3CVF8fLQ", - assertionMethod: ["did:itn:BRZ2CKoq2kV1WiuMYZcBwu#z6MkgG2CF1h4gcjpxX5wW1z55NzJ6DQMmJnVNcagb4kCggMM"], - authentication: ["did:itn:BRZ2CKoq2kV1WiuMYZcBwu#z6MkgG2CF1h4gcjpxX5wW1z55NzJ6DQMmJnVNcagb4kCggMM"], - keyAgreement: [{ - id: "did:itn:BRZ2CKoq2kV1WiuMYZcBwu#z6LSrGYukPKRADR2GZk25uAYwpZdF2qF75Xgm6dQS3gdEB1F", - type: "X25519KeyAgreementKey2020", - controller: "did:itn:BRZ2CKoq2kV1WiuMYZcBwu", - publicKeyMultibase: "z6LSrGYukPKRADR2GZk25uAYwpZdF2qF75Xgm6dQS3gdEB1F", - }], - verificationMethod: [{ - id: "did:itn:BRZ2CKoq2kV1WiuMYZcBwu#z6MkgG2CF1h4gcjpxX5wW1z55NzJ6DQMmJnVNcagb4kCggMM", - type: "Ed25519VerificationKey2020", - controller: "did:itn:BRZ2CKoq2kV1WiuMYZcBwu", - publicKeyMultibase: "z6MkgG2CF1h4gcjpxX5wW1z55NzJ6DQMmJnVNcagb4kCggMM", - }], - }, - didResolutionMetadata: {}, - didDocumentMetadata: { - created: "2023-11-03T10:42:27.093Z", - }, - }, - created: 1699008147093, - updated: 1699008147093, -}) -``` - ---- - -#### `saveDIDResolutionResult()` API - -```ts -saveDIDResolutionResult(result: DIDResolutionResult): Promise -``` - -* `result` - DID resolution result to be saved - -Saves the DID resolution result to the wallet. - -**example:** - -```typescript - const didResolutionResult = { - didDocument: { - "@context": ["https://www.w3.org/ns/did/v1"], - id: "did:itn:RSF6nsbNFXW1Rpny3pKUuu", - assertionMethod: [ - "did:itn:RSF6nsbNFXW1Rpny3pKUuu#z6MkuFe4dc9njM5uBNQL2rhubLx5jZRjLP8ftuXwz45Mvg5F", - ], - authentication: [ - "did:itn:RSF6nsbNFXW1Rpny3pKUuu#z6MkuFe4dc9njM5uBNQL2rhubLx5jZRjLP8ftuXwz45Mvg5F", - ], - keyAgreement: [ - { - id: "did:itn:RSF6nsbNFXW1Rpny3pKUuu#z6LSpUuyUHWwpjyK59xE9d5ZrtDqN6ya7RzBjyPxgsAT2VNL", - type: "X25519KeyAgreementKey2020", - controller: "did:itn:RSF6nsbNFXW1Rpny3pKUuu", - publicKeyMultibase: "z6LSpUuyUHWwpjyK59xE9d5ZrtDqN6ya7RzBjyPxgsAT2VNL", - }, - ], - verificationMethod: [ - { - id: "did:itn:RSF6nsbNFXW1Rpny3pKUuu#z6MkuFe4dc9njM5uBNQL2rhubLx5jZRjLP8ftuXwz45Mvg5F", - type: "Ed25519VerificationKey2020", - controller: "did:itn:RSF6nsbNFXW1Rpny3pKUuu", - publicKeyMultibase: "z6MkuFe4dc9njM5uBNQL2rhubLx5jZRjLP8ftuXwz45Mvg5F", - }, - ], - }, - contentType: undefined, - created: new Date().toISOString(), -} - -await agent.managers.didDoc.saveDIDResolutionResult(didResolutionResult) -``` - ---- - ITN SDK has crypto-ld-suite package that provides a set of functions to generate crypto keys for use with [@digitalbazaar/crypto-ld](https://github.com/digitalbazaar/crypto-ld) library, a set of functions to create and verify signatures for use with [@digitalbazaar/jsonld-signatures](https://github.com/digitalbazaar/jsonld-signatures) library and a set of utility functions for use with crypto keys. Cryptographic Key Types supported From e857ac5a45bb7a27e55872a57e83e3f72e5d9453 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Tue, 16 Apr 2024 10:14:09 -0700 Subject: [PATCH 16/35] added the privacy content --- README.md | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ae42b6b..df3f19b 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,12 @@ The keywords MAY, MUST, MUST NOT, RECOMMENDED, SHOULD, and SHOULD NOT in this do ## Terminology 1. ITN - Integrated Trust Network -2. EDV - Encrypted Data Vault +2. EDV - Encrypted Data Vault +3. CAS - Content Addressable Storage +4. DLT - Distributed Ledger Network +5. DID - Decentralized Identifier +6. VC - Verifiable Credentials +7. VP - Verifiable Presentations ## DID ITN Method Specification @@ -237,7 +242,6 @@ The `revoke` operation also deactivate the DID. **Note:** Operations section ensures the ITN DID Method Operations complies with [W3C DID Method Operations](https://w3c.github.io/did-core/#method-operations) - ## Security Considerations For all `did:itn` DIDs, the initial asset creation, and subsequent updates are executed using `Ed25519` keys, which are widely recognized as a robust and secure cryptographic mechanism. `Confirm With Umed & Andreas - if the keys are different. DELETE THIS COMMENT LATER.` @@ -246,7 +250,27 @@ For all `did:itn` DIDs, the initial asset creation, and subsequent updates are e ## Privacy Considerations -Text - TBD +The ITN can be classified as a data processor because +1. in its business model, the ITN only deals with enterprises and not individuals, and, +2. because the ITN does not determine the purpose and the means of data processing + +While it is true that the ITN determines the means of data processing, because of its federated nature, only the data controller can authorize data processing, in other words, determine its purpose. + +### What Data is ITN storing and what does that mean with regard to data privacy? + +ITN is only storing the following data: +- Public Keys in DID documents stored in our CAS, and in Smart Contracts stored on our DLTs +- Hashed data in Smart Contracts on our DLTs representing DID documents, in our CAS for our VC revocation lists, and aggregate application state data +- Service endpoints in DID documents on our CAS + +In the ITN context, only Public Keys and Service Endpoints may refer to an individual. ITN ensures proper management in the following way: +1. DID documents may be deleted by their controllers, and, therefore, access to DID documents from the outside by a 3rd party is no longer possible. +2. While public keys and hashes of DID documents remain on the DLTs of the ITN, ITN will not maintain logs of IP addresses that requested ITN service operations, and, therefore, makes the correlation of a public key with personal data (the IP assigned to an individual’s router at a specific physical address by the ISP) from the point of view of the ITN, or an entity breaching the ITN, not possible. However, if a public key is used outside of the context of ITN more than once, then it may be subject to linkability to other personal data. + +The reason why within ITN hashed data may be considered sufficiently anonymized is as follows: While hashed data may contain personal data through public keys or service endpoints in the DID documents, it is combined with randomized, non-personal data such as a DID itself, per EC guideline. + +Note that the permissioned DLTs of the ITN are not directly accessible from the outside by 3rd parties. + **Note:** Privacy Considerations section ensures the ITN DID Method Privacy considerations complies with [W3C DID Method Privacy Requirements](https://w3c.github.io/did-core/#privacy-requirements) From 50c886983b562ec6e5582896a480b29cc935d0ff Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Tue, 16 Apr 2024 11:30:07 -0700 Subject: [PATCH 17/35] Removed the constraint line from the CRUD operation section. Sample DID Document section. Removed first paragraph content from the privacy section. --- README.md | 113 +++++++++++++++++++++--------------------------------- 1 file changed, 44 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index df3f19b..777c3c9 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ The DID ITN Method Specification 1.0 **Draft Created:** April 10, 2024 -**Latest Update:** April 15, 2024 +**Latest Update:** April 16, 2024 **Contributors & Editors:** @@ -119,7 +119,6 @@ Identity Protocol provides methods to manage DIDs. #### Create Description: Based on the DID data schema context file and DID method an ITN process anchors a DID and its DID document and delivers it to the requestor. -Constraints: Can only be invoked by the DID controller(s). Requirements: @@ -127,74 +126,22 @@ Requirements: - The provided DID MUST be compliant with the did:itn method. - The provided DID document MUST be compliant with the DID V1.0 DID document specification. -`Note: Question to Umed -- as per below comments - if its just DID string - how & when DID Document is created then??` - --- #### Resolve Description: Based on the DID data schema context file and DID method an ITN process delivers a DID document in accordance with the W3C DID standard. -Constraints: Any entity should be able to invoke the process. Requirements: - A DID string MUST be provided as an input parameter. - The provided DID MUST be compliant with the did:itn method. -**example:** - -```typescript -await agent.resolveDIDDoc("did:itn:NL28Bubaa8xUmhJAARNkNS") -``` - -Response to above code will be a DID Document as below: - -```json -{ - "didDocument": { - "@context": [ - "https://www.w3.org/ns/did/v1" - ], - "assertionMethod": [ - "did:itn:NL28Bubaa8xUmhJAARNkNS#z6MkiYmb7ncfDAAhcxtAAGsm1oySq4KYJtsi2wHaoKAnmVXC" - ], - "authentication": [ - "did:itn:NL28Bubaa8xUmhJAARNkNS#z6MkiYmb7ncfDAAhcxtAAGsm1oySq4KYJtsi2wHaoKAnmVXC" - ], - "id": "did:itn:NL28Bubaa8xUmhJAARNkNS", - "keyAgreement": [ - { - "id": "did:itn:NL28Bubaa8xUmhJAARNkNS#z6LSd76Tk2UJ3RVxcTjYjZ8TfvHMQgZG5HmbKPmCidPXyTGZ", - "type": "X25519KeyAgreementKey2020", - "controller": "did:itn:NL28Bubaa8xUmhJAARNkNS", - "publicKeyMultibase": "z6LSd76Tk2UJ3RVxcTjYjZ8TfvHMQgZG5HmbKPmCidPXyTGZ" - } - ], - "verificationMethod": [ - { - "id": "did:itn:NL28Bubaa8xUmhJAARNkNS#z6MkiYmb7ncfDAAhcxtAAGsm1oySq4KYJtsi2wHaoKAnmVXC", - "type": "Ed25519VerificationKey2020", - "controller": "did:itn:NL28Bubaa8xUmhJAARNkNS", - "publicKeyMultibase": "z6MkiYmb7ncfDAAhcxtAAGsm1oySq4KYJtsi2wHaoKAnmVXC" - } - ] - }, - "didDocumentMetadata": { - "created": "2023-11-10T15:20:59Z", - "updated": "2023-11-10T15:20:59Z", - "deactivated": false, - "recoveryCommitment": "99cdefca761b58664641d3f0b89b4f1e04ad833b7a24a726e3424bc6c17f39a0" - }, - "didResolutionMetadata": { } -} -``` - --- #### Update Description: Based on the DID data schema context file and DID method an ITN process creates an updated DID document in accordance with the W3C DID standard. -Constraints: Can only be called by the DID controller(s). Requirements: @@ -208,7 +155,6 @@ Requirements: #### Revoke Description: Based on the DID data schema context file and DID method an ITN process revokes an existing DID and its DID document in accordance with the W3C DID standard. -Constraints: Can only be invoked by the DID controller(s). Requirements: @@ -224,7 +170,6 @@ Requirements: #### Recover Description: Based on the DID data schema context file and DID method, an ITN process recovers a DID and its DID document in accordance with the W3C DID standard. -Constraints: Can only be invoked by the DID controller(s). Requirements: @@ -239,7 +184,48 @@ Requirements: The `revoke` operation also deactivate the DID. -**Note:** Operations section ensures the ITN DID Method Operations complies with [W3C DID Method Operations](https://w3c.github.io/did-core/#method-operations) + +## Sample DID Document + +```json +{ + "didDocument": { + "@context": [ + "https://www.w3.org/ns/did/v1" + ], + "assertionMethod": [ + "did:itn:NL28Bubaa8xUmhJAARNkNS#z6MkiYmb7ncfDAAhcxtAAGsm1oySq4KYJtsi2wHaoKAnmVXC" + ], + "authentication": [ + "did:itn:NL28Bubaa8xUmhJAARNkNS#z6MkiYmb7ncfDAAhcxtAAGsm1oySq4KYJtsi2wHaoKAnmVXC" + ], + "id": "did:itn:NL28Bubaa8xUmhJAARNkNS", + "keyAgreement": [ + { + "id": "did:itn:NL28Bubaa8xUmhJAARNkNS#z6LSd76Tk2UJ3RVxcTjYjZ8TfvHMQgZG5HmbKPmCidPXyTGZ", + "type": "X25519KeyAgreementKey2020", + "controller": "did:itn:NL28Bubaa8xUmhJAARNkNS", + "publicKeyMultibase": "z6LSd76Tk2UJ3RVxcTjYjZ8TfvHMQgZG5HmbKPmCidPXyTGZ" + } + ], + "verificationMethod": [ + { + "id": "did:itn:NL28Bubaa8xUmhJAARNkNS#z6MkiYmb7ncfDAAhcxtAAGsm1oySq4KYJtsi2wHaoKAnmVXC", + "type": "Ed25519VerificationKey2020", + "controller": "did:itn:NL28Bubaa8xUmhJAARNkNS", + "publicKeyMultibase": "z6MkiYmb7ncfDAAhcxtAAGsm1oySq4KYJtsi2wHaoKAnmVXC" + } + ] + }, + "didDocumentMetadata": { + "created": "2023-11-10T15:20:59Z", + "updated": "2023-11-10T15:20:59Z", + "deactivated": false, + "recoveryCommitment": "99cdefca761b58664641d3f0b89b4f1e04ad833b7a24a726e3424bc6c17f39a0" + }, + "didResolutionMetadata": { } +} +``` ## Security Considerations @@ -250,14 +236,6 @@ For all `did:itn` DIDs, the initial asset creation, and subsequent updates are e ## Privacy Considerations -The ITN can be classified as a data processor because -1. in its business model, the ITN only deals with enterprises and not individuals, and, -2. because the ITN does not determine the purpose and the means of data processing - -While it is true that the ITN determines the means of data processing, because of its federated nature, only the data controller can authorize data processing, in other words, determine its purpose. - -### What Data is ITN storing and what does that mean with regard to data privacy? - ITN is only storing the following data: - Public Keys in DID documents stored in our CAS, and in Smart Contracts stored on our DLTs - Hashed data in Smart Contracts on our DLTs representing DID documents, in our CAS for our VC revocation lists, and aggregate application state data @@ -267,10 +245,7 @@ In the ITN context, only Public Keys and Service Endpoints may refer to an indiv 1. DID documents may be deleted by their controllers, and, therefore, access to DID documents from the outside by a 3rd party is no longer possible. 2. While public keys and hashes of DID documents remain on the DLTs of the ITN, ITN will not maintain logs of IP addresses that requested ITN service operations, and, therefore, makes the correlation of a public key with personal data (the IP assigned to an individual’s router at a specific physical address by the ISP) from the point of view of the ITN, or an entity breaching the ITN, not possible. However, if a public key is used outside of the context of ITN more than once, then it may be subject to linkability to other personal data. -The reason why within ITN hashed data may be considered sufficiently anonymized is as follows: While hashed data may contain personal data through public keys or service endpoints in the DID documents, it is combined with randomized, non-personal data such as a DID itself, per EC guideline. - -Note that the permissioned DLTs of the ITN are not directly accessible from the outside by 3rd parties. - +The reason why within ITN hashed data may be considered sufficiently anonymized is as follows: While hashed data may contain personal data through public keys or service endpoints in the DID documents, it is combined with randomized, non-personal data such as a DID itself, per European Commission (EC) guideline. **Note:** Privacy Considerations section ensures the ITN DID Method Privacy considerations complies with [W3C DID Method Privacy Requirements](https://w3c.github.io/did-core/#privacy-requirements) From f07ab9cbe5639c2ae82df971789580ac34adcc2d Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Tue, 16 Apr 2024 13:18:38 -0700 Subject: [PATCH 18/35] minor corrections - removed comments and extra spaces. --- README.md | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 777c3c9..e7d7eaf 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,6 @@ The DID ITN Method Specification 1.0 3. [Parth Bhatt](https://github.com/bparth24) 4. [Umed Khudoiberdiev](https://github.com/pleerock) - ## Abstract Integrated Trust Network (ITN) is a community-built and operated network. The objective is to build a Federated Trust Layer (Core Services) and Business Automation Interoperability Infrastructure (User Agents) for ITN. The ITN Identifier is specified in accordance with the [W3C DID Core specification](https://www.w3.org/TR/did-core/). @@ -32,6 +31,7 @@ For a detailed read on DID and other DID method specifications, one can refer [W The ITN is a permissioned network of nodes operated by ITN Node Operators. Each ITN Node is comprised of the following elements depicted in the figure below: + - ITN Agent for Core Services ~ (former name used - Self Sovereign Digital Twin (SSDT) of the Core Services OR Core Services SSDT) - DLT Gateway: A NodeJS application integrating with the Core Services SSDT, Apache Kafka, and the different DLT networks of the ITN. In the next phase of implementation, the Apache Kafka instances will be connected via message replication to obtain a holistic picture of messages across the network. - DID Resolver: The DID resolver utilizes the Decentralized Identity Foundation DID resolver and is integrated with the Core Services SSDT. @@ -42,7 +42,6 @@ All applications external to the ITN and wishing to utilize the ITN Core Service ![ITN Architecture Overview](./docs/images/ITN%20Architecture%20Overview.jpg) - The ITN Agent utilized in each ITN node is implemented in NodeJS and is comprised of the following elements: - API Endpoint Service for both REST APIs and [Decentralized Identity Foundation (DIF) DIDcomm](https://identity.foundation/didcomm-messaging/spec/) messaging protocol for integration with ITN Core Services, other Agents, and Legacy Applications via REST APIs @@ -57,17 +56,16 @@ Integration of an ITN Agent in any application is achieved through the ITN SDK. ![ITN Agent](./docs/images/ITN%20Agent.jpg) - ITN Agent is an implementation of the [Aries Agent RFC](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0004-agents/README.md) with a flexible plugin architecture. Depending on which plugins and [DIDComm protocols](https://didcomm.org/search/?page=1) you use, your instance of ITN Agent can perform a variety of roles: -* Create and manage cryptographic keys -* Create and manage Decentralized Identifiers -* Issue and verify Verifiable Credentials (VCs) and Presentations (VPs) -* Communicate with other Agents over [DIDComm](https://identity.foundation/didcomm-messaging/spec/#discover-features-protocol-20) +- Create and manage cryptographic keys +- Create and manage Decentralized Identifiers +- Issue and verify Verifiable Credentials (VCs) and Presentations (VPs) +- Communicate with other Agents over [DIDComm](https://identity.foundation/didcomm-messaging/spec/#discover-features-protocol-20) Agent provides a common interface for plugins to expand its functionality. It is designed to be modular and extensible, so you can add new protocols, transports, and managers to fit your needs. @@ -81,8 +79,6 @@ The agent was written in [TypeScript](https://www.typescriptlang.org/) and runs The ITN SDK has an Identity Protocol provides methods to manage DIDs. The ITN SDK has a DID Document Manager provide a set of functions to manage DID Documents. -`Conirm with Umed & Andreas - here I am only providing necessary information related to DIDs & DID Document. Is that okay?` - ## Conformance The keywords MAY, MUST, MUST NOT, RECOMMENDED, SHOULD, and SHOULD NOT in this document are to be interpreted... TBD `Not sure if required` @@ -151,7 +147,6 @@ Requirements: --- - #### Revoke Description: Based on the DID data schema context file and DID method an ITN process revokes an existing DID and its DID document in accordance with the W3C DID standard. @@ -163,10 +158,8 @@ Requirements: - The provided DID string MUST be compliant with the did:itn method. - The provided DID document MUST be compliant with the DID V1.0 DID document specification. - --- - #### Recover Description: Based on the DID data schema context file and DID method, an ITN process recovers a DID and its DID document in accordance with the W3C DID standard. @@ -184,7 +177,6 @@ Requirements: The `revoke` operation also deactivate the DID. - ## Sample DID Document ```json @@ -227,7 +219,6 @@ The `revoke` operation also deactivate the DID. } ``` - ## Security Considerations For all `did:itn` DIDs, the initial asset creation, and subsequent updates are executed using `Ed25519` keys, which are widely recognized as a robust and secure cryptographic mechanism. `Confirm With Umed & Andreas - if the keys are different. DELETE THIS COMMENT LATER.` @@ -237,13 +228,15 @@ For all `did:itn` DIDs, the initial asset creation, and subsequent updates are e ## Privacy Considerations ITN is only storing the following data: + - Public Keys in DID documents stored in our CAS, and in Smart Contracts stored on our DLTs - Hashed data in Smart Contracts on our DLTs representing DID documents, in our CAS for our VC revocation lists, and aggregate application state data - Service endpoints in DID documents on our CAS In the ITN context, only Public Keys and Service Endpoints may refer to an individual. ITN ensures proper management in the following way: + 1. DID documents may be deleted by their controllers, and, therefore, access to DID documents from the outside by a 3rd party is no longer possible. -2. While public keys and hashes of DID documents remain on the DLTs of the ITN, ITN will not maintain logs of IP addresses that requested ITN service operations, and, therefore, makes the correlation of a public key with personal data (the IP assigned to an individual’s router at a specific physical address by the ISP) from the point of view of the ITN, or an entity breaching the ITN, not possible. However, if a public key is used outside of the context of ITN more than once, then it may be subject to linkability to other personal data. +2. While public keys and hashes of DID documents remain on the DLTs of the ITN, ITN will not maintain logs of IP addresses that requested ITN service operations, and, therefore, makes the correlation of a public key with personal data (the IP assigned to an individual’s router at a specific physical address by the ISP) from the point of view of the ITN, or an entity breaching the ITN, not possible. However, if a public key is used outside of the context of ITN more than once, then it may be subject to linkability to other personal data. The reason why within ITN hashed data may be considered sufficiently anonymized is as follows: While hashed data may contain personal data through public keys or service endpoints in the DID documents, it is combined with randomized, non-personal data such as a DID itself, per European Commission (EC) guideline. @@ -279,16 +272,13 @@ Supported curves are: Bls12381G2 secp256k1 -Refer: [crypto-ld-suite](https://github.com/itn-trust/itn/tree/master/packages/sdk/crypto-ld-suite) `Not sure where to add and how to explain. Need some guidance.` -____________ - ## Message Encryptor Provides a set of functions to encrypt and decrypt DIDComm messages. Message Encryptor supports two forms of message encryption: Authenticated Sender Encryption (`authcrypt`) and Anonymous Sender Encryption (`anoncrypt`). Both forms are encrypted to the recipient DID. Only `authcrypt` provides direct assurances of who the sender is. -#### Message Encryptor supports the following curves for the keys involved in key agreement: +#### Message Encryptor supports the following curves for the keys involved in key agreement | Curve | Description | |--------|---------------------------------------------------------------------------------------------------------------------------------------| @@ -297,8 +287,7 @@ Both forms are encrypted to the recipient DID. Only `authcrypt` provides direct | P-384 | NIST defined P-384 elliptic curve. | | P-521 | NIST defined P-521 elliptic curve. | -## -#### The following `AEAD` algorithms are supported for content encryption of the message: +#### The following `AEAD` algorithms are supported for content encryption of the message | Algorithm | Description | |---------------|---------------------------------------------| @@ -306,8 +295,8 @@ Both forms are encrypted to the recipient DID. Only `authcrypt` provides direct | A256GCM | AES256-GCM with a 256 bit key | | XC20P | XChaCha20Poly1305 with a 256 bit key | -## -#### The following Key Wrapping Algorithms are supported to wrap shared secret key: +#### The following Key Wrapping Algorithms are supported to wrap shared secret key + | Algorithm | Curve (epk crv) | key type (epk kty) | |-----------------|------------------|--------------------| | ECDH-ES+A256KW | P-256 | EC | @@ -319,8 +308,6 @@ Both forms are encrypted to the recipient DID. Only `authcrypt` provides direct | ECDH-1PU+A256KW | P-521 | EC | | ECDH-1PU+A256KW | X25519 | OKP | -Refer: [Agent Services](https://github.com/itn-trust/itn/blob/master/packages/sdk/agent/src/service/README.md#agent-services) `Not sure where to add and how to explain. Need some guidance.` - ## References -[1] W3C Decentralized Identifiers (DIDs) v1.0, https://w3c.github.io/did-core/ +[1] W3C Decentralized Identifiers (DIDs) v1.0, From a8fdcbf34b2a79fd3dba8a18da23a34af1b8570e Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Tue, 16 Apr 2024 14:37:22 -0700 Subject: [PATCH 19/35] Incorporated suggested changes, added content in the security consideration section. --- README.md | 51 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e7d7eaf..85afd0c 100644 --- a/README.md +++ b/README.md @@ -38,11 +38,11 @@ Each ITN Node is comprised of the following elements depicted in the figure belo - Content Addressable Storage Network: Currently utilizing an append-only implementation of a Postgres DB with content-addressable hashes and replication between ITN Nodes. There is an implementation of peer-to-peer replication using the IPFS Cluster. - DLT Networks: It is comprised of a Hyperledger Fabric network and Arbitrum One EVM equivalent network (with more to follow, in particular, based on Integrated Trust Network (ITN) expansion). -All applications external to the ITN and wishing to utilize the ITN Core Services must implement an ITN Agent as their abstraction layer through the ITN SDK in the [ITN GitHub repository](https://github.com/itn-trust/itn). An ITN Agent represents a user’s capabilities on ITN and serves as an abstraction and integration layer between ITN and other applications/networks. +All applications external to the ITN and wishing to utilize the ITN Core Services must implement an ITN Agent as their abstraction layer. An ITN Agent represents a user’s capabilities on ITN and serves as an abstraction and integration layer between ITN and other applications/networks. ![ITN Architecture Overview](./docs/images/ITN%20Architecture%20Overview.jpg) -The ITN Agent utilized in each ITN node is implemented in NodeJS and is comprised of the following elements: +The ITN Agent utilized in each ITN node is comprised of the following elements: - API Endpoint Service for both REST APIs and [Decentralized Identity Foundation (DIF) DIDcomm](https://identity.foundation/didcomm-messaging/spec/) messaging protocol for integration with ITN Core Services, other Agents, and Legacy Applications via REST APIs - Authentication service utilizing [OAuth2 for REST APIs](https://oauth.net/2/) and [DIF DID AuthN](https://identity.foundation/working-groups/authentication.html) for DIF DIDcomm messaging @@ -50,9 +50,9 @@ The ITN Agent utilized in each ITN node is implemented in NodeJS and is comprise - An implementation of the W3C Verifiable Credential Issuance and Verification standard both as REST APIs and as DIDcomm endpoints - Implementation of ITN Data Sharing APIs both as REST APIs and as DIDcomm endpoints - An implementation of ITN Core Services functionality via DIF DIDcomm -- An implementation of the [W3C/DIF Encrypted Data Vault](https://identity.foundation/confidential-storage/) for document storage currently utilizing CouchDB with Leader-Leader replication +- An implementation of the [W3C/DIF Encrypted Data Vault](https://identity.foundation/confidential-storage/) for document storage -Integration of an ITN Agent in any application is achieved through the ITN SDK. +ITN Agent Integration can be achieved through an SDK, as utilized by the ITN. ![ITN Agent](./docs/images/ITN%20Agent.jpg) @@ -70,8 +70,6 @@ perform a variety of roles: Agent provides a common interface for plugins to expand its functionality. It is designed to be modular and extensible, so you can add new protocols, transports, and managers to fit your needs. -The agent was written in [TypeScript](https://www.typescriptlang.org/) and runs natively in Node.js, Browsers, and React Native. - ## ITN SDK ![ITN_SDK](https://github.com/itn-trust/itn-did-spec/assets/18353464/6135b073-c085-41fd-8ea4-f80e64e0485d) @@ -81,7 +79,7 @@ The ITN SDK has a DID Document Manager provide a set of functions to manage DID ## Conformance -The keywords MAY, MUST, MUST NOT, RECOMMENDED, SHOULD, and SHOULD NOT in this document are to be interpreted... TBD `Not sure if required` +The keywords MAY, MUST, MUST NOT, RECOMMENDED, SHOULD, and SHOULD NOT in this document are to be interpreted according to [RFC2119](https://datatracker.ietf.org/doc/html/rfc2119)` ## Terminology @@ -223,6 +221,45 @@ The `revoke` operation also deactivate the DID. For all `did:itn` DIDs, the initial asset creation, and subsequent updates are executed using `Ed25519` keys, which are widely recognized as a robust and secure cryptographic mechanism. `Confirm With Umed & Andreas - if the keys are different. DELETE THIS COMMENT LATER.` +- Authentication service utilizing [OAuth2](https://oauth.net/2/) for REST APIs and [DIF DID AuthN](https://identity.foundation/working-groups/authentication.html) for DIF DIDcomm messaging +- Keys are specified in the DID Document in Verification Methods object for various Verification Relationships. +- ITN heavily relies on W3C DIDs (Decentralized Identifiers) and VCs (Verifiable Credentials) employ cryptographic mechanisms and decentralized trust models to mitigate the risks associated with various forms of attacks. +- Within ITN, actors of [W3C VC Data Model](https://www.w3.org/TR/vc-data-model-2.0/) - Issuer, Holder, and Verifier MUST be an ITN DID associated with corresponding DID Document. + +Here's how ITN can prevent the specific attacks outlined: + +1. Eavesdropping + +ITN DID can facilitate the establishment of secure communication channels between parties by encrypting messages exchanged between DIDs using cryptographic keys defined in the corresponding DID Documents. DIDs and VCs use cryptographic signatures to ensure that communication between parties is encrypted and authenticated. This prevents unauthorized interception and eavesdropping of sensitive information. + +2. Replay + +VCs typically include timestamps & cryptogrphic signtaures to prevent replay attacks. Cryptographic signatures are generated using the cryptographic keys are defined in the corresponding DID Documents. Additionally, ITN DID can be combined with secure channels (e.g., HTTPS) to prevent unauthorized retransmission of captured communication. + +3. Message Insertion + +VCs MUST be signed by the issuer, ensuring that any unauthorized insertion of messages would result in a signature mismatch and detection of tampering. + +4. Deletion: + +`Need help here... not sure` + +5. Modification: + +VCs ensure data integrity, as any unauthorized modification of messages would result in a signature mismatch and detection of tampering. + +6. Denial of Service (DoS): + +DIDs and VCs do not inherently prevent DoS attacks, but service providers can implement rate limiting, access controls, and other security measures to mitigate the impact of DoS attacks. + +7. Amplification: + +DIDs and VCs themselves do not amplify attacks. However, service providers implementing DID and VC systems should follow best practices to prevent abuse and exploitation of their services. + +8. Man-in-the-Middle (MitM): + +DIDs and VCs use cryptographic techniques such as Decentralized public key infrastructure (DPKI) and cyrptographic signatures to prevent unauthorized interception and manipulation of communication between parties. By verifying cryptographic signatures associated with DIDs, parties can ensure the authenticity and integrity of messages, mitigating the risk of MitM attacks. + **Note:** Security Considerations section ensures the ITN DID Method Security considerations comply with [W3C DID Method Security Requirements](https://w3c.github.io/did-core/#security-requirements) ## Privacy Considerations From cb65fc9234c8390b57c05da559cf250270be0ae9 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Tue, 16 Apr 2024 16:52:23 -0700 Subject: [PATCH 20/35] accepting suggestions Co-authored-by: Andreas Freund --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 85afd0c..9b623fa 100644 --- a/README.md +++ b/README.md @@ -223,7 +223,7 @@ For all `did:itn` DIDs, the initial asset creation, and subsequent updates are e - Authentication service utilizing [OAuth2](https://oauth.net/2/) for REST APIs and [DIF DID AuthN](https://identity.foundation/working-groups/authentication.html) for DIF DIDcomm messaging - Keys are specified in the DID Document in Verification Methods object for various Verification Relationships. -- ITN heavily relies on W3C DIDs (Decentralized Identifiers) and VCs (Verifiable Credentials) employ cryptographic mechanisms and decentralized trust models to mitigate the risks associated with various forms of attacks. +- ITN heavily relies on W3C DIDs (Decentralized Identifiers) and VCs (Verifiable Credentials) cryptographic mechanisms and decentralized trust models to mitigate the risks associated with various attacks. - Within ITN, actors of [W3C VC Data Model](https://www.w3.org/TR/vc-data-model-2.0/) - Issuer, Holder, and Verifier MUST be an ITN DID associated with corresponding DID Document. Here's how ITN can prevent the specific attacks outlined: From 7e9e73c7827d8f85c3daf00ce7e59ee58bc14221 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Tue, 16 Apr 2024 16:52:56 -0700 Subject: [PATCH 21/35] accepting suggestion Co-authored-by: Andreas Freund --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 9b623fa..06bcd7d 100644 --- a/README.md +++ b/README.md @@ -224,7 +224,6 @@ For all `did:itn` DIDs, the initial asset creation, and subsequent updates are e - Authentication service utilizing [OAuth2](https://oauth.net/2/) for REST APIs and [DIF DID AuthN](https://identity.foundation/working-groups/authentication.html) for DIF DIDcomm messaging - Keys are specified in the DID Document in Verification Methods object for various Verification Relationships. - ITN heavily relies on W3C DIDs (Decentralized Identifiers) and VCs (Verifiable Credentials) cryptographic mechanisms and decentralized trust models to mitigate the risks associated with various attacks. -- Within ITN, actors of [W3C VC Data Model](https://www.w3.org/TR/vc-data-model-2.0/) - Issuer, Holder, and Verifier MUST be an ITN DID associated with corresponding DID Document. Here's how ITN can prevent the specific attacks outlined: From 140db1d33dd2e69a4d8f2780b012d87c49113ab3 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Tue, 16 Apr 2024 16:53:24 -0700 Subject: [PATCH 22/35] accepting suggestion Co-authored-by: Andreas Freund --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 06bcd7d..5fcc766 100644 --- a/README.md +++ b/README.md @@ -233,7 +233,7 @@ ITN DID can facilitate the establishment of secure communication channels betwee 2. Replay -VCs typically include timestamps & cryptogrphic signtaures to prevent replay attacks. Cryptographic signatures are generated using the cryptographic keys are defined in the corresponding DID Documents. Additionally, ITN DID can be combined with secure channels (e.g., HTTPS) to prevent unauthorized retransmission of captured communication. +Digital signatures utilized between the ITN and a user utilize nonces and DLT transactions on either of the utilized networks utilize both chainIds and account nonces to prevent DLT transaction replays. 3. Message Insertion From 863fd5514a4a79fa75255531b9bceeca18062c11 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Tue, 16 Apr 2024 16:53:50 -0700 Subject: [PATCH 23/35] accepting suggestions Co-authored-by: Andreas Freund --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5fcc766..fa0bef8 100644 --- a/README.md +++ b/README.md @@ -237,7 +237,7 @@ Digital signatures utilized between the ITN and a user utilize nonces and DLT tr 3. Message Insertion -VCs MUST be signed by the issuer, ensuring that any unauthorized insertion of messages would result in a signature mismatch and detection of tampering. +Since ITN communication channels are using asymmetric encryption, the only way to insert a message would be to gain access to the private keys used for encryption, DID AuthN, and VC signatures. 4. Deletion: From ecd3fc44502a6b2bfe0f96a4ec2ec1dcd083fa83 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Tue, 16 Apr 2024 16:54:31 -0700 Subject: [PATCH 24/35] accepting suggestions Co-authored-by: Andreas Freund --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fa0bef8..40b1e8f 100644 --- a/README.md +++ b/README.md @@ -241,7 +241,7 @@ Since ITN communication channels are using asymmetric encryption, the only way t 4. Deletion: -`Need help here... not sure` +The DLT transactions on the two anchor DLTs cannot be deleted and DID document entries in the CAS can only be deleted by ITN Node Operators. ITN Node Operators are permissioned, and known legal entities. In addition, currently, only three ITN nodes have write permissions into the CAS. Lastly, existing CAS data redundancies make a CAS deletion not practical. 5. Modification: From 0dec26d5a12b1993cc7e8d369ac3fbdbf2992e13 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Tue, 16 Apr 2024 16:55:02 -0700 Subject: [PATCH 25/35] accepting suggestion Co-authored-by: Andreas Freund --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 40b1e8f..2167082 100644 --- a/README.md +++ b/README.md @@ -245,7 +245,7 @@ The DLT transactions on the two anchor DLTs cannot be deleted and DID document e 5. Modification: -VCs ensure data integrity, as any unauthorized modification of messages would result in a signature mismatch and detection of tampering. +Modifications of the DID anchoring transactions on the two DLTs cannot be modified. CAS DID doc entries could only be maliciously modified by three specific ITN Nodes. Furthermore, data redundancies with rollbacks make modification attacks useless. 6. Denial of Service (DoS): From 45b0d3d0b8fa101818762e75fe7eaa40218e2a94 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Tue, 16 Apr 2024 16:55:26 -0700 Subject: [PATCH 26/35] accepting suggestion Co-authored-by: Andreas Freund --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2167082..53d88d0 100644 --- a/README.md +++ b/README.md @@ -249,7 +249,7 @@ Modifications of the DID anchoring transactions on the two DLTs cannot be modifi 6. Denial of Service (DoS): -DIDs and VCs do not inherently prevent DoS attacks, but service providers can implement rate limiting, access controls, and other security measures to mitigate the impact of DoS attacks. +The ITN can operate as long as one honest node is operational. This means that besides typical (D)DoS protections enterprises utilize, the node redundancies in the network mitigate a DoS attack. 7. Amplification: From 8edf9342ffab76bdf5817898e4454378e03c6399 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Tue, 16 Apr 2024 16:56:25 -0700 Subject: [PATCH 27/35] accepting suggestion Co-authored-by: Andreas Freund --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 53d88d0..75bf8a5 100644 --- a/README.md +++ b/README.md @@ -257,7 +257,7 @@ DIDs and VCs themselves do not amplify attacks. However, service providers imple 8. Man-in-the-Middle (MitM): -DIDs and VCs use cryptographic techniques such as Decentralized public key infrastructure (DPKI) and cyrptographic signatures to prevent unauthorized interception and manipulation of communication between parties. By verifying cryptographic signatures associated with DIDs, parties can ensure the authenticity and integrity of messages, mitigating the risk of MitM attacks. +Asymmetric encryption of all ITN communication channels ensures a high degree of safety against MitM attacks unless the relevant private keys are compromised. **Note:** Security Considerations section ensures the ITN DID Method Security considerations comply with [W3C DID Method Security Requirements](https://w3c.github.io/did-core/#security-requirements) From 88fd2b84e8fde3647153b0adf1fe28bee1b9ccc4 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Tue, 16 Apr 2024 20:57:18 -0700 Subject: [PATCH 28/35] accepting suggestion. Co-authored-by: Andreas Freund --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 75bf8a5..407fcf0 100644 --- a/README.md +++ b/README.md @@ -253,7 +253,7 @@ The ITN can operate as long as one honest node is operational. This means that b 7. Amplification: -DIDs and VCs themselves do not amplify attacks. However, service providers implementing DID and VC systems should follow best practices to prevent abuse and exploitation of their services. +All DID operations apart from DID creation require DID AuthN. Therefore, each attack on a DID operation endpoint requires a DID and a secure communications channel. Hence, any attacks are limited to that established channel which can be disconnected at any time by an Operator. Lastly, the DID creation operation also requires establishing a secure communications channel which again restricts any attack to that channel, and, therefore, mitigation is as already mentioned. DOSing a channel would lead to a blacklisting of the malicious DID and a new DID would have to be created to perform an attack. Since the network only requires one honestly operating node, attacks by individual nodes would be recognized by other network nodes and access to that node can be easily removed by each node operator in their node, isolating the malicious node. And since network transactions have to be reimbursed to the ITN as an organization, spamming attacks of a compromised node lead to economic damage to the Operator operating the malicious node. This is an economic security guarantee since all Node Operators are known legal entities to which exists legal recourse. 8. Man-in-the-Middle (MitM): From 6cbaec7d28d65bcd7a4fc68f46f9f6d0799c7807 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Wed, 17 Apr 2024 15:30:24 -0700 Subject: [PATCH 29/35] updated security considerations & incorporated Umed & Dmitry's feedback. --- README.md | 46 +++++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 407fcf0..f6523db 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ The DID ITN Method Specification 1.0 **Draft Created:** April 10, 2024 -**Latest Update:** April 16, 2024 +**Latest Update:** April 17, 2024 **Contributors & Editors:** @@ -83,13 +83,13 @@ The keywords MAY, MUST, MUST NOT, RECOMMENDED, SHOULD, and SHOULD NOT in this do ## Terminology -1. ITN - Integrated Trust Network -2. EDV - Encrypted Data Vault -3. CAS - Content Addressable Storage -4. DLT - Distributed Ledger Network -5. DID - Decentralized Identifier -6. VC - Verifiable Credentials -7. VP - Verifiable Presentations +1. Integrated Trust Network (ITN) is a block-chain based, protocol-agnostic, federated network delivering decentralized identity services for a new generation of secure digital commerce. ITN provides decentralized digital infrastructure as the required core trust services of governance, authority, identity, & assurance for multi-party business ecosystems. +2. Encrypted Data Vault (EDV) for document storage. +3. Content Addressable Storage (CAS) is an append-only implementation of a Postgres DB with content-addressable hashes and replication between ITN Nodes. +4. Distributed Ledger Technology (DLT) (also called a distributed ledger or shared ledger) is the consensus of replicated, shared, and synchronized digital data that is geographically spread (distributed) across many sites, countries, or institutions. A distributed ledger requires peer-to-peer network and consensus algorithms to ensure the ledger is reliably replicated across nodes. Blockchains are the most well-known example. +5. Decentralized Identifier (DID) is a globally unique identifier that can be resolved to a DID Document, or de-referenced on a specific distributed ledger network, much like a URL on the Internet. +6. Verifiable Credential (VC) is a tamper-evident credential that has authorship that can be cryptographically verified. Verifiable credentials can be used to build verifiable presentations, which can also be cryptographically verified. +7. Verifiable Presentation (VP) is a tamper-evident presentation encoded in such a way that authorship of the data can be trusted after a process of cryptographic verification. ## DID ITN Method Specification @@ -100,7 +100,7 @@ The ITN DID is derived as follow: - A random 32 byte string is generated - The seed is hashed using sha512 - An Ed25519 key pair is generated from the hash. The key pair will be used as the recovery key pair -- The uuid of the did:itn is the base58 encoded value of public keys hexadecimal value +- The identifier of the did:itn is the first 16 bytes of the public key encoded into Base58 format. The format of ITN DID conform to the [W3C DID Core specification](https://www.w3.org/TR/did-core/). The W3C DID Core specification does not specify how a DID is generated, and leaves it up to the implementation provided it ensures uniqueness to a high degree of confidence. @@ -208,10 +208,20 @@ The `revoke` operation also deactivate the DID. ] }, "didDocumentMetadata": { - "created": "2023-11-10T15:20:59Z", - "updated": "2023-11-10T15:20:59Z", + "created": "2024-04-16T14:46:33Z", + "updated": "2024-04-16T14:46:33Z", "deactivated": false, - "recoveryCommitment": "99cdefca761b58664641d3f0b89b4f1e04ad833b7a24a726e3424bc6c17f39a0" + "recoveryCommitment": "b45a0730f9c3227eae0338c8f95e140cff12393e90272fd32f2f21dadd242df0", + "hlfProof": { + "dataHash": "a440e6586566c3370cf968a8fbee40620fc9ac70e2bc2d2c482902576183f30e", + "blockNumber": "19519", + "transactionId": "812cbef8d667c28e939e3ee8f46fe7550f11b6c0042ae8bc3c7965c7e93a262f" + }, + "evmProof": { + "blockHash": "0xadddd6ae2eddbe50117357e8fbcd3921c4b0c6e3be2859a0cc9a75920bf876e3", + "blockNumber": 34291384, + "txHash": "0x4da901b643c05025c262fff27c80f0a30cb635783d057bebd79ef4f5cfed07e7" + } }, "didResolutionMetadata": { } } @@ -219,11 +229,17 @@ The `revoke` operation also deactivate the DID. ## Security Considerations -For all `did:itn` DIDs, the initial asset creation, and subsequent updates are executed using `Ed25519` keys, which are widely recognized as a robust and secure cryptographic mechanism. `Confirm With Umed & Andreas - if the keys are different. DELETE THIS COMMENT LATER.` +For all `did:itn` DIDs, the initial asset creation, and subsequent updates are executed using `Ed25519` keys, which are widely recognized as a robust and secure cryptographic mechanism. + +@AlexMesser @pleerock can you - `Confirm - if the keys are different in the above line. DELETE THIS COMMENT LATER.` -- Authentication service utilizing [OAuth2](https://oauth.net/2/) for REST APIs and [DIF DID AuthN](https://identity.foundation/working-groups/authentication.html) for DIF DIDcomm messaging -- Keys are specified in the DID Document in Verification Methods object for various Verification Relationships. - ITN heavily relies on W3C DIDs (Decentralized Identifiers) and VCs (Verifiable Credentials) cryptographic mechanisms and decentralized trust models to mitigate the risks associated with various attacks. +- Authentication service utilizing [OAuth2](https://oauth.net/2/) for REST APIs and [DIF DID AuthN](https://identity.foundation/working-groups/authentication.html) for DIF DIDcomm messaging. +- Authentication is involved, particularly user-host authentication, the security characteristics are those of OAuth2 and DIDCom 2.0. +- Beyond the residual risks specified in the utilized authentication and authorization protocols, there are the normal implementation security risks that should be addressed through a security audit of any implementation. +- ITN DID Method relies on cryptographic protection mechanisms, ensuring that DID AuthN for all endpoints and communication channels and asymmetric encryption for all data. +- Only the private keys are held in secret and that is up to the user to implement. ITN nodes employ the EDV standard for secret securing including Secure Hardware Elements (HSMs). +- Keys are specified in the DID Document in Verification Methods object for various Verification Relationships. Here's how ITN can prevent the specific attacks outlined: From 7df96748179604fa6d99364fb10bbc55c676aae8 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Thu, 18 Apr 2024 13:20:58 -0700 Subject: [PATCH 30/35] Incorporated feedback from Umed. --- README.md | 53 +++++++++++++++++++++-------------------------------- 1 file changed, 21 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index f6523db..c1e841f 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ The DID ITN Method Specification 1.0 **Draft Created:** April 10, 2024 -**Latest Update:** April 17, 2024 +**Latest Update:** April 18, 2024 **Contributors & Editors:** @@ -33,9 +33,9 @@ The ITN is a permissioned network of nodes operated by ITN Node Operators. Each ITN Node is comprised of the following elements depicted in the figure below: - ITN Agent for Core Services ~ (former name used - Self Sovereign Digital Twin (SSDT) of the Core Services OR Core Services SSDT) -- DLT Gateway: A NodeJS application integrating with the Core Services SSDT, Apache Kafka, and the different DLT networks of the ITN. In the next phase of implementation, the Apache Kafka instances will be connected via message replication to obtain a holistic picture of messages across the network. +- DLT Gateway: An application integrating with the Core Services SSDT, Apache Kafka, and the different DLT networks of the ITN. - DID Resolver: The DID resolver utilizes the Decentralized Identity Foundation DID resolver and is integrated with the Core Services SSDT. -- Content Addressable Storage Network: Currently utilizing an append-only implementation of a Postgres DB with content-addressable hashes and replication between ITN Nodes. There is an implementation of peer-to-peer replication using the IPFS Cluster. +- Content Addressable Storage Network: A database with content-addressable hashes and replication between ITN Nodes. Additionally, supports peer-to-peer replication. - DLT Networks: It is comprised of a Hyperledger Fabric network and Arbitrum One EVM equivalent network (with more to follow, in particular, based on Integrated Trust Network (ITN) expansion). All applications external to the ITN and wishing to utilize the ITN Core Services must implement an ITN Agent as their abstraction layer. An ITN Agent represents a user’s capabilities on ITN and serves as an abstraction and integration layer between ITN and other applications/networks. @@ -74,8 +74,7 @@ so you can add new protocols, transports, and managers to fit your needs. ![ITN_SDK](https://github.com/itn-trust/itn-did-spec/assets/18353464/6135b073-c085-41fd-8ea4-f80e64e0485d) -The ITN SDK has an Identity Protocol provides methods to manage DIDs. -The ITN SDK has a DID Document Manager provide a set of functions to manage DID Documents. +The ITN SDK provides methods to manage DIDs & DID Documents. ## Conformance @@ -85,7 +84,7 @@ The keywords MAY, MUST, MUST NOT, RECOMMENDED, SHOULD, and SHOULD NOT in this do 1. Integrated Trust Network (ITN) is a block-chain based, protocol-agnostic, federated network delivering decentralized identity services for a new generation of secure digital commerce. ITN provides decentralized digital infrastructure as the required core trust services of governance, authority, identity, & assurance for multi-party business ecosystems. 2. Encrypted Data Vault (EDV) for document storage. -3. Content Addressable Storage (CAS) is an append-only implementation of a Postgres DB with content-addressable hashes and replication between ITN Nodes. +3. Content Addressable Storage (CAS) is a database with content-addressable hashes and replication between ITN Nodes. 4. Distributed Ledger Technology (DLT) (also called a distributed ledger or shared ledger) is the consensus of replicated, shared, and synchronized digital data that is geographically spread (distributed) across many sites, countries, or institutions. A distributed ledger requires peer-to-peer network and consensus algorithms to ensure the ledger is reliably replicated across nodes. Blockchains are the most well-known example. 5. Decentralized Identifier (DID) is a globally unique identifier that can be resolved to a DID Document, or de-referenced on a specific distributed ledger network, much like a URL on the Internet. 6. Verifiable Credential (VC) is a tamper-evident credential that has authorship that can be cryptographically verified. Verifiable credentials can be used to build verifiable presentations, which can also be cryptographically verified. @@ -100,7 +99,7 @@ The ITN DID is derived as follow: - A random 32 byte string is generated - The seed is hashed using sha512 - An Ed25519 key pair is generated from the hash. The key pair will be used as the recovery key pair -- The identifier of the did:itn is the first 16 bytes of the public key encoded into Base58 format. +- The identifier of the `did:itn` is the first 16 bytes of the public key encoded into Base58 format. The format of ITN DID conform to the [W3C DID Core specification](https://www.w3.org/TR/did-core/). The W3C DID Core specification does not specify how a DID is generated, and leaves it up to the implementation provided it ensures uniqueness to a high degree of confidence. @@ -108,16 +107,13 @@ The format of ITN DID conform to the [W3C DID Core specification](https://www.w3 ### Operations -Identity Protocol provides methods to manage DIDs. - #### Create Description: Based on the DID data schema context file and DID method an ITN process anchors a DID and its DID document and delivers it to the requestor. Requirements: -- `creator` input parameter can be a DID String or a DID document. -- The provided DID MUST be compliant with the did:itn method. +- The provided DID MUST be compliant with the `did:itn` method. - The provided DID document MUST be compliant with the DID V1.0 DID document specification. --- @@ -128,8 +124,8 @@ Description: Based on the DID data schema context file and DID method an ITN pro Requirements: -- A DID string MUST be provided as an input parameter. -- The provided DID MUST be compliant with the did:itn method. +- A DID string MUST be provided. +- The provided DID MUST be compliant with the `did:itn` method. --- @@ -139,8 +135,7 @@ Description: Based on the DID data schema context file and DID method an ITN pro Requirements: -- `receiver` input parameter can be a DID string or a DID Document. -- The provided DID string MUST be compliant with the did:itn method. +- The provided DID string MUST be compliant with the `did:itn` method. - The provided DID document MUST be compliant with the DID V1.0 DID document specification. --- @@ -151,9 +146,8 @@ Description: Based on the DID data schema context file and DID method an ITN pro Requirements: -- `did` input parameter MUST be a DID string that has to be revoked. -- `receiver` input parameter can be a DID string or a DID Document. -- The provided DID string MUST be compliant with the did:itn method. +- A DID string MUST be provided that has to be revoked. +- The provided DID string MUST be compliant with the `did:itn` method. - The provided DID document MUST be compliant with the DID V1.0 DID document specification. --- @@ -164,9 +158,8 @@ Description: Based on the DID data schema context file and DID method, an ITN pr Requirements: -- `did` input parameter MUST be a DID string that has to be recovered. -- `receiver` input parameter can be a DID string or a DID Document. -- The provided DID string MUST be compliant with the did:itn method. +- A DID string MUST be provided that has to be recovered. +- The provided DID string MUST be compliant with the `did:itn` method. - The provided DID document MUST be compliant with the DID V1.0 DID document specification. --- @@ -229,10 +222,6 @@ The `revoke` operation also deactivate the DID. ## Security Considerations -For all `did:itn` DIDs, the initial asset creation, and subsequent updates are executed using `Ed25519` keys, which are widely recognized as a robust and secure cryptographic mechanism. - -@AlexMesser @pleerock can you - `Confirm - if the keys are different in the above line. DELETE THIS COMMENT LATER.` - - ITN heavily relies on W3C DIDs (Decentralized Identifiers) and VCs (Verifiable Credentials) cryptographic mechanisms and decentralized trust models to mitigate the risks associated with various attacks. - Authentication service utilizing [OAuth2](https://oauth.net/2/) for REST APIs and [DIF DID AuthN](https://identity.foundation/working-groups/authentication.html) for DIF DIDcomm messaging. - Authentication is involved, particularly user-host authentication, the security characteristics are those of OAuth2 and DIDCom 2.0. @@ -255,23 +244,23 @@ Digital signatures utilized between the ITN and a user utilize nonces and DLT tr Since ITN communication channels are using asymmetric encryption, the only way to insert a message would be to gain access to the private keys used for encryption, DID AuthN, and VC signatures. -4. Deletion: +4. Deletion The DLT transactions on the two anchor DLTs cannot be deleted and DID document entries in the CAS can only be deleted by ITN Node Operators. ITN Node Operators are permissioned, and known legal entities. In addition, currently, only three ITN nodes have write permissions into the CAS. Lastly, existing CAS data redundancies make a CAS deletion not practical. -5. Modification: +5. Modification -Modifications of the DID anchoring transactions on the two DLTs cannot be modified. CAS DID doc entries could only be maliciously modified by three specific ITN Nodes. Furthermore, data redundancies with rollbacks make modification attacks useless. +Modifications of the DID anchoring transactions on the two DLTs cannot be modified. CAS DID doc entries could only be maliciously modified by three specific ITN Nodes. Furthermore, data redundancies with rollbacks make modification attacks useless. -6. Denial of Service (DoS): +6. Denial of Service (DoS) The ITN can operate as long as one honest node is operational. This means that besides typical (D)DoS protections enterprises utilize, the node redundancies in the network mitigate a DoS attack. -7. Amplification: +7. Amplification -All DID operations apart from DID creation require DID AuthN. Therefore, each attack on a DID operation endpoint requires a DID and a secure communications channel. Hence, any attacks are limited to that established channel which can be disconnected at any time by an Operator. Lastly, the DID creation operation also requires establishing a secure communications channel which again restricts any attack to that channel, and, therefore, mitigation is as already mentioned. DOSing a channel would lead to a blacklisting of the malicious DID and a new DID would have to be created to perform an attack. Since the network only requires one honestly operating node, attacks by individual nodes would be recognized by other network nodes and access to that node can be easily removed by each node operator in their node, isolating the malicious node. And since network transactions have to be reimbursed to the ITN as an organization, spamming attacks of a compromised node lead to economic damage to the Operator operating the malicious node. This is an economic security guarantee since all Node Operators are known legal entities to which exists legal recourse. +All DID operations apart from DID creation require DID AuthN. Therefore, each attack on a DID operation endpoint requires a DID and a secure communications channel. Hence, any attacks are limited to that established channel which can be disconnected at any time by an Operator. Lastly, the DID creation operation also requires establishing a secure communications channel which again restricts any attack to that channel, and, therefore, mitigation is as already mentioned. DOSing a channel would lead to a blacklisting of the malicious DID and a new DID would have to be created to perform an attack. Since the network only requires one honestly operating node, attacks by individual nodes would be recognized by other network nodes and access to that node can be easily removed by each node operator in their node, isolating the malicious node. And since network transactions have to be reimbursed to the ITN as an organization, spamming attacks of a compromised node lead to economic damage to the Operator operating the malicious node. This is an economic security guarantee since all Node Operators are known legal entities to which exists legal recourse. -8. Man-in-the-Middle (MitM): +8. Man-in-the-Middle (MitM) Asymmetric encryption of all ITN communication channels ensures a high degree of safety against MitM attacks unless the relevant private keys are compromised. From b654b0eed32d2e420a696fff1a0169f7029449d9 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Fri, 19 Apr 2024 07:22:03 -0700 Subject: [PATCH 31/35] minor changes removed an ITN process --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c1e841f..b09f461 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,7 @@ The format of ITN DID conform to the [W3C DID Core specification](https://www.w3 #### Create -Description: Based on the DID data schema context file and DID method an ITN process anchors a DID and its DID document and delivers it to the requestor. +Description: Based on the DID data schema context file and DID method, the network anchors a DID and its DID document and delivers it to the requestor. Requirements: @@ -120,7 +120,7 @@ Requirements: #### Resolve -Description: Based on the DID data schema context file and DID method an ITN process delivers a DID document in accordance with the W3C DID standard. +Description: Based on the DID data schema context file and DID method, the network delivers a DID document in accordance with the W3C DID standard. Requirements: @@ -131,7 +131,7 @@ Requirements: #### Update -Description: Based on the DID data schema context file and DID method an ITN process creates an updated DID document in accordance with the W3C DID standard. +Description: Based on the DID data schema context file and DID method, the network creates an updated DID document in accordance with the W3C DID standard. Requirements: @@ -142,7 +142,7 @@ Requirements: #### Revoke -Description: Based on the DID data schema context file and DID method an ITN process revokes an existing DID and its DID document in accordance with the W3C DID standard. +Description: Based on the DID data schema context file and DID method, the network revokes an existing DID and its DID document in accordance with the W3C DID standard. Requirements: @@ -154,7 +154,7 @@ Requirements: #### Recover -Description: Based on the DID data schema context file and DID method, an ITN process recovers a DID and its DID document in accordance with the W3C DID standard. +Description: Based on the DID data schema context file and DID method, the network recovers a DID and its DID document in accordance with the W3C DID standard. Requirements: From 19b1abaf77457d12dd85cb9e92f875595582ebf3 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Fri, 19 Apr 2024 07:27:48 -0700 Subject: [PATCH 32/35] Minor Updates Updated the Appendix section. --- README.md | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/README.md b/README.md index b09f461..89f27ed 100644 --- a/README.md +++ b/README.md @@ -311,22 +311,7 @@ Supported curves are: P-521 Bls12381G1 Bls12381G2 - secp256k1 - -## Message Encryptor - -Provides a set of functions to encrypt and decrypt DIDComm messages. Message Encryptor supports two forms of message -encryption: Authenticated Sender Encryption (`authcrypt`) and Anonymous Sender Encryption (`anoncrypt`). -Both forms are encrypted to the recipient DID. Only `authcrypt` provides direct assurances of who the sender is. - -#### Message Encryptor supports the following curves for the keys involved in key agreement - -| Curve | Description | -|--------|---------------------------------------------------------------------------------------------------------------------------------------| -| X25519 | The underlying curve is actually Curve25519, however when used in the context of Diffie-Hellman
the identifier of X25519 is used | -| P-256 | NIST defined P-256 elliptic curve. | -| P-384 | NIST defined P-384 elliptic curve. | -| P-521 | NIST defined P-521 elliptic curve. | + secp256k1 | #### The following `AEAD` algorithms are supported for content encryption of the message From 9b187fff24204a02f88ea4321ab6c436f8a63e90 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Fri, 19 Apr 2024 08:02:59 -0700 Subject: [PATCH 33/35] Removed ITN Agent Image and minor updates. --- README.md | 10 +++------- docs/images/ITN Agent.jpg | Bin 47745 -> 0 bytes 2 files changed, 3 insertions(+), 7 deletions(-) delete mode 100644 docs/images/ITN Agent.jpg diff --git a/README.md b/README.md index 89f27ed..3883a59 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ The DID ITN Method Specification 1.0 **Draft Created:** April 10, 2024 -**Latest Update:** April 18, 2024 +**Latest Update:** April 19, 2024 **Contributors & Editors:** @@ -52,11 +52,7 @@ The ITN Agent utilized in each ITN node is comprised of the following elements: - An implementation of ITN Core Services functionality via DIF DIDcomm - An implementation of the [W3C/DIF Encrypted Data Vault](https://identity.foundation/confidential-storage/) for document storage -ITN Agent Integration can be achieved through an SDK, as utilized by the ITN. - -![ITN Agent](./docs/images/ITN%20Agent.jpg) - -ITN Agent is an implementation of the [Aries Agent RFC](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0004-agents/README.md) +ITN Agent Integration can be achieved through an SDK, as utilized by the ITN. ITN Agent is an implementation of the [Aries Agent RFC](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0004-agents/README.md) with a flexible plugin architecture. Depending on which plugins and [DIDComm protocols](https://didcomm.org/search/?page=1) you use, your instance of ITN Agent can @@ -246,7 +242,7 @@ Since ITN communication channels are using asymmetric encryption, the only way t 4. Deletion -The DLT transactions on the two anchor DLTs cannot be deleted and DID document entries in the CAS can only be deleted by ITN Node Operators. ITN Node Operators are permissioned, and known legal entities. In addition, currently, only three ITN nodes have write permissions into the CAS. Lastly, existing CAS data redundancies make a CAS deletion not practical. +The DLT transactions on the two anchor DLTs cannot be deleted and DID document entries in the CAS can only be deleted by ITN Node Operators. ITN Node Operators are permissioned, and known legal entities. In addition, currently, only three ITN nodes have write permissions into the CAS. Lastly, existing CAS data redundancies make a CAS deletion not practical. 5. Modification diff --git a/docs/images/ITN Agent.jpg b/docs/images/ITN Agent.jpg deleted file mode 100644 index efed6168cc3612f4319c515f1db4ce6f7d35c181..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47745 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 -t&UJh8vI(bEJlfKhmG1cAR@+!7v{x32nM@A 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 L4Fx;w|K9`vU#`*3 From 598a3c38ad99bcfeebf363d21c9fab8980eda568 Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Fri, 19 Apr 2024 08:27:10 -0700 Subject: [PATCH 34/35] Updated the format section with recovery key pair details. --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3883a59..0fee770 100644 --- a/README.md +++ b/README.md @@ -92,10 +92,13 @@ The keywords MAY, MUST, MUST NOT, RECOMMENDED, SHOULD, and SHOULD NOT in this do The ITN DID is derived as follow: -- A random 32 byte string is generated -- The seed is hashed using sha512 -- An Ed25519 key pair is generated from the hash. The key pair will be used as the recovery key pair -- The identifier of the `did:itn` is the first 16 bytes of the public key encoded into Base58 format. +1. A random 32 byte string is generated +2. The seed is hashed using sha512 +3. An Ed25519 key pair is generated from the hash. The key pair will be used as the recovery key pair +4. The identifier of the `did:itn` is the first 16 bytes of the recovery key pair's public key encoded into Base58 format. +5. Prefix the generated identifier with `did:itn` + +All operations on the DID (update, revoke, recover) are signed by private recovery key and verified by public recovery key. Verification process also includes the DID identifier validation - having the public recovery key, the verifier repeats steps 4 and 5 on his side and makes sure the DID matches the recovery key. The format of ITN DID conform to the [W3C DID Core specification](https://www.w3.org/TR/did-core/). The W3C DID Core specification does not specify how a DID is generated, and leaves it up to the implementation provided it ensures uniqueness to a high degree of confidence. From e2b4bc61783a51270d58fd0bac3532521f7ae01a Mon Sep 17 00:00:00 2001 From: Parth Bhatt Date: Fri, 19 Apr 2024 09:04:14 -0700 Subject: [PATCH 35/35] Updated the Modification attack explanation in security consideration. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0fee770..0ab84eb 100644 --- a/README.md +++ b/README.md @@ -249,7 +249,7 @@ The DLT transactions on the two anchor DLTs cannot be deleted and DID document e 5. Modification -Modifications of the DID anchoring transactions on the two DLTs cannot be modified. CAS DID doc entries could only be maliciously modified by three specific ITN Nodes. Furthermore, data redundancies with rollbacks make modification attacks useless. +DID anchoring transactions on a DLT cannot be altered once the anchoring transaction is finalized on the respective DLT. CAS DID doc entries could only be maliciously modified by three specific ITN Nodes. Furthermore, data redundancies with rollbacks make modification attacks useless. 6. Denial of Service (DoS)