Product Docs
Product DocsTechnical DocsLearning & GovernanceUseful Links
  • Product Docs
  • Node Docs
  • Learning Docs
  • â„šī¸Getting Started
    • Product Overview
    • âžĄī¸Get Started with cheqd Studio
      • 👉Set Up Your Account
      • đŸ—ī¸Create API Keys
      • đŸĒ™Token Top Up
      • 🔄Advanced Configuration Options
    • â˜‘ī¸Use Trust Registries for AI Agents
      • đŸ—ī¸Build an AI Agent Trust Registry
        • Setup AI Agent Trust Registry
          • Issue Verifiable Credentials to AI Agent
        • Setup and Configure MCP Server
          • Create AI Agent DID
          • Import Credential to AI Agent
          • Advanced functionality
            • Issue a Verifiable Credential
            • Verify a Credential
      • 🤝Validate AI Agent Trust Chain
  • đŸŸĸStart using cheqd
    • 🆔Create DIDs and Identity Keys
      • Create a DID
      • Create Identity Keys
      • Create a Subject DID
      • Resolve a DID
      • Update a DID
      • Deactivate a DID
    • ✅Issue Credentials and Presentations
      • Issue a Verifiable Credential
      • Setup Verida Wallet
      • Verify a Verifiable Credential
      • Verify a Verifiable Presentation
      • Revoke a Verifiable Credential
      • Suspend or Unsuspend a Verifiable Credential
    • â™ģī¸Charge for Verifiable Credentials
      • Understanding Credential Payments
        • Access Control Conditions
        • Privacy Considerations
      • Charge for Status List
      • Issue Credential with Encrypted Status List
      • Create Verifier Pays Issuer flow
      • Bulk Update or Rotate Encryption Keys
    • 🤝Build Trust Registries
      • Decentralized Trust Chains (DTCs)
        • Root Authorisations
        • RTAO -> TAO
        • TAO -> SubTAO
        • TAO -> Trusted Issuer (TI)
        • Referencing Trust Registry within a Verifiable Credential
      • Set up Trust Chain
        • Issue a Verifiable Accreditation
        • Verify a Verifiable Accreditation
      • Get Started with TRAIN
        • Deploy TRAIN and Anchor rTAO in DNS
        • Validate Trust Chain
    • 🎋Create Status Lists
      • Bitstring Status List
        • Create Bitstring Status List
        • Update Bitstring Status List
        • Check Bitstring Status List
        • Search Bitstring Status List
      • Token Status List
        • Create Token Status List
        • Update Token Status List
    • â†•ī¸Create DID-Linked Resources
      • Understanding DID-Linked Resources
        • Context for developing DID-Linked Resources
        • Technical composition of DID-Linked Resources
        • Referencing DID-Linked Resources in VCs
      • Create a DID-Linked Resource
      • Search for DID-Linked Resources
  • đŸ› ī¸Integrate an SDK
    • Choosing the right SDK
    • 🍏Credo
      • Setup Credo Agent
      • Decentralized Identifiers (DIDs)
        • Create a DID
        • Update a DID
        • Deactivate a DID
      • DID-Linked Resources
        • Create DID-Linked Resource
        • Resolve DID-Linked Resource
        • Create AnonCreds Schema
        • Create AnonCreds Credential Definition
      • Verifiable Credentials and Presentations
        • Issue a Verifiable Credential (AnonCreds)
        • Present a Verifiable Credential (AnonCreds)
    • 🍊ACA-Py
      • Setup ACA-Py Agent
      • Decentralized Identifiers (DIDs)
        • Create a DID
        • Update a DID
        • Deactivate a DID
      • DID-Linked Resources
        • Create AnonCreds Schema
        • Create AnonCreds Credential Definition
      • Verifiable Credentials and Presentations
        • AnonCreds
          • Issue a Verifiable Credential
          • Present a Verifiable Credential
          • Revoke a Verifiable Credential
        • JSON-LD
          • Issue a Verifiable Credential
          • Present a Verifiable Credential
    • 🍈Veramo
      • Setup Veramo CLI for cheqd
        • Troubleshooting Veramo CLI Setup
      • Decentralized Identifiers (DIDs)
        • Create a DID
        • Querying a DID
        • Update an existing DID
        • Deactivate a DID
        • Create an off-ledger holder DID
        • Managing Identity Keys
        • Troubleshooting
      • Verifiable Credentials and Presentations
        • Issue a Verifiable Credential
        • Verify a Verifiable Credential
        • Create a Verifiable Presentation
        • Verify a Verifiable Presentation
      • Credential Payments
        • Charge for Status List
        • Issue Credential with Encrypted Status List
        • Verifier pays Issuer
      • Bitstring Status List
        • Create Status List
        • Issuing a Verifiable Credential referencing Status List
      • DID-Linked Resources
        • Create a DID-Linked Resource
        • Create a new Resource version within existing Collection
    • đŸĢWalt.id Community Stack
  • đŸ—ī¸Architecture
    • Architecture Decision Record (ADR) Process
    • List of ADRs
      • đŸ”ĩADR 001: cheqd DID Method
      • đŸŸĸADR 002: DID-Linked Resources
      • 🟡ADR 003: DID Resolver
      • 🟠ADR 004: DID Registrar
      • đŸŸŖADR 005: DID Resolution & DID URL Dereferencing
  • đŸ’ĢAdvanced features and alternatives
    • âžĄī¸DID Registrar
      • Setup DID Registrar
      • Create a DID
      • Create a DID-Linked Resource
    • âŦ…ī¸DID Resolver
      • Setup DID Resolver
    • ⚡AnonCreds Object Method
      • Schemas
      • Credential Definitions
      • Revocation Registry Definitions
      • Revocation Status Lists
    • 🌠Advanced Tooling
      • cheqd Cosmos CLI for identity
        • Create a DID
        • Update a DID
        • Deactivate a DID
        • Query a DID
        • Create a DID-Linked Resource
        • Update a DID-Linked Resource
      • Direct interaction with ledger code
      • VDR Tools CLI with cheqd (deprecated)
      • Demo Wallet for Identity Setup
  • âš›ī¸Network
    • Get started with cheqd Network
      • Identity Write Pricing
      • Comparison to Hyperledger Indy
    • ⏊Setup your Wallet
      • Setup Leap Wallet
        • Congifure cheqd Testnet for Leap
      • Setup Keplr Wallet
      • Migrate from Keplr to Leap Wallet
    • â†Ēī¸Useful Tools and APIs
      • Block Explorer
      • Testnet Faucet
      • Validator Status API
      • Cheqd x Cosmos Data APIs
      • Cosmos Airdrop Helpers
      • Cosmos Address Convertor
      • Ethereum Bridge
    • âŦ†ī¸Network Upgrades
      • 2021
        • 0.1.x
        • 0.2.x
        • 0.3.x
      • 2022
        • 0.4.x
        • 0.5.x
        • 0.6.x
      • 2023
        • 1.x
      • 2024
        • 2.x
        • 3.x
      • Root Cause Analysis of Outages
        • v1.x upgrade RCA
  • âš–ī¸Legal
    • License
    • Code of Conduct
    • Security Policy
  • 🆘Support
    • System Status
    • Discord
    • Bugs & Feature Requests
