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 a DID-Linked Resource
        • Resolve a DID-Linked Resource
        • Create an AnonCreds Schema
        • Create an AnonCreds Credential Definition
      • Verifiable Credentials and Presentations
        • AnonCreds
          • Issue a Verifiable Credential
          • Present a Verifiable Credential
        • JSON-LD
          • Issue a Verifiable Credential
          • Present a Verifiable Credential
        • SD-JWT VC
          • Issue a Verifiable Credential
          • Present a Verifiable Credential
    • 🍊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
      • 2025
        • 3.1.x
        • 4.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
  • Resolve function
  • Resolve Representation function
  • Architecture of DID Resolver for cheqd
  • Full cheqd DID Resolver
  • Decision
  • Universal Resolver driver for did:cheqd
  • Configuration properties for Universal Resolver driver
  • Consequences
  • Backwards Compatibility
  • Positive
  • Negative
  • Neutral
  • References

Was this helpful?

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

ADR 003: DID Resolver

Architecture Decision Record (ADR) detailing cheqd's implementation of its DID Resolver.

Last updated 1 month ago

Was this helpful?

Status

Category
Status

Authors

Alex Tweeddale, Renata Toktar, Ankur Banerjee, Andrew Nikitin

ADR Stage

ACCEPTED

Implementation Status

Implemented

Start Date

2022-02-22

Last Updated

2023-04-25

Summary

The defines how DIDs are created and read from ledger. According to the , DID methods are expected to provide .

The is designed to implement the for method.

Context

The DID Resolution specification prescribes that a conforming DID method must be able to produce.

All conforming DID resolvers implement resolve and resolveRepresentation abstract functions, as defined in the .

Resolve function

The resolve function is intended to fetch the abstract form of the DID Document, as stored on the ledger. This abstract/raw form as the underlying data persistence layer where the DIDDoc is stored for any particular method might use different serialisation/storage formats.

resolve(did, resolutionOptions) →
ÂĢ didResolutionMetadata, didDocument, didDocumentMetadata Âģ

Cosmos SDK framework typically provides gRPC/gRPC-Web, JSON-RPC, and REST API endpoints for on-ledger modules and functionality.

For example, did:cheqd:testnet:DAzMQo4MDMxCjgwM can be fetched using the native Cosmos SDK REST API endpoint (or equivalent endpoints). This provides responses that would meet the abstract definition of a resolve function as defined in the DID Core specification.

{
  "value": {
    "did_doc": {
      "context": [
      ],
      "id": "did:cheqd:testnet:97e351e6-2d9d-4314-82ec-e0d12bc5de43",
      "controller": [
        "did:cheqd:testnet:97e351e6-2d9d-4314-82ec-e0d12bc5de43"
      ],
      "verification_method": [
        {
          "id": "did:cheqd:testnet:97e351e6-2d9d-4314-82ec-e0d12bc5de43#key-1",
          "verification_method_type": "JsonWebKey2020",
          "controller": "did:cheqd:testnet:97e351e6-2d9d-4314-82ec-e0d12bc5de43",
          "verification_material": "{\"crv\":\"Ed25519\",\"kty\":\"OKP\",\"x\":\"q8-CHj4_nIYo8tK5RdjYbXlsTUnwW_i4gIEclps2i2o\"}"
        }
      ],
      "authentication": [
        "did:cheqd:testnet:97e351e6-2d9d-4314-82ec-e0d12bc5de43#key-1"
      ],
      "assertion_method": [
      ],
      "capability_invocation": [
      ],
      "capability_delegation": [
      ],
      "key_agreement": [
      ],
      "service": [
      ],
      "also_known_as": [
      ]
    },
    "metadata": {
      "created": "2023-03-01T08:47:07.919899771Z",
      "updated": "2023-03-01T08:52:27.785774183Z",
      "deactivated": false,
      "version_id": "cfe2f51f-8ec5-4fd8-8ab9-61859de879f4",
      "next_version_id": "",
      "previous_version_id": "482feb56-1de8-4c36-bc00-a15a4188bccc"
    }
  }
}

As you can see in the response body above, this is the raw Protobuf fetched from the cheqd testnet ledger, marshalled into a JSON form. Crucially, this form has certain deviations from the JSON/JSON-LD production expected in DID Core specification:

  1. DID Core properties with empty values are still shown in this JSON, whereas the requirement is to drop them from standards-compliant DIDDoc representations.

Resolve Representation function

resolveRepresentation(did, resolutionOptions) →
ÂĢ didResolutionMetadata, didDocumentStream, didDocumentMetadata Âģ

For example, a resolveRepresentation function could derive a valid standards-compliant representation of did:cheqd:testnet:ea2b76cf-a118-403a-8f49-244e56c9dcb8 from the above resolve function. The response would be similar to the one below containing Resolution Metadata, DIDDoc, and DIDDoc Metadata:

