Skip to main content

DIDs

Learn how to work with DIDs.

DIDs, short for Decentralized Identifiers, are commonly used in decentralized identity ecosystems as a way to identify issuers, holders, and verifiers. On this page you'll learn more about what they are, what kinds of DIDs are supported, and how to handle DIDs with Procivis One.

What is a DID

A DID is a type of globally unique identifier for a resource. It's similar to a URL and can be resolved to a DID document which offers metadata about the identified resource. Because a DID is typically created in association with a public/private key pair, the controller of the private key is able to prove control of the DID and thus authenticate themselves.

For a deep dive on DIDs, see the DIDs concept article.

Supported DID methods

did:web

did:web specification

The did:web method uses an existing web domain through which to create DIDs: the method-specific identifier of the DID is an actual domain name secured by a TLS certificate and resolvable through HTTPS via the Domain Name System (DNS). DIDs are thus hosted on the web and you resolve them by making web calls.

No Distributed Ledger Technology (DLT) is required.

did:webvh

did:webvh info page (includes specification)

Formerly called did:tdw, did:webvh uses the same DID-to-HTTPS transformation as did:web but adds a "verifiable history" component via a DID Log.

The DID Log is ledger-like in that it includes an entry for the DID creation and each update to the DID after that. The log is not kept on Distributed Ledger Technology (DLT) but is instead hosted in a jsonl file which can be resolved by verifiers by converting the DID address to a fully qualified domain name (FQDN) secured by a TLS/SSL certificate. Each log entry is secured with a Data Integrity proof, making the log tamper-resistant and cryptographically verifiable.

Other notable features of this method include:

  • SCID: when creating the first log entry, a preliminary entry is created with a {SCID} placeholder but other data such as the keys to be used in place. The hash of this preliminary entry is then calculated and becomes the SCID, a "self-certifying identifier". The method-specific identifier of the DID is then a combination of the SCID and the domain name.
  • DID witness: the DID can contain a list of witnesses who are tasked with monitoring and approving each update to the DID.
  • Key pre-rotation: a DID controller can commit to use a new authorization key in the next log entry, each time they update the DID. This mechanism prevents an attacker from using a compromised key to rotate to a new key under their own control.
  • /whois: DID controllers can optionally host another path that contains a verifiable presentation containing verifiable credentials, each with the DID as the credentialSubject and each signed by the DID. This allows verifiers to gain verifiable data about the DID controller upon DID resolution.

Implementation

The system supports the following elements of v0.3:

  • DID creation
  • DID resolution, including verification of the DID Log.

For DID creation, use ECDSA keys.

When you create the DID, the system automatically creates an Ed25519 key to generate a Data Integrity proof of the DID Log. This key is placed in the updateKeys field of the DID document.

note

Version 0.3 of the standard uses did:tdw as the method name.

Full support of the method is in development.

DID structure

Created DIDs have the following structure:

did:tdw:{{SCID}}:{{BASE-URL}}:ssi:did-webvh:v1:{{DID ID}}

Custom hosting URL

By default the DID Logs are hosted at:

{{BASE-URL}}/ssi/did-webvh/v1/{{DID ID}}/did.jsonl

To set a custom external host:

  1. Use the params when creating the DID:

{
"method": "WEBVH",
"name": "My webvh DID",
"keys": {
"authentication": [
"{{MY-AUTH-KEY}}"
],
...
},
"params": { "externalHostingUrl": "{{MY-HOST-URL}}"}
}
  1. Integrate a method for uploading the DID Document. The system does not currently support automatic uploading.

did:key

did:key specification

The did:key method starts with a public key and encodes it into a DID. When the DID is resolved, the public key is decoded and expanded into the DID document. DIDs of this type are immutable: updating or deactivating them is not possible.

No Distributed Ledger Technology (DLT) is required.

did:jwk

did:jwk specification

The did:jwk method starts with a JSON Web Key (JWK) and encodes it into a DID. When the DID is resolved, the public key is decoded and expanded into the DID document. DIDs of this type are immutable: updating or deactivating them is not possible.