Powered by GitBook
LogoLogo

General

  • Website
  • Blog
  • Get $CHEQ

Product Docs

  • Product Docs
  • cheqd Studio
  • Creds.xyz
  • Bug/Feature Requests

Technical Docs

  • Node Docs
  • GitHub
  • Block Explorer

Learning Docs

  • Learning Docs
  • Governance Docs
  • Governance Forum
  • Governance Explorer
On this page
  • Status
  • Summary
  • Context
  • Rationale for baselining against Hyperledger Indy
  • Rationale for using the Cosmos blockchain framework for cheqd
  • Identity-domain transaction types in Hyperledger Indy
  • cheqd DID method (did:cheqd)
  • DID Method Name
  • Method Specific Identifier
  • Syntax for did:cheqd method
  • Examples of did:cheqd identifiers
  • DID Documents ("DIDDocs") on cheqd
  • Elements of a DIDDoc
  • DID Document metadata
  • Verification method
  • Services
  • Representation on cheqd-node in protobuf format
  • DIDDoc representation on-ledger
  • Verification method representation on-ledger
  • Service representation on-ledger
  • Update DID
  • Deactivate DID
  • Get/Resolve DID
  • Considerations
  • Security considerations
  • Privacy Considerations
  • Changes from Indy entities and transactions
  • Decision
  • Consequences
  • Backward Compatibility
  • Positive
  • Negative
  • Neutral
  • References

Was this helpful?

Edit on GitHub
Export as PDF
  1. Architecture
  2. List of ADRs

ADR 001: cheqd DID Method

Architecture Decision Record (ADR) detailing the cheqd DID Method: did:cheqd.

Last updated 28 days ago

Was this helpful?

Status

Category
Status

Authors

Ankur Banerjee, Alexandr Kolesov, Alex Tweeddale, Brent Zundel, Renata Toktar, Richard Esplin

ADR Stage

ACCEPTED

Implementation Status

Implemented

Start Date

2021-09-23

Last Updated

2023-02-06

Summary

This ADR defines the cheqd DID method and describes the identity entities, queries, and transaction types for the cheqd network: a purpose-built self-sovereign identity (SSI) network based on the .

(DIDs) are a type of identifier that enables verifiable, decentralized digital identity. A DID refers to any subject (for example, a person, organization, thing, data model, abstract entity, and so on) as determined by the controller of the DID.

Context

Rationale for baselining against Hyperledger Indy

Hyperledger Indy is a verifiable data registry (VDR) built for DIDs with a strong focus on privacy-preserving techniques. It is one of the most widely-adopted SSI blockchain ledgers. Most notably, Indy is used by the .

