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
3,161 downloads per month
Used in 22 crates
(7 directly)
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:
did:key
: for static cryptographic keys, implemented byDIDKey
.did:jwk
: for Json Web Keys (JWK) implemented byDIDJWK
.did:web
: for web-hosted DID documents, implemented byDIDWeb
.did:pkh
: implemented byDIDPKH
.did:ethr
: implemented byDIDEthr
.did:ion
: implemented byDIDION
.did:tz
: implemented byDIDTz
.
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