@digitalbazaar/did-method-web
v1.0.1
Published
A did:web method resolver.
Downloads
12,759
Readme
did:web method driver (@digitalbazaar/did-method-web)
A DID (Decentralized Identifier) method driver for the
did-io
library and for standalone use
Table of Contents
Background
See also (related specs):
A did:web
method driver for the did-io
client library and for standalone use.
did:web
allows DIDs to bootstrap trust using a web domain's existing reputation.
did:web
DIDs come in the following format:
did:web:<subdomain.domain%3Aport>:optional:path
The port must be percent encoded to avoid confusion with the did syntax use of :
.
So, for example, the following DID would resolve to w3c-ccg.github.io/user/alice/did.json
did:web:w3c-ccg.github.io:user:alice
That DID would correspond to the following Document:
Example DID Document
{
"@context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/suites/ed25519-2020/v1",
"https://w3id.org/security/suites/x25519-2020/v1"
],
"id": "did:web:w3c-ccg.github.io:user:alice",
"verificationMethod": [{
"id": "did:web:w3c-ccg.github.io:user:alice#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
"type": "Ed25519VerificationKey2020",
"controller": "did:web:w3c-ccg.github.io:user:alice",
"publicKeyMultibase": "z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"
}],
"authentication": [
"did:web:w3c-ccg.github.io:user:alice#z6Mkpw72M9suPCBv48X2Xj4YKZJH9W7wzEK1aS6JioKSo89C"
],
"assertionMethod": [
"did:web:w3c-ccg.github.io:user:alice#z6Mkpw72M9suPCBv48X2Xj4YKZJH9W7wzEK1aS6JioKSo89C"
],
"capabilityDelegation": [
"did:web:w3c-ccg.github.io:user:alice#z6Mkpw72M9suPCBv48X2Xj4YKZJH9W7wzEK1aS6JioKSo89C"
],
"capabilityInvocation": [
"did:web:w3c-ccg.github.io:user:alice#z6Mkpw72M9suPCBv48X2Xj4YKZJH9W7wzEK1aS6JioKSo89C"
],
"keyAgreement": [{
"id": "did:web:w3c-ccg.github.io:user:alice#z6LSj72tK8brWgZja8NLRwPigth2T9QRiG1uH9oKZuKjdh9p",
"type": "X25519KeyAgreementKey2020",
"controller": "did:web:w3c-ccg.github.io:user:alice",
"publicKeyMultibase": "z6LSj72tK8brWgZja8NLRwPigth2T9QRiG1uH9oKZuKjdh9p"
}]
}
Security
did:web
has security issues outlined in the security section of the specification.
This DID method does not specify any authentication or authorization mechanism for writing to, removing or creating the DID Document, leaving it up to implementations to protect did:web documents as with any other web resource.
It is up to implementer to secure their web environments according to industry best practices for updating or otherwise managing web content based on the specific needs of their threat environment.
Install
Requires Node.js 18+
To install from npm
:
npm install --save @digitalbazaar/did-method-web
To install locally (for development):
git clone https://github.com/digitalbazaar/did-method-web.git
cd did-method-web
npm install
Usage
fromKeyPair()
A new did:web
DID Document can be generated from an existing key pair:
import {driver} from '@digitalbazaar/did-method-web';
import {Ed25519VerificationKey2020} from
'@digitalbazaar/ed25519-verification-key-2020';
import {X25519KeyAgreementKey2020} from
'@digitalbazaar/x25519-key-agreement-key-2020';
// create a driver with the desired key support
const didWebDriver = driver();
didWebDriver.use({
multibaseMultikeyHeader: 'z6Mk',
fromMultibase: Ed25519VerificationKey2020.from
});
didWebDriver.use({
multibaseMultikeyHeader: 'z6LS',
fromMultibase: X25519KeyAgreementKey2020.from
});
/* similarly, ECDSA or BBS (Bls12381G2) can be used:
import * as Bls12381Multikey from '@digitalbazaar/bls12-381-multikey';
import * as EcdsaMultikey from '@digitalbazaar/ecdsa-multikey';
didWebDriver.use({
multibaseMultikeyHeader: 'zDna',
fromMultibase: EcdsaMultikey.from
});
didWebDriver.use({
multibaseMultikeyHeader: 'zUC7',
fromMultibase: Bls12381Multikey.from
});
*/
// generate did:web DID doc from an Ed25519 key pair and X25519 key pair
const publicKeyMultibaseForVerificationKeyPair =
'z6MknCCLeeHBUaHu4aHSVLDCYQW9gjVJ7a63FpMvtuVMy53T';
const keyPairForVerification = await Ed25519VerificationKey2020.from({
publicKeyMultibase: publicKeyMultibaseForVerificationKeyPair
});
const publicKeyMultibaseForKeyAgreementKeyPair =
'z6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc';
const keyPairForKeyAgreement = await X25519KeyAgreementKey2020.from({
publicKeyMultibase: publicKeyMultibaseForKeyAgreementKeyPair
});
const {
didDocument, keyPairs, methodFor
} = await didWebDriver.fromKeyPair({
// the desired `did:web` DID URL
url: 'did:web:w3c-ccg.github.io:user:alice',
// either one or both of these key pairs must be provided
verificationKeyPair: keyPairForVerification,
keyAgreementKeyPair: keyPairForKeyAgreement
});
// print the DID Document above
console.log(JSON.stringify(didDocument, null, 2));
// keyPairs will be set like so ->
Map(2) {
'did:web:w3c-ccg.github.io:user:alice#z6Mkpw72M9suPCBv48X2Xj4YKZJH9W7wzEK1aS6JioKSo89C' => Ed25519VerificationKey2020 {
id: 'did:web:w3c-ccg.github.io:user:alice#z6Mkpw72M9suPCBv48X2Xj4YKZJH9W7wzEK1aS6JioKSo89C',
controller: 'did:web:w3c-ccg.github.io:user:alice',
type: 'Ed25519VerificationKey2020',
publicKeyMultibase: 'z6Mkpw72M9suPCBv48X2Xj4YKZJH9W7wzEK1aS6JioKSo89C'
},
'did:web:w3c-ccg.github.io:user:alice#z6LSgxJr5q1pwHPbiK7u8Pw1GvnfMTZSMxkhaorQ1aJYWFz3' => X25519KeyAgreementKey2020 {
id: 'did:web:w3c-ccg.github.io:user:alice#z6LSgxJr5q1pwHPbiK7u8Pw1GvnfMTZSMxkhaorQ1aJYWFz3',
controller: 'did:web:w3c-ccg.github.io:user:alice',
type: 'X25519KeyAgreementKey2020',
publicKeyMultibase: 'z6LSgxJr5q1pwHPbiK7u8Pw1GvnfMTZSMxkhaorQ1aJYWFz3'
}
}
methodFor
is a convenience function that returns a public key pair
instance for a given purpose. For example, a verification key (containing a
verifier()
function) is frequently useful for
jsonld-signatures
or
vc
operations. After generating
a new did:web
DID, you can do:
// for verifying Verifiable Credentials
const assertionKeyPair = methodFor({purpose: 'assertionMethod'});
// for verifying authorization Capabilities (zCaps)
const invocationKeyPair = methodFor({purpose: 'capabilityInvocation'});
// for encryption to a recipient using `@digitalbazaar/minimal-cipher`
const keyAgreementPair = methodFor({purpose: 'keyAgreement'});
Note that methodFor
returns a key pair that contains a public key pair.
This makes it useful for verifying and encrypting operations.
get()
Getting a full DID Document from a did:web
DID
To get a DID Document for an existing did:web
DID:
const did = 'did:web:w3c-ccg.github.io:user:alice';
const didDocument = await didWebDriver.get({did});
(Results in the example DID Doc above).
Backwards Compatibility with legacy key expressions
A did:web
driver can be configured to return whatever key expression is
desirable, including legacy key expressions. For example, you can create a
driver that will return an Ed25519VerificationKey2018
formatted key when
an ed25519
key is detected:
import {
Ed25519VerificationKey2018
} from '@digitalbazaar/ed25519-verification-key-2018';
import * as didWeb from '@digitalbazaar/did-method-web';
const didWebDriver2018 = didWeb.driver();
didWebDriver2018.use({
multibaseMultikeyHeader: 'z6Mk',
fromMultibase: Ed25519VerificationKey2018.from
});
const did = 'did:web:w3c-ccg.github.io:user:alice:2018';
await didWebDriver2018.get({url: did});
// ->
{
'@context': [
'https://www.w3.org/ns/did/v1',
'https://w3id.org/security/suites/ed25519-2018/v1',
'https://w3id.org/security/suites/x25519-2019/v1'
],
id: 'did:web:w3c-ccg.github.io:user:alice:2018',
verificationMethod: [{
id: 'did:web:w3c-ccg.github.io:user:alice:2018#z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH',
type: 'Ed25519VerificationKey2018',
controller: 'did:web:w3c-ccg.github.io:user:alice:2018',
publicKeyBase58: 'B12NYF8RrR3h41TDCTJojY59usg3mbtbjnFs7Eud1Y6u'
}],
// etc,
keyAgreement: [{
id: 'did:web:w3c-ccg.github.io:user:alice:2018#z6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc',
type: 'X25519KeyAgreementKey2019',
controller: 'did:web:w3c-ccg.github.io:user:alice:2018',
publicKeyBase58: 'JhNWeSVLMYccCk7iopQW4guaSJTojqpMEELgSLhKwRr'
}]
}
Allow List
This driver allows you to restrict the domains it will generate and resolve for.
To do this pass the parameter allowList
to either DidWebDriver
or the driver
function.
import {DidWebDriver, driver} from '@digitalbazaar/did-method-web';
const allowList = ['safe-domain.org', 'localhost:46443'];
const restrictedDriver = new DidWebDriver({allowList});
// call `restrictedDriver.use()` with supported key types and then ...
// this will always fail
const failedGenerate = await restrictedDriver.get({
url: 'did:web:unsafe-domain.net'
});
// this can succeed
const successfulGenerate = await restrictedDriver.get({
url: 'did:web:safe-domain.org'
});
fetchOptions
This library resolves HTTP requests using implementations of fetch
.
The following apis will accept a fetchOptions
parameter: DidWebDriver
, driver
, and driver.get
.
import {DidWebDriver, driver} from '@digitalbazaar/did-method-web';
// accept really large DID documents
const fetchOptions = {size: 81920000};
const driver = new driver({fetchOptions});
const fetchOptions2 = {redirect: 'follow'};
const did = 'did:web:safe-domain.org';
// this will spread `fetchOptions2` over `fetchOptions`
const didDocument = await driver.get({url: did, fetchOptions: fetchOptions2})
Helper Functions
In addition to the did:web
driver, this package also exports several helper
functions for working with did:web
DIDs.
To convert a did:web
URL to its corresponding HTTPS URL:
import {didUrlToHttpsUrl} from '@digitalbazaar/did-method-web';
const didUrl = 'did:web:w3c-ccg.github.io:user:alice';
const httpsUrl = didUrlToHttpsUrl(did);
// https://w3c-ccg.github.io/user/alice/did.json
To convert an HTTPS URL to its corresponding did:web
DID URL
import {httpsUrlToDidUrl} from '@digitalbazaar/did-method-web';
const httpsUrl = 'https://w3c-ccg.github.io/user/alice/did.json'
const didUrl = httpsUrlToDidUrl(url);
// did:web:w3c-ccg.github.io:user:alice
Contribute
See the contribute file!
PRs accepted.
If editing the Readme, please conform to the standard-readme specification.
Commercial Support
Commercial support for this library is available upon request from Digital Bazaar: [email protected]
License
New BSD License (3-clause) © Digital Bazaar