The Sovrin Foundation initiated a project called in 2018 to create a native token for Hyperledger Indy. libsovtoken was intended to be a payment handler library that could work with libindy and be merged upstream. This native token would allow interactions on Hyperledger Indy networks (such as Sovrin) to be paid for using tokens.

Due to challenges the project ran into, the libsovtoken codebase saw its .

Rationale for using the Cosmos blockchain framework for cheqd

The cheqd network aims to support similar use cases for SSI as seen on Hyperledger Indy networks, with a similar focus on privacy-resspecting techniques.

  1. Hyperledger Indy is a permissioned ledger: Indy networks are permissioned networks where the ability to have write capability is restricted to a limited number of nodes. Governance of such a permissioned network is therefore also not decentralised.

  2. Wider ecosystem for token functionality outside of Hyperledger Indy: Due to its origins as an identity-specific ledger, Indy does not have a fully-featured token implementation with sophisticated capabilities. Moreover, this also impacts end-user options for ecosystem services such as token wallets, cryptocurrency exchanges, custodianship services etc that would be necessary to make a viable, enterprise-ready SSI ledger with token functionality.

Identity-domain transaction types in Hyperledger Indy

The following identity-domain transactions from Indy were considered:

  1. NYM: Equivalent to "DIDs" on other networks

  2. ATTRIB: Payload for DID Document generation

  3. SCHEMA: Schema used by a credential

  4. CRED_DEF: Credential definition by an issuer for a particular schema

  5. REVOC_REG_DEF: Credential revocation registry definition

  6. REVOC_REG_ENTRY: Credential revocation registry entry

Revocation registries for credentials are not covered under the scope of this ADR. This topic is discussed separately in a future ADR as there is ongoing research by the cheqd project on how to improve the privacy and scalability of credential revocations.

cheqd DID method (did:cheqd)

DID Method Name

The method-name for the cheqd DID Method will be identified by the string cheqd.

A DID that uses the cheqd DID method MUST begin with the prefix did:cheqd. This prefix string MUST be in lowercase. The remainder of the DID, after the prefix, is as follows:

Method Specific Identifier

The cheqd DID method's method-specific identifier (method-specific-id) is made up of the namespace component. The namespace is defined as a string that identifies the cheqd network (e.g., "mainnet", "testnet") where the DID reference is stored. Different cheqd networks may be differentiated based on whether they are production vs non-production, governance frameworks in use, participants involved in running nodes, etc.

The namespace associated with a certain network/ledger is stored in the genesis file on the node and cannot be changed by validators vote. A namespace is optional and can be omitted.

UUID-style Unique Identifiers

Any client application can generate these UUIDs using their own preferred implementation in any programming language, as opposed to the method-specific logic required for Indy-style DID identifiers.

Indy-style Unique Identifiers

Namespace

If no namespace is specified, it assumed to be default namespace for the network/ledger the request is targetted at. This will generally be mainnet for the primary production cheqd network.

Syntax for did:cheqd method

cheqd-did       = "did:cheqd:" [namespace]
namespace       = 1*namespace-char ":" unique-id
namespace-char  = ALPHA / DIGIT
unique-id       = *id-char / UUID
id-char         = ALPHA / DIGIT

Note: The *id-char unique-id must be 16 bytes of Indy-style base58 encoded identifier.

ABNF syntax for UUID-style identifiers

UUID                   = time-low "-" time-mid "-"
                         time-high-and-version "-"
                         clock-seq-and-reserved
                         clock-seq-low "-" node
time-low               = 4hexOctet
time-mid               = 2hexOctet
time-high-and-version  = 2hexOctet
clock-seq-and-reserved = hexOctet
clock-seq-low          = hexOctet
node                   = 6hexOctet
hexOctet               = hexDigit hexDigit
hexDigit =
      "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" /
      "a" / "b" / "c" / "d" / "e" / "f" /
      "A" / "B" / "C" / "D" / "E" / "F"

Examples of did:cheqd identifiers

Indy-style

A DID written to the cheqd "mainnet" ledger namespace with an Indy-style identifier:

did:cheqd:mainnet:TAwT8WVt3dz2DBAifwuSkn

A DID written to the cheqd "testnet" ledger namespace with an Indy-style identifier:

did:cheqd:testnet:TAwT8WVt3dz2DBAifwuSkn

An Indy-style DID where no namespace is defined, where the namespace would default to the one defined on ledger where it's published (typically, mainnet):

did:cheqd:TAwT8WVt3dz2DBAifwuSkn

UUID-style

A UUID-style DID on cheqd "mainnet" namespace:

did:cheqd:mainnet:de9786cd-ec53-458c-857c-9342cf264f80

A UUID-style DID where no namespace is defined, where the namespace would default to the one defined on ledger where it's published (typically, mainnet):

did:cheqd:de9786cd-ec53-458c-857c-9342cf264f80

DID Documents ("DIDDocs") on cheqd

Elements of a DIDDoc