No Distributed Ledger Technology (DLT) is required.

did:mdl

The did:mdl method is not a registered DID method, but is used by the system to enable flexibility between credential models.

Related guide: Configure for ISO mdoc

did:sd_jwt_vc_issuer_metadata

The SD-JWT VC specification names three ways public keys can be retrieved from the iss field of a credential:

  • DID Document Resolution
  • HTTPS URI
  • X.509 Certificates

The system supports the DID Document Resolution method out-of-the-box. The other two methods can be supported by configuring an instance of did:sd_jwt_vc_issuer_metadata. This is not a registered DID method.

To enable HTTPS URI, configure an instance of did:sd_jwt_vc_issuer_metadata and ensure it is enabled. The system will then retrieve public keys from the /.well-known/jwt-vc-issuer endpoint when it encounters an iss field containing an HTTPS URI.

To enable X.509 Certificates, add the root certificate of the issuer to the params of this DID method:

SD_JWT_VC_ISSUER_METADATA:
type: 'SD_JWT_VC_ISSUER_METADATA'
params:
private:
iacaCertificate: MIIDHTCCAqOgAw... // Add the issuer's root certificate here

For credentials signed by certificates, the system will verify the chain back to the specified root certificate.

Working with DIDs

DID operations

When working with DIDs in the system, you'll primarily perform these core operations:

  • Create new DIDs for entities
  • Manage DID relationships with Trust Registries
  • Deactivate DIDs that are no longer needed

For managing DID relationships with Trust Registries, see the relevant Trust Registry guide.

Create a DID

To create a DID, you must provide:

  • a DID name (unique within the organization)
  • the DID method
  • a keys object

When passing the DID method, you must reference the configuration instance of your chosen DID method. Retrieve the configuration and check the did object for supported methods, their instance names, and which operations are supported for that method.

Keys object

Each DID document specifies the verification methods (that is, keys) for the DID subject.

  • authentication: Used to identify and authenticate the DID subject
  • assertionMethod: Used to express claims, such as in issuing a credential
  • keyAgreement: Used to establish confidential communications with the DID subject
  • capabilityInvocation: Used to invoke a capability the DID subject has, such as access to update the DID document
  • capabilityDelegation: Used to delegate a capability to another party

When you create a DID, you must specify a key (by its UUID) for each method.

While some DID methods only allow one key for all verification methods, other methods allow for different keys to be specified for the different purposes described above. In these cases, the verifier can check that the verification method being presented in a proof for authentication, for example, is the same verification method contained in the authentication relationship.

Currently did:webis the only supported DID method that supports multiple keys in the keys object.

For DID methods which don't support multiple verification methods, the same key must be passed for all verification methods. For DID methods supporting multiple verification methods, different keys can be passed for each method.

The configuration determines the minimum and maximum number of keys specifiable for each DID and each verification method. For example:

"did": {
"WEB": {
...
"params": {
"keys": { // In this configuration, DIDs of type did:web:
"min": 1, // Require at least one key
"max": 5, // And at most 5
"authentication": {
"min": 0, // For authentication, no key is required
"max": 2 // At most 2 keys can be specified for authentication
},
"assertionMethod": {
"min": 1, // At least one key must be specified for assertion
"max": 2 // and so on...
},
"keyAgreement": {
"min": 1,
"max": 1
},
"capabilityInvocation": {
"min": 1,
"max": 1
},
"capabilityDelegation": {
"min": 1,
"max": 1
}
}
}
}
}

Deactivate a DID

caution

DID deactivation is permanent.

DID deactivation is useful if, for instance, a private key is leaked.

Currently, only did:web supports deactivation.

Resolve a DID

DID resolver operations

The system resolves DIDs whenever it needs public keys to verify a proof, but you can also resolve a DID by using the /api/did-resolver/v1/:did endpoint.

The endpoint accepts a DID address (not the system UUID of the DID) and resolves it to its DID document.