{
  "didResolutionMetadata": {
    "contentType": "application/did+ld+json",
    "retrieved": "2022-08-03T09:52:49Z",
    "did": {
      "didString": "did:cheqd:testnet:ea2b76cf-a118-403a-8f49-244e56c9dcb8",
      "methodSpecificId": "ea2b76cf-a118-403a-8f49-244e56c9dcb8",
      "method": "cheqd"
    }
  },
  "didDocument": {
    "id": "did:cheqd:testnet:ea2b76cf-a118-403a-8f49-244e56c9dcb8",
    "verificationMethod": [
      {
        "id": "did:cheqd:testnet:ea2b76cf-a118-403a-8f49-244e56c9dcb8#key1",
        "type": "Ed25519VerificationKey2020",
        "controller": "did:cheqd:testnet:ea2b76cf-a118-403a-8f49-244e56c9dcb8",
        "publicKeyMultibase": "z6jVkB274neVf7iJETpMECwznBF8wDe8tpvF4BZLRZgMU"
      }
    ],
    "authentication": ["did:cheqd:testnet:ea2b76cf-a118-403a-8f49-244e56c9dcb8#key1"]
  },
  "didDocumentMetadata": {
    "created": "2022-07-19T08:29:07Z",
    "versionId": "a0a4f3a3-829d-4188-bc78-8bea6a522037",
    "linkedResourceMetadata": [
      {
        "resourceURI": "did:cheqd:testnet:ea2b76cf-a118-403a-8f49-244e56c9dcb8/resources/44547089-170b-4f5a-bcbc-06e46e0089e4",
        "resourceCollectionId": "ea2b76cf-a118-403a-8f49-244e56c9dcb8",
        "resourceId": "44547089-170b-4f5a-bcbc-06e46e0089e4",
        "resourceName": "DemoResource",
        "resourceType": "CL-Schema",
        "mediaType": "application/json",
        "created": "2022-07-19T08:40:00Z",
        "checksum": "7b2022636f6e74656e74223a202274657374206461746122207d0ae3b0c44298",
        "previousVersionId": "", // empty string if no previous version, otherwise, resourceId of previous version
        "nextVersionId": "" // empty string if no new version, otherwise, resourceId of new version
      }
    ]
  }
}

Architecture of DID Resolver for cheqd

This objective has certain advantages:

  • Updates to DID Resolver code can be carried out and released independently of cheqd-node releases. As a consequence, there's no need to go through an on-ledger governance vote, and voting period to make a change to resolveRepresentation.

  • A separate web service module would allow for flexibility in how to handle complex scenarios on DID URL Dereferencing, error code handling for DID URL requests, and safely handling content transport for various media types.

  • Making the DID Resolver a standalone, non-ledger module allows for an operator of this web service to independently scale their service horizontally and vertically.

We explored two architectural patterns for how a DID Resolver could be implemented for the cheqd ledger. The objective here was to explore and provide DID resolution operators multiple approaches for running resolution service, each with their own pros and cons (which are discussed below).

  1. "Full" cheqd DID Resolver

    1. Data retrieved would be in the native Protobuf representation as stored on ledger, thus allowing data integrity computations to be made.

  2. "Light" cheqd DID Resolver

    1. However, a limitation of Cloudflare Workers is they do not allow a gRPC request to be made to an external endpoint. This would force the "Light" cheqd Resolver to use the gRPC-Web / REST endpoint resolve implementation to fetch data from the ledger. This could be considered a higher risk profile in terms of data integrity by resolver operators / client applications.

Full cheqd DID Resolver

The Full cheqd DID Resolver is able to use github.com/cheqd/cheqd-node as a Golang module for send resolve requests to a cheqd node instance to fetch DIDDoc / Resources from the ledger.

Since the Full cheqd DID Resolver is wrapped for usage as a Docker container image using the Universal Resolver specification, the end-to-end sequence diagram for our DID Resolver would look like below:

The Full cheqd DID Resolver is designed to handle requests concurrently, while reducing the risk of large quantities of threads and requests blocking the efficiency of the on-ledger services.

Fetching Protobuf from ledger and converting it to JSON

Figure 2: "Full" cheqd DID Resolver class diagram

Marshalling/unmarshalling requests back-and-forth between Protobuf and JSON is carried out by services in the "Full" DID Resolver

Decision

Given the drawbacks associated with a Light cheqd DID Resolver being unable to send gRPC requests to a cheqd node instance, the decision was taken to (initially) implement the Full cheqd DID Resolver architecture. Future work might separately consider and design a Light DID Resolver profile that can work with Cloudflare Workers while also allowing deployment through Docker.

Universal Resolver driver for did:cheqd

Configuration properties for Universal Resolver driver

  1. Operators should be able to configure gRPC endpoints for mainnet as as testnet (or any other cheqd network namespaces) so that a single DID Resolver instance can resolve requests to any network. (E.g., grpc.cheqd.netfor mainnet, grpc.cheqd.network for testnet)

  2. For each supported cheqd network namespace (e.g., mainnet, testnet), operators should be able to define one or more upstream cheqd node gRPC endpoints. (E.g., additional fallback endpoints besides grpc.cheqd.net for mainnet.) In case any one of the upstream endpoints is unavailable, this allows the DID Resolver to try a different upstream gRPC endpoint for resiliency.

  3. Operators should be able to define whether their gRPC pull/request is secure (default, carried out over HTTP.2 with TLS handshake) or insecure (optional, equivalent to a grpcurl -plaintext connection downgrade). This accommodates scenarios where gRPC endpoints may not necessarily be equipped to handle TLS handshakes, since the default Cosmos SDK / cheqd node configuration endpoints do not have TLS certificates defined.