The following elements are needed for a W3C specification compliant DIDDoc representation:

  1. @context (optional): A list of strings with links or JSONs for describing specifications that this DID Document is following to.

  2. id: Target DID with cheqd DID Method prefix did:cheqd:<namespace>: and a unique-id identifier.

  3. controller (optional): A list of fully qualified DID strings or one string. Contains one or more DIDs who can update this DIDdoc. All DIDs must exist.

  4. verificationMethod (optional): A list of Verification Methods

  5. authentication (optional): A list of strings with key aliases or IDs

  6. assertionMethod (optional): A list of strings with key aliases or IDs

  7. capabilityInvocation (optional): A list of strings with key aliases or IDs

  8. capabilityDelegation (optional): A list of strings with key aliases or IDs

  9. keyAgreement (optional): A list of strings with key aliases or IDs

  10. service (optional): A set of Service Endpoint maps

  11. alsoKnownAs (optional): A list of strings. A DID subject can have multiple identifiers for different purposes, or at different times. The assertion that two or more DIDs refer to the same DID subject can be made using the alsoKnownAs property.

Example of DIDDoc representation

{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    "https://w3id.org/security/suites/ed25519-2020/v1"
  ],
  "id": "did:cheqd:mainnet:c82f2b02-bdab-4dd7-b833-3e143745d612",
  "verificationMethod": [
    {
      "id": "did:cheqd:mainnet:c82f2b02-bdab-4dd7-b833-3e143745d612#authKey1",
      "type": "Ed25519VerificationKey2020", // external (property value)
      "controller": "did:cheqd:mainnet:c82f2b02-bdab-4dd7-b833-3e143745d612",
      "publicKeyMultibase": "zAKJP3f7BD6W4iWEQ9jwndVTCBq8ua2Utt8EEjJ6Vxsf"
    },
    {
      "id": "did:cheqd:mainnet:c82f2b02-bdab-4dd7-b833-3e143745d612#capabilityInvocationKey",
      "type": "Ed25519VerificationKey2020", // external (property value)
      "controller": "did:cheqd:mainnet:c82f2b02-bdab-4dd7-b833-3e143745d612",
      "publicKeyMultibase": "z4BWwfeqdp1obQptLLMvPNgBw48p7og1ie6Hf9p5nTpNN"
    }
  ],
  "authentication": ["did:cheqd:mainnet:c82f2b02-bdab-4dd7-b833-3e143745d612#authKey1"],
  "capabilityInvocation": ["did:cheqd:mainnet:c82f2b02-bdab-4dd7-b833-3e143745d612#capabilityInvocationKey"],
}

State format for DIDDocs on ledger

"diddoc:<id>" -> {DIDDoc, DidDocumentMetadata, txHash, txTimestamp }

didDocumentMetadata is created by the node after transaction ordering and before adding it to a state.

DID Document metadata

Each DID Document MUST have a metadata section when a representation is produced. It can have the following properties:

  1. created (string): Formatted as an XML Datetime normalized to UTC 00:00:00 and without sub-second decimal precision, e.g., 2020-12-20T19:17:47Z.

  2. updated (string): The value of the property MUST follow the same formatting rules as the created property. The updated field is null if an Update operation has never been performed on the DID document. If an updated property exists, it can be the same value as the created property when the difference between the two timestamps is less than one second.

  3. deactivated (string): If DID has been deactivated, DID document metadata MUST include this property with the boolean value true. By default this is set to false.

  4. versionId (string): A UUID string that represents the version identifier of the DID Document.

  5. previousVersionId (string): A UUID string that represents the version identifier of the previous version of the DID Document. The previousVersionId field is an empty string if an Update operation has never been performed on the DID document

  6. nextVersionId (string): A UUID string that represents the version identifier of the next version of the DID Document. The nextVersionId field is an empty string if an Update operation has never been performed on the DID document

Example of DIDDoc metadata

{
  "created": "2020-12-20T19:17:47Z",
  "updated": "2020-12-20T19:19:47Z",
  "deactivated": false,
  "versionId": "37c20bad-7593-4cce-a0f5-db9aa77b359c",
  "previousVersionId": null,
  "nextVersionId": null,
  "linkedResourceMetadata": [
       {
        "resourceURI":          "did:cheqd:mainnet:N22KY2Dyvmuu2PyyqSFKue/resources/9cc97dc8-ab3a-4a2e-a18a-13f5a54e9096",
        "resourceCollectionId": "N22KY2Dyvmuu2PyyqSFKue",
        "resourceId":            "9cc97dc8-ab3a-4a2e-a18a-13f5a54e9096",
        "resourceName":         "PassportSchema",
        "resourceType":         "CL-Schema",
        "mediaType":            "application/json",
        "created":              "2022-04-20T20:19:19Z",
        "checksum":             "a7c369ee9da8b25a2d6e93973fa8ca939b75abb6c39799d879a929ebea1adc0a",
        "previousVersionId":     "",
        "nextVersionId":         ""
      }
  ]
}

Verification method

