4 releases

0.2.1 Sep 20, 2024
0.2.0 Jul 26, 2024
0.1.1 Mar 8, 2023
0.1.0 Dec 16, 2022

#5 in #self-sovereign-identity

Download history 925/week @ 2024-08-11 734/week @ 2024-08-18 798/week @ 2024-08-25 826/week @ 2024-09-01 1301/week @ 2024-09-08 1448/week @ 2024-09-15 1584/week @ 2024-09-22 928/week @ 2024-09-29 930/week @ 2024-10-06 659/week @ 2024-10-13 848/week @ 2024-10-20 802/week @ 2024-10-27 695/week @ 2024-11-03 752/week @ 2024-11-10 858/week @ 2024-11-17 673/week @ 2024-11-24

3,044 downloads per month
Used in 22 crates (7 directly)

Apache-2.0 and maybe GPL-3.0

585KB
12K SLoC

DID Methods.

This library provides Decentralized Identifiers (DIDs), a type of identifier defined by the W3C that enables verifiable, self-sovereign digital identities. Unlike traditional identifiers, such as email addresses or usernames, DIDs are not tied to a central authority. Instead, they are generated and managed on decentralized networks like blockchains, providing greater privacy, security, and control to the individual or entity that owns them.

Each DID is an URI using the did scheme. This library uses the [DID] and DIDBuf (similar to [str] and String) to parse and store DIDs.

use ssi_dids::{DID, DIDBuf};

// Create a `&DID` from a `&str`.
let did = DID::new("did:web:w3c-ccg.github.io:user:alice").unwrap();

// Create a `DIDBuf` from a `String`.
let owned_did = DIDBuf::from_string("did:web:w3c-ccg.github.io:user:alice".to_owned()).unwrap();

Just like regular URLs, it is possible to provide the DID with a fragment part. The result is a DID URL, which can be parsed and stored using DIDURL and DIDURLBuf.

use ssi_dids::{DIDURL, DIDURLBuf};

// Create a `&DIDURL` from a `&str`.
let did_url = DIDURL::new("did:web:w3c-ccg.github.io:user:alice#key").unwrap();

// Create a `DIDBuf` from a `String`.
let owned_did_url = DIDURLBuf::from_string("did:web:w3c-ccg.github.io:user:bob#key".to_owned()).unwrap();

Note that a DID URL, with a fragment, is not a valid DID.

DID document resolution

DID resolution is the process of retrieving the DID document associated with a specific DID. A DID document is a JSON-LD formatted file that contains crucial information needed to interact with the DID, such as verification methods containing the user's public keys, and service endpoints. Here is an example DID document:

{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    "https://w3id.org/security/suites/jws-2020/v1"
  ],
  "id": "did:jwk:eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwieCI6ImFjYklRaXVNczNpOF91c3pFakoydHBUdFJNNEVVM3l6OTFQSDZDZEgyVjAiLCJ5IjoiX0tjeUxqOXZXTXB0bm1LdG00NkdxRHo4d2Y3NEk1TEtncmwyR3pIM25TRSJ9",
  "verificationMethod": [
    {
      "id": "did:jwk:eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwieCI6ImFjYklRaXVNczNpOF91c3pFakoydHBUdFJNNEVVM3l6OTFQSDZDZEgyVjAiLCJ5IjoiX0tjeUxqOXZXTXB0bm1LdG00NkdxRHo4d2Y3NEk1TEtncmwyR3pIM25TRSJ9#0",
      "type": "JsonWebKey2020",
      "controller": "did:jwk:eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwieCI6ImFjYklRaXVNczNpOF91c3pFakoydHBUdFJNNEVVM3l6OTFQSDZDZEgyVjAiLCJ5IjoiX0tjeUxqOXZXTXB0bm1LdG00NkdxRHo4d2Y3NEk1TEtncmwyR3pIM25TRSJ9",
      "publicKeyJwk": {
        "crv": "P-256",
        "kty": "EC",
        "x": "acbIQiuMs3i8_uszEjJ2tpTtRM4EU3yz91PH6CdH2V0",
        "y": "_KcyLj9vWMptnmKtm46GqDz8wf74I5LKgrl2GzH3nSE"
      }
    }
  ],
  "assertionMethod": ["did:jwk:eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwieCI6ImFjYklRaXVNczNpOF91c3pFakoydHBUdFJNNEVVM3l6OTFQSDZDZEgyVjAiLCJ5IjoiX0tjeUxqOXZXTXB0bm1LdG00NkdxRHo4d2Y3NEk1TEtncmwyR3pIM25TRSJ9#0"],
  "authentication": ["did:jwk:eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwieCI6ImFjYklRaXVNczNpOF91c3pFakoydHBUdFJNNEVVM3l6OTFQSDZDZEgyVjAiLCJ5IjoiX0tjeUxqOXZXTXB0bm1LdG00NkdxRHo4d2Y3NEk1TEtncmwyR3pIM25TRSJ9#0"],
  "capabilityInvocation": ["did:jwk:eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwieCI6ImFjYklRaXVNczNpOF91c3pFakoydHBUdFJNNEVVM3l6OTFQSDZDZEgyVjAiLCJ5IjoiX0tjeUxqOXZXTXB0bm1LdG00NkdxRHo4d2Y3NEk1TEtncmwyR3pIM25TRSJ9#0"],
  "capabilityDelegation": ["did:jwk:eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwieCI6ImFjYklRaXVNczNpOF91c3pFakoydHBUdFJNNEVVM3l6OTFQSDZDZEgyVjAiLCJ5IjoiX0tjeUxqOXZXTXB0bm1LdG00NkdxRHo4d2Y3NEk1TEtncmwyR3pIM25TRSJ9#0"],
  "keyAgreement": ["did:jwk:eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwieCI6ImFjYklRaXVNczNpOF91c3pFakoydHBUdFJNNEVVM3l6OTFQSDZDZEgyVjAiLCJ5IjoiX0tjeUxqOXZXTXB0bm1LdG00NkdxRHo4d2Y3NEk1TEtncmwyR3pIM25TRSJ9#0"]
}