Consequences

Backwards Compatibility

  1. Not applicable, since this would be the first release of cheqd DID Resolver

Positive

  1. Full cheqd DID Resolver reuses existing code to handle some parts of resolve and representing DIDDocs.

  2. Third-party applications that want to implement their own DID Resolver implementations for cheqd can consume the current implementation as a Golang module (e.g., import "github.com/cheqd/cheqd-did-resolver/services").

  3. Universal Resolver driver implementation provides a standardised way of incorporating did:cheqd into Universal Resolver instances that support multiple DID methods.

Negative

Neutral

  1. Lack of a Light cheqd DID Resolver, at least initially, might not give an easy and computationally-cheap alternative to running Docker containers.

References

Since , the underlying data storage and retrieval ("resolve") mechanisms used rely on those offered by the . Cosmos SDK uses Protobuf (Protocol Buffers) encoding for its wire protocol.

In case of the cheqd network testnet, an instance of this resolve endpoint through the Cosmos SDK REST API would be which returns the following response:

JSON key names that correlate to DID Core properties are listed in , rather than as required. This is because Protobuf standard linting rules require these properties to be defined in snake_case.

The resolveRepresentation abstract function, as defined in DID Core specification, is intended to address concerns similar to the ones highlighted above to product a of a DIDDoc.

As described above, the abstract resolve function is already available for the cheqd ledger via the default Cosmos SDK gRPC/REST API endpoints. Our primary objective with building a DID Resolver for cheqd was to design this resolveRepresentation piece as a standalone component that was not packaged within the .

Since the / Cosmos SDK is written in Golang, this resolver would consist of Golang libraries imported from the existing ledger code. This promotes code reuse.

Data would be fetched from the ledger using the gRPC endpoint on a node, which allows it (by default) to take place over an encrypted channel .

Universal Resolver drivers are designed to be run as Docker containers. A limitation of this approach is that the computation footprint of a compute resource can be quite high, e.g., a Docker container may be 100 MB+ in size and .

Thus, our "Light" DID Resolver idea was to explore using , a lightweight serverless compute platform. As a comparison, and . (We use Cloudflare Workers in , for example.)

Cloudflare Workers can also be deployed outside the Cloudflare service in a Docker container using . This could be used to provide a Docker container deployment option for the Universal Resolver did:cheqd driver.

Both of the architectural patterns above are designed so that a could be created. The Universal Resolver project aims to provide a common REST API definition for DID Resolution where each DID method can provide a Docker container that with an easy-to-deploy mechanism for the specific DID method.

Figure 1: "Full" cheqd DID Resolver sequence diagram ()

Since Cosmos SDK SDK encodes data in Protobuf, the DID Resolver "" them to JSON. The software class diagram below describes how these components/methods are tied together:

Figure 3: "Full" cheqd DID Resolver Protobuf <-> JSON marshalling ()

Compiled packages/binaries for the Full cheqd DID Resolver will be made available as a Docker container image with standardised Docker Compose configuration as defined in the to provide an easy mechanism for DID Resolution operators to incorporate did:cheqd as one of the supported DID methods they handle.

Use of a custom DID URL path (e.g., /1.0/identifiers/{did}/resources/{resource-id} can be non-standard). Efforts should be made to see if this can implemented instead using DID URL queries according to the .

recommendation

specification

guide

đŸ—ī¸
🟡
did:cheqd method ADR
W3C DID Core specification
standards-compliant methods of DID and DID Document ("DIDDoc") production
cheqd DID Resolver
W3C DID Resolution specification
did:cheqd
a defined algorithm with standardised behaviour for expected and unexpected inputs
DID Resolution specification
may not necessarily be in JSON/JSON-LD format
cheqd uses the Cosmos SDK blockchain framework
Cosmos SDK framework
api.cheqd.network/cheqd/did/v2/did:cheqd:testnet:97e351e6-2d9d-4314-82ec-e0d12bc5de43
snake_case
camelCase
standards-compliant JSON/JSON-LD representation
cheqd-node ledger code
cheqd-node ledger
since gRPC uses HTTP/2
suffer from slow startup times in a "cold-start" scenario
Cloudflare Workers
Cloudflare Workers are limited to 1 MB in size
have extremely low cold-start times
our Cosmos SDK Custom Data API
Miniflare
Universal Resolver driver for did:cheqd
editable version
marshalls
editable version
Universal Resolver driver development guide
Trust over IP Foundation "DID URL Resource Parameter" specification
W3C Decentralized Identifiers (DIDs)
W3C Decentralized Identifier Resolution (DID Resolution)
Universal Resolver driver development
DID Core Specification Test Suite
Full cheqd DID Resolver sequence diagram
Full cheqd DID Resolver class diagram
Full cheqd DID Resolver Protobuf <-> JSON marshalling