Verification methods are used to define how to authenticate / authorise interactions with a DID subject or delegates. Verification method is an OPTIONAL property.

  1. id (string): A string with format did:cheqd:<namespace>#<key-alias>

  2. controller: A string with fully qualified DID. DID must exist.

  3. type (string)

  4. publicKeyBase58 (optional): A base58-encoded string.

Note: A single verification method entry cannot contain more than one of publicKeyJwk, publicKeyBase58 and publicKeyMultibase, but must contain at least one of them.

Example of Verification method in a DIDDoc

{
  "id": "did:cheqd:mainnet:N22N22KY2Dyvmuu2#key-0",
  "type": "JsonWebKey2020",
  "controller": "did:cheqd:mainnet:N22N22KY2Dyvmuu2",
  "publicKeyJwk": {
    "kty": "OKP",
    // external (property name)
    "crv": "Ed25519",
    // external (property name)
    "x": "VCpo2LMLhn6iWku8MKvSLg2ZAoC-nlOyPVQaO3FxVeQ"
    // external (property name)
  }
}

Services

Services can be defined in a DIDDoc to express means of communicating with the DID subject or associated entities.

Example of Service in a DIDDoc

{
  "id":"did:cheqd:mainnet:N22N22KY2Dyvmuu2#linked-domain",
  "type": "LinkedDomains",
  "serviceEndpoint": [
    "https://foo.example.com"
  ]
}

Representation on cheqd-node in protobuf format

Since cheqd-node is built using the Cosmos SDK, the data stored directly on ledger is formatted in Protobuf and is transformed back into compliant JSON client-side on request.

DIDDoc representation on-ledger

{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    "https://w3id.org/security/suites/ed25519-2020/v1"
  ],
  "id": "did:cheqd:mainnet:5rjaLzcffhGUH4nt4fyfAg",
  "controller": [
      "did:cheqd:mainnet:5rjaLzcffhGUH4nt4fyfAg"
  ],
  "verification_method": [
      {
          "id": "did:cheqd:mainnet:5rjaLzcffhGUH4nt4fyfAg#key-1",
          "verification_method_type": "Ed25519VerificationKey2020",
          "controller": "did:cheqd:mainnet:5rjaLzcffhGUH4nt4fyfAg",
          "verification_material": "z6MkpqEAYo7Ri8WYt6Kx4efLQdVJNgh4QzDf8ptVxJoexXdx"
      },
      {
          "id": "did:cheqd:mainnet:5rjaLzcffhGUH4nt4fyfAg#key-2",
          "verification_method_type": "Ed25519VerificationKey2020",
          "controller": "did:cheqd:mainnet:5rjaLzcffhGUH4nt4fyfAg",
          "verification_material": "z6MkqX2qR3rvt9UQpXsaYKFqGjX79ooFfwhhpZo8HfVXiDMP"
      },
  ],
  "authentication": [
            "did:cheqd:mainnet:5rjaLzcffhGUH4nt4fyfAg#key-1"
        ],
  "capability_delegation": [
            "did:cheqd:mainnet:5rjaLzcffhGUH4nt4fyfAg#key-2"
        ],
}

Verification method representation on-ledger

Example of how cheqd-node stores verification_method

  1. id (string): A string with format did:cheqd:<namespace>#<key-alias>

  2. controller: A string with fully qualified DID. DID must exist.

  3. verification_method_type (string): A string that represents type of verification method. Supported: Ed25519VerificationKey2018, Ed25519VerificationKey2020, JsonWebKey2020.

  4. verification_material (string): It represents the exact decoded string value of public key for the verification method. Supported types of public key representations are: publicKeyBase58, publicKeyMultibase, publicJwk.

Service representation on-ledger

{
  "id":"did:cheqd:mainnet:5rjaLzcffhGUH4nt4fyfAg#linked-domain",
  "service_type": "LinkedDomains",
  "service_endpoint": [
    "https://foo.example.com"
  ]
}

## DID transactions

### Create DID and DIDDoc

This operation creates a new DID using the `did:cheqd` method along with associated DID Document representation.

- **`signatures`**: `CreateDidDocRequest` should be signed by all `controller` private keys. This field contains a `dict` structure with the key URI from `DIDDoc.authentication`, as well as signature values.
- **`id`**: Fully qualified DID of type `did:cheqd:<namespace>`.
- **`context, controller, verificationMethod, authentication, assertionMethod, capabilityInvocation, capabilityDelegation, keyAgreement, service, alsoKnownAs, versionId`**: Optional parameters in accordance with DID Core specification properties.

#### Client request format for create DID