DID documents are represented using the Document type and can be resolved from a DID using any implementation of the DIDResolver trait. The AnyDidMethod type is provided as a default implementation for DIDResolver that supports various DID methods (see below).

use ssi_dids::{DID, AnyDidMethod, DIDResolver};

// Create a DID.
let did = DID::new("did:jwk:eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwieCI6ImFjYklRaXVNczNpOF91c3pFakoydHBUdFJNNEVVM3l6OTFQSDZDZEgyVjAiLCJ5IjoiX0tjeUxqOXZXTXB0bm1LdG00NkdxRHo4d2Y3NEk1TEtncmwyR3pIM25TRSJ9").unwrap();

// Setup the DID resolver.
let resolver = AnyDidMethod::default();

// Resolve the DID document (equal to the example document above).
let document = resolver.resolve(did).await.unwrap().document;

// Extract the first verification method.
let vm = document.verification_method.first().unwrap();

Instead of resolving a DID document and extracting verification methods manually, you can use the dereference method to resolve a DID URL:

use ssi_dids::{DIDURL, AnyDidMethod, DIDResolver};

// Create a DID URL with the fragment `#0` referencing a verification method.
let did_url = DIDURL::new("did:jwk:eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwieCI6ImFjYklRaXVNczNpOF91c3pFakoydHBUdFJNNEVVM3l6OTFQSDZDZEgyVjAiLCJ5IjoiX0tjeUxqOXZXTXB0bm1LdG00NkdxRHo4d2Y3NEk1TEtncmwyR3pIM25TRSJ9#0").unwrap();

// Setup the DID resolver.
let resolver = AnyDidMethod::default();

// Dereference the verification method.
let vm = resolver
  .dereference(did_url)
  .await
  .unwrap()
  .content
  .into_verification_method()
  .unwrap();

DID methods

A key component of the DID system is the concept of DID methods. A DID method defines how a specific type of DID is created, resolved, updated, and deactivated on a particular decentralized network or ledger. Each DID method corresponds to a unique identifier format and a set of operations that can be performed on the associated DIDs. The general syntax of DIDs depends on the method used:

did:method:method-specific-id

There exists various DID methods, each defined by their own specification. In this library, methods are defining by implementing the DIDMethod trait. Implementations are provided for the following methods:

The AnyDidMethod regroups all those methods into one DIDResolver implementation.

DID method types can also be used to generate fresh DID URLs:

use ssi_jwk::JWK;
use ssi_dids::DIDJWK;

/// Generate a new JWK.
let jwk = JWK::generate_p256();

/// Generate a DID URL out of our JWK URL.
let did_url = DIDJWK::generate_url(&jwk);

Dependencies

~27–45MB
~756K SLoC