```jsonc
WriteRequest (CreateDidRequest(context, id, controller, verificationMethod, authentication, assertionMethod, capabilityInvocation, capabilityDelegation, keyAgreement, service, alsoKnownAs, versionId), signatures)

Example of a create DID client request

WriteRequest{
  "data": 
    "CreateDidDocRequest" {   
      "context": [
          "https://www.w3.org/ns/did/v1",
          "https://w3id.org/security/suites/ed25519-2020/v1"
      ],
      "id": "did:cheqd:mainnet:N22N22KY2Dyvmuu2",
      "controller": ["did:cheqd:mainnet:N22N22KY2Dyvmuu2"],
      "verificationMethod": [
        {
          "id": "did:cheqd:mainnet:N22N22KY2Dyvmuu2#authKey1",
          "type": "Ed25519VerificationKey2020", // external (property value)
          "controller": "did:cheqd:mainnet:N22N22KY2Dyvmuu2",
          "publicKeyMultibase": "z4BWwfeqdp1obQptLLMvPNgBw48p7og1ie6Hf9p5nTpNN"
        }
      ],
      "authentication": ["did:cheqd:mainnet:N22N22KY2Dyvmuu2#authKey1"],
      "versionId": "c4ffc8de-8bf9-4c6b-9457-3c5ee13c40c9",
  },
  "signatures": {
      "Verification Method URI": "<signature>"
      // Multiple verification methods and corresponding signatures can be added here
  }
}

Update DID

This operation updates the DID Document associated with an existing DID of type did:cheqd:<namespace>.

  • signatures: UpdateDidRequest should be signed by all controller private keys. This field contains a dict structure with the key URI from DIDDoc.authentication, as well as signature values.

  • id: Fully qualified DID of type did:cheqd:<namespace>.

  • versionId: Transaction hash of the previous DIDDoc version. This is necessary to provide replay protection. The previous DIDDoc versionId can fetched using a get DID query.

  • controller, verificationMethod, authentication, assertionMethod, capabilityInvocation, capabilityDelegation, keyAgreement, service, alsoKnownAs, context: Optional parameters in accordance with DID Core specification properties.

Client request format for update DIDDoc

WriteRequest(UpdateDidDocRequest(context, id, controller, verificationMethod, authentication, assertionMethod, capabilityInvocation, capabilityDelegation, keyAgreement, service, alsoKnownAs, versionId), signatures)

Example of an update DID client request

WriteRequest{
  "data": 
    "UpdateDidRequest" {   
      "context": [
          "https://www.w3.org/ns/did/v1",
          "https://w3id.org/security/suites/ed25519-2020/v1"
      ],
      "id": "did:cheqd:mainnet:N22N22KY2Dyvmuu2",
      "controller": ["did:cheqd:mainnet:N22N22KY2Dyvmuu2"],
      "verificationMethod": [
        {
          "id": "did:cheqd:mainnet:N22N22KY2Dyvmuu2#capabilityInvocationKey",
          "type": "Ed25519VerificationKey2020", // external (property value)
          "controller": "did:cheqd:mainnet:N22N22N22KY2Dyvmuu2",
          "publicKeyMultibase": "z4BWwfeqdp1obQptLLMvPNgBw48p7og1ie6Hf9p5nTpNN"
        }
      ],
      "authentication": ["did:cheqd:mainnet:N22N22KY2Dyvmuu2#authKey1"],
      "versionId": "1049f853-d4fb-46b7-84e2-3f0770e98907"
  },
  "signatures": {
      "Verification Method URI": "<signature>"
      // Multiple verification methods and corresponding signatures can be added here
  }
}

Deactivate DID

This operation deactivates the DID for a given did:cheqd:<namespace>. Once deactivated, a DID cannot be re-activated or any DIDDoc update operations carried out.

  • id: Fully qualified DID of type did:cheqd:<namespace>.

  • signatures: DeactivateDidDocRequest should be signed by all controller private keys. This field contains controller key URIs and signature values.

Client request format for deactivate DID

WriteRequest (DeactivateDidDocRequest(id), signatures)

Example of a deactivate DID client request

WriteRequest {
  "data": 
    "DeactivateDidDocRequest" {   
      "id": "did:cheqd:mainnet:5rjaLzcffhGUH4nt4fyfAg",
    },
  "signatures": {
      "Verification Method URI": "<signature>"
      // Multiple verification methods and corresponding signatures can be added here
  }
}

Get/Resolve DID

DIDDocs associated with a DID of type did:cheqd:<namespace> can be resolved using the GetDidDoc query to fetch a response from the ledger. The response contains:

Client request format for get/resolve DID

DID resolution requests can be sent to the Tendermint RPC interface for a node by passing the fully-qualified DID.

QueryGetDidDocResponse(did)

Example of an get/resolve DID client request

  "didDocument": {
    "id": "did:cheqd:mainnet:76d28343-ee38-44b5-b098-72c08ea0f9c1",
    "verification_method": [ {
      "id": "did:cheqd:mainnet:76d28343-ee38-44b5-b098-72c08ea0f9c1#key1",
            "verification_method_type": "Ed25519VerificationKey2018",
            "controller": "did:cheqd:mainnet:76d28343-ee38-44b5-b098-72c08ea0f9c1",
            "verification_material": "B38Mt4DXaPxq2SxejqTbEEfQFYX9TmTgJyyoELoUMoCB"
        }
    ],
    "authentication": [
        "did:cheqd:mainnet:76d28343-ee38-44b5-b098-72c08ea0f9c1#key1"
    ]
},
"didDocumentMetadata": {
    "created": "2023-01-16T13:09:18.995088591Z",
    "updated": "2023-01-16T13:09:20.123096781Z",
    "deactivated": false,
    "version_id": "c4ffc8de-8bf9-4c6b-9457-3c5ee13c40c9",
    "previous_version_id": "57e760fd-6b9c-4da8-aabc-48c65a32ace3",
    "next_version_id": ""
} 

Considerations

Security considerations

  1. For creating a new DID or update the DIDDoc associated with an existing DID, the requested should be signed by all controller signatures.

    1. To update a DIDDoc fragment without a controller (any field except VerificationMethods), the request MUST be signed by the DID's controller(s).

    2. To update a DIDDoc fragment that has its own controller(s), the request MUST be signed by the DID's controller(s) and the DIDDoc fragment's controller(s).

  2. Changing the controller(s) associated with a DID requires a list of signatures as before for changing any field.

Privacy Considerations

One of the key design decisions in the cheqd DID method is to use separate sets of key pairs for Cosmos / node layer transactions and identity payloads.

Keypairs and accounts on the Cosmos node layer are public, and can be crawled/explored by inspecting transactions on a node or through a block explorer. This therefore poses a privacy risk through correlation, if the identity payloads were signed using the same keys.

By splitting the keys/accounts for the two layers, we account for identity payloads being signed using keys that can be kept off-ledger.

This also allows for uses cases where the key owners/controllers at the identity layer are different than the key/account owners at the Cosmos node layer. In essence, that this allows is it removes the need for a DID's controllers to also have an account on the cheqd network ledger.

Changes from Indy entities and transactions

Rename NYM transactions to DID transactions

NYM is the term used by Hyperledger Indy for DIDs. cheqd uses the term DID instead of NYM in transactions, which should make it easier to understand the context of a transaction easier by bringing it closer to W3C DID terminology used by the rest of the SSI ecosystem.

Removing role field from DID transactions

Hyperledger Indy is a public-permissioned distributed ledger and therefore use the role field to distinguish transactions from different types of nodes. As cheqd networks are public-permissionless, the role scope has been removed.

ATTRIB transactions dropped

ATTRIB was originally used in Hyperledger Indy to add document content similar to DID Documents (DIDDocs). The cheqd DID method replaces this by implementing DIDDocs for most transaction types.

Included resource metadata within DIDDoc metadata

Decision

Identity entities and transactions for the cheqd network may differ in name from those in Hyperledger Indy, but aim enable equivalent support for privacy-respecting SSI use cases.

With better compliance against the DID Core specification, the goal of the cheqd DID method is to maximise interoperability with compatible third-party software librarires, tools and projects in the SSI ecosystem.

Consequences

Backward Compatibility

  • The cheqd DID method does not aim to be 1:1 compatible in API methods with did:indy. It makes opinionated choices to not implement certain transaction types, which in our analysis have been superseded by new developments in the W3C DID Core specification.

  • Support for Indy-style DID unique identifiers is intended to provide a compatibility mode with existing Indy-based client applications.

Positive

  • Design decisions defined in this ADR aim to make the cheqd DID method compliant with the W3C DID Core specification.

  • Usage of UUID-style identifiers significantly simplifies the generation and implementation of unique identifiers, since any client application can generate these UUIDs using their own preferred implementation in any programming language, as opposed to the method-specific logic required for Indy-style DID identifiers.

Negative

  • Trying to maintain backwards-compatibility with Hyperledger Indy APIs means some functionality will not be available for legacy client applications which cannot support non-Indy DID Document elements, e.g., multiple verification methods in the same DIDDoc.

Neutral

  • DID transaction operations at the moment must be assembled using a client-side library with DID specification identity standards support, and then wrapped up inside a Cosmos transaction that is sent to the Tendermint RPC or Cosmos SDK gRPC interface. We aim to build client apps/SDKs that can be used by developers to make the process of interacting with the ledger simpler.

References

Since the core of Hyperledger Indy's architecture was designed before the started to be defined, the (did:indy) has aspects that are not fully-compliant with latest specifications.

However, the were primarily down to the following reasons:

Limitations of Hyperledger Indy's consensus mechanism: Linked to the permissioned nature of Indy are the drawbacks of its mechanism, which effectively limits the number of nodes with write capability to approximately 25 nodes. This limit is due to limited transactions per second (TPS) for an Indy network with a large number of nodes, rather than a hard cap implemented in the consensus protocol.

By selecting the Cosmos blockchain framework, the maintainers of the cheqd project aim to address the limitations of Hyperledger Indy outlined above. However, with an eye towards interoperability, the cheqd project aims to use for ledger-related peer-to-peer interactions.

Our aim is to support the functionality enabled by into cheqd-node. This will partly enable the goal of allowing use cases of existing SSI networks on Hyperledger Indy to be supported by the cheqd network.

Schemas and Credential Definitions are also not covered under the scope of this ADR. Their implementation is covered in .

A did:cheqd DID must be unique. The syntax of the unique-id component may be defined as a generated by the creator(s) of the DID. UUIDs are the preferred unique identifier format for cheqd network.

Usage of UUID-style identifiers significantly simplifies the generation and implementation of unique identifiers, is generated independently.

Alternatively, from the initial public key of the DID (e.g., base58 encoding of the first 16 bytes of the SHA256 of the first Verification Method Ed25519 public key). This unique-id format is referred to as the "Indy-style" unique identifier in our documentation.

Support for Indy-style unique identifiers makes compatibility with Indy-based client SDKs, such as those based on .

The cheqd DID method ABNF to conform with is as follows:

Where the :

A DID Document ("DIDDoc") associated with a cheqd DID is a set of data describing a DID subject. The from a DID on cheqd networks MUST meet the DID Core specifications.

resources (list of resources metadata referred to as )| optional. Cannot be changed by CreateDID or UpdateDID transactions. cheqd ledger stores only the resource identifiers in the DID Doc metadata. The remainder of the resources' metadata is added when a DID is resolved.

publicKeyJwk (map[string,string], optional): A map representing a JSON Web Key that conforms to . See definition of publicKeyJwk for additional constraints.

publicKeyMultibase (optional): A base58-encoded string that conforms to a encoded public key.

id (string): The value of the id property for a Service MUST be a URI conforming to . A conforming producer MUST NOT produce multiple service entries with the same ID. A conforming consumer MUST produce an error if it detects multiple service entries with the same ID. It has a follow formats: <DIDDoc-id>#<service-alias> or #<service-alias>.

type (string): The service type and its associated properties SHOULD be registered in the

serviceEndpoint (list of strings): A string that conforms to the rules of for URIs, a map, or a set composed of a one or more strings that conform to the rules of for URIs and/or maps.

did_doc: DIDDoc associated with the specified DID in a W3C specification compliant .

metadata: Contains the MUST have associated with a DIDDOc.

The response is returned as a , which can be converted to JSON client-side.

Further discussion on how these boundaries are separated in implementation, with one specific implementation library, is described in

To support the , cheqd ledger includes a reference to resource previews within the DIDDoc metadata.

The differences stem primarily from aiming to achieve better compliance with the W3C specification and architectural differences between Hyperledger Indy and (used to build cheqd-node).

cheqd-node and earlier had a transaction type called NYM which would allow writing/reading a unique identifier on ledger. However, this NYM state was not fully defined as a DID method and did not store DID Documents associated with a DID. This NYM transaction type is deprecated and the data written to cheqd testnet with legacy states will not be retained.

As the client/peer-to-peer exchange layer (at least in the implementation provided by ) is built on a library that supports Hyperledger Aries, extending Aries implementations to other W3C compliant DID methods should become simpler for the SSI ecosystem.

official project background on Hyperledger Foundation wiki

GitHub repository: Server-side blockchain node for Indy ()

GitHub repository: Plenum Byzantine Fault Tolerant consensus protocol; used by indy-node ()

(did:indy)

official project background on Hyperledger Foundation wiki

GitHub repository: Provides links to implementations in various programming languages

GitHub repository: Contains Requests for Comment (RFCs) that define the Aries protocol behaviour

specification

official project website

GitHub repository ()

: Sovrin Network token library

đŸ—ī¸
đŸ”ĩ
Cosmos blockchain framework
Decentralized identifiers
Sovrin Network
libsovtoken
last official release in August 2019
W3C DID specification
Indy DID Method
rationale for why the cheqd team chose the Cosmos blockchain framework instead of Hyperledger Indy
Plenum Byzantine Fault Tolerant (BFT) consensus
Hyperledger Aries
identity-domain transactions in by Hyperledger Indy
ADR 002: DID-Linked Resources
Universally Unique Identifier (UUID)
with extremely-low probability of a collission where the same UUID
the unique-id may also be generated similar to the did:indy method
Hyperledger Aries
DID syntax guidelines
formal definition of UUIDs is represented using this ABNF
representation of a DIDDoc when requested for production
Resource previews
RFC7517
MULTIBASE
RFC3986
DID Specification Registries
RFC3986
RFC3986
DIDDoc structure
DIDDoc metadata
Protobuf
cheqd node ADR 003: Command Line Interface (CLI) tools
cheqd Resource Module
DID Core
Cosmos SDK
release v0.1.19
VDR Tools SDK
Hyperledger Indy
indy-node
documentation
indy-plenum
documentation
Indy DID method
Indy identity-domain transactions
Hyperledger Aries
aries
aries-rfcs
W3C Decentralized Identifiers (DIDs)
DID Core Specification Test Suite
Cosmos blockchain framework
cosmos-sdk
documentation
Sovrin Foundation
Sovrin Networks
libsovtoken
Sovrin Ledger token plugin