Create an ION DID
Introduction
The Identity Overlay Network (ION) DID method establishes an efficient way to anchor the public DID document to the Bitcoin ledger. It relies on a protocol known as Sidetree, to effectively batch transactions before writing to the ledger. This solves the thorny issue of lengthening transaction times on this particular ledger and, by batching, the system's nodes are able to write many hundreds of thousands of DID documents to the ledger in a single transaction.
The ION DID method is being championed by the likes of Microsoft, and relies on several novel technologies including IPFS, Sidetree protocol & employs proof-of-work schemes. By using this method on the MATTR VII platform you gain the benefits of using the DID method through a simple interface and private key management.
Constraints
Due to the batching nature of the nodes, a newly created DID may take between 20 minutes to 2 hours to become fully publicly available. This has impacts on some of the operations you can perform on the MATTR VII platform, for example configuring the OIDC Bridge Issuer DID will be blocked until the ION DID is publicly resolvable.
Note: The creation of ION DIDs during a trial of the MATTR VII platform may be subject to change. As you move into production workloads please get in touch to discuss your needs.
Create DID and DID Document
A DID with a DID method of ION can be created as follows.
1POST https://YOUR_TENANT_URL/v1/dids
Request
1{
2 "method": "ion"
3}
The method
is set to ion
in order to create a DID with a DID method of ION.
This call will initiate the ION nodes to batch the DID document, as well as creating the associated private key and store it in the KMS. The default key type ed25519
Response
1{
2 "did": "did:ion:EiBbvWpBHPql_2W9sObr4vPFl9k9InEDYOEDXvPPRDRyBg",
3 "registrationStatus": "PROCESSING",
4 "localMetadata": {
5 "keys": [
6 {
7 "kmsKeyId": "a21fc9ff-1d67-4d76-a02c-d4524acc1685",
8 "didDocumentKeyId": "did:ion:EiBbvWpBHPql_2W9sObr4vPFl9k9InEDYOEDXvPPRDRyBg#z6MkvvCxe4mL1ghEEgKL"
9 },
10 {
11 "kmsKeyId": "fa4672d1-e833-42e6-8a55-a0da956c2c4c",
12 "didDocumentKeyId": "did:ion:EiBbvWpBHPql_2W9sObr4vPFl9k9InEDYOEDXvPPRDRyBg#z6LSnqJCx9BnhEShY1uC"
13 },
14 {
15 "kmsKeyId": "63b1525e-20a7-4026-b323-a114a66b58e7",
16 "authorizedDidOperations": [
17 "Recover"
18 ]
19 },
20 {
21 "kmsKeyId": "92f6f4f4-5e46-41f4-a336-88fad589b6b5",
22 "authorizedDidOperations": [
23 "Update"
24 ]
25 }
26 ],
27 "registered": 1628811763535,
28 "initialDidDocument": {
29 "id": "did:ion:EiBbvWpBHPql_2W9sObr4vPFl9k9InEDYOEDXvPPRDRyBg",
30 "@context": [
31 "https://www.w3.org/ns/did/v1",
32 {
33 "@base": "did:ion:EiBbvWpBHPql_2W9sObr4vPFl9k9InEDYOEDXvPPRDRyBg"
34 }
35 ],
36 "keyAgreement": [
37 "#z6LSnqJCx9BnhEShY1uC"
38 ],
39 "authentication": [
40 "#z6MkvvCxe4mL1ghEEgKL"
41 ],
42 "assertionMethod": [
43 "#z6MkvvCxe4mL1ghEEgKL"
44 ],
45 "verificationMethod": [
46 {
47 "id": "#z6MkvvCxe4mL1ghEEgKL",
48 "type": "JsonWebKey2020",
49 "controller": "",
50 "publicKeyJwk": {
51 "x": "9KIvHIY9zI9TZtrpdx4AIxfsZArbLDKhs3-PBlNLX34",
52 "crv": "Ed25519",
53 "kty": "OKP"
54 }
55 },
56 {
57 "id": "#z6LSnqJCx9BnhEShY1uC",
58 "type": "JsonWebKey2020",
59 "controller": "",
60 "publicKeyJwk": {
61 "x": "pca-6GiWWYRSys1U2j5I6gqq7olyJw0M3aqZcuHsST0",
62 "crv": "X25519",
63 "kty": "OKP"
64 }
65 }
66 ],
67 "capabilityDelegation": [
68 "#z6MkvvCxe4mL1ghEEgKL"
69 ],
70 "capabilityInvocation": [
71 "#z6MkvvCxe4mL1ghEEgKL"
72 ]
73 }
74 }
75}
When first creating the ION DID it will return the response: "registrationStatus": "PROCESSING",
This indicates that the document has been sent to the nodes for batching.
In our testing the service that registers the DID Document can take between 20 minutes and up to 2 hours before the document is anchored and publicly available.
The returned initialDidDocument
will be the document that is anchored to the ledger and made publicly available.
Anatomy of the DID Document
ION DIDs have chosen to reference attributes using only the fragment hash #
nomenclature e.g.
1"authentication": [
2 "#z6MkvvCxe4mL1ghEEgKL"
3]
Which references
1{
2 "id": "#z6MkvvCxe4mL1ghEEgKL",
3 "type": "JsonWebKey2020",
4 "controller": "",
5 "publicKeyJwk": {
6 "x": "9KIvHIY9zI9TZtrpdx4AIxfsZArbLDKhs3-PBlNLX34",
7 "crv": "Ed25519",
8 "kty": "OKP"
9 }
10}
Check status
Checking the registration status can be achieved using the retrieve DID endpoint.
1GET https://YOUR_TENANT_URL/v1/dids/did:ion:EiABhoVuB1ORgFuZlZP0Cg9WhZWUIg4S1APBxeNTL5z_iw
1{
2 "didDocument": {
3 "id": "did:ion:EiBbvWpBHPql_2W9sObr4vPFl9k9InEDYOEDXvPPRDRyBg",
4 "@context": [
5 "https://www.w3.org/ns/did/v1",
6 {
7 "@base": "did:ion:EiBbvWpBHPql_2W9sObr4vPFl9k9InEDYOEDXvPPRDRyBg"
8 }
9 ],
10 "verificationMethod": [
11 {
12 "id": "#z6MkvvCxe4mL1ghEEgKL",
13 "controller": "",
14 "type": "JsonWebKey2020",
15 "publicKeyJwk": {
16 "kty": "OKP",
17 "crv": "Ed25519",
18 "x": "9KIvHIY9zI9TZtrpdx4AIxfsZArbLDKhs3-PBlNLX34"
19 }
20 },
21 {
22 "id": "#z6LSnqJCx9BnhEShY1uC",
23 "controller": "",
24 "type": "JsonWebKey2020",
25 "publicKeyJwk": {
26 "kty": "OKP",
27 "crv": "X25519",
28 "x": "pca-6GiWWYRSys1U2j5I6gqq7olyJw0M3aqZcuHsST0"
29 }
30 }
31 ],
32 "authentication": [
33 "#z6MkvvCxe4mL1ghEEgKL"
34 ],
35 "assertionMethod": [
36 "#z6MkvvCxe4mL1ghEEgKL"
37 ],
38 "capabilityDelegation": [
39 "#z6MkvvCxe4mL1ghEEgKL"
40 ],
41 "capabilityInvocation": [
42 "#z6MkvvCxe4mL1ghEEgKL"
43 ],
44 "keyAgreement": [
45 "#z6LSnqJCx9BnhEShY1uC"
46 ]
47 },
48 "registrationStatus": "COMPLETED",
49 "localMetadata": {
50 "keys": [
51 {
52 "kmsKeyId": "a21fc9ff-1d67-4d76-a02c-d4524acc1685",
53 "didDocumentKeyId": "did:ion:EiBbvWpBHPql_2W9sObr4vPFl9k9InEDYOEDXvPPRDRyBg#z6MkvvCxe4mL1ghEEgKL"
54 },
55 {
56 "kmsKeyId": "fa4672d1-e833-42e6-8a55-a0da956c2c4c",
57 "didDocumentKeyId": "did:ion:EiBbvWpBHPql_2W9sObr4vPFl9k9InEDYOEDXvPPRDRyBg#z6LSnqJCx9BnhEShY1uC"
58 },
59 {
60 "kmsKeyId": "63b1525e-20a7-4026-b323-a114a66b58e7",
61 "authorizedDidOperations": [
62 "Recover"
63 ]
64 },
65 {
66 "kmsKeyId": "92f6f4f4-5e46-41f4-a336-88fad589b6b5",
67 "authorizedDidOperations": [
68 "Update"
69 ]
70 }
71 ],
72 "registered": 1628811763535,
73 "initialDidDocument": {
74 "id": "did:ion:EiBbvWpBHPql_2W9sObr4vPFl9k9InEDYOEDXvPPRDRyBg",
75 "@context": [
76 "https://www.w3.org/ns/did/v1",
77 {
78 "@base": "did:ion:EiBbvWpBHPql_2W9sObr4vPFl9k9InEDYOEDXvPPRDRyBg"
79 }
80 ],
81 "keyAgreement": [
82 "#z6LSnqJCx9BnhEShY1uC"
83 ],
84 "authentication": [
85 "#z6MkvvCxe4mL1ghEEgKL"
86 ],
87 "assertionMethod": [
88 "#z6MkvvCxe4mL1ghEEgKL"
89 ],
90 "verificationMethod": [
91 {
92 "id": "#z6MkvvCxe4mL1ghEEgKL",
93 "type": "JsonWebKey2020",
94 "controller": "",
95 "publicKeyJwk": {
96 "x": "9KIvHIY9zI9TZtrpdx4AIxfsZArbLDKhs3-PBlNLX34",
97 "crv": "Ed25519",
98 "kty": "OKP"
99 }
100 },
101 {
102 "id": "#z6LSnqJCx9BnhEShY1uC",
103 "type": "JsonWebKey2020",
104 "controller": "",
105 "publicKeyJwk": {
106 "x": "pca-6GiWWYRSys1U2j5I6gqq7olyJw0M3aqZcuHsST0",
107 "crv": "X25519",
108 "kty": "OKP"
109 }
110 }
111 ],
112 "capabilityDelegation": [
113 "#z6MkvvCxe4mL1ghEEgKL"
114 ],
115 "capabilityInvocation": [
116 "#z6MkvvCxe4mL1ghEEgKL"
117 ]
118 }
119 }
120}
The didDocument
as resolved from the ION node is returned in the response.
The "registered"
field now includes a Unix timestamp in ms.
Resolve DID Document
Once registration is complete the DID document can be resolved outside of the platform, a simple method to do this is using the DIF Universal Resolver (note: this service is not operated by MATTR).
ZKP Enabled ION DID
ION DIDs can also be created with a bls12381g2
key type, DIDs containing this key can then be used to create ZKP-enabled verifiable credentials.
Using the same Create DID endpoint:
1POST https://YOUR_TENANT_URL/v1/dids
Request
Include an options
body with the BLS key type.
1{
2 "method": "ion",
3 "options": {
4 "keyType": "bls12381g2"
5 }
6}
Response
1{
2 "did": "did:ion:EiDj2a9m5LGjT1sUZ7uNtgu4hDukTpUYmqDQpjwo5D5yhw",
3 "registrationStatus": "PROCESSING",
4 "localMetadata": {
5 "keys": [
6 {
7 "didDocumentKeyId": "did:ion:EiDj2a9m5LGjT1sUZ7uNtgu4hDukTpUYmqDQpjwo5D5yhw#zUC76grJYJ2PgnV9awfH",
8 "kmsKeyId": "e9eff366-4a4e-4e7a-b9dc-b9e75f449065"
9 },
10 {
11 "didDocumentKeyId": "did:ion:EiDj2a9m5LGjT1sUZ7uNtgu4hDukTpUYmqDQpjwo5D5yhw#z6LSqPrtC9FqEZbiCE3J",
12 "kmsKeyId": "7d6346b0-1ef0-482d-af0e-a29ac0631217"
13 },
14 {
15 "kmsKeyId": "b9587492-15bc-4a4d-bdfa-bea410557fa6",
16 "authorizedDidOperations": [
17 "Recover"
18 ]
19 },
20 {
21 "kmsKeyId": "b8f9eaf6-d2ac-4cd2-a6be-ad260cbc2406",
22 "authorizedDidOperations": [
23 "Update"
24 ]
25 }
26 ],
27 "registered": 1629174954651,
28 "initialDidDocument": {
29 "id": "did:ion:EiDj2a9m5LGjT1sUZ7uNtgu4hDukTpUYmqDQpjwo5D5yhw",
30 "@context": [
31 "https://www.w3.org/ns/did/v1",
32 {
33 "@base": "did:ion:EiDj2a9m5LGjT1sUZ7uNtgu4hDukTpUYmqDQpjwo5D5yhw"
34 }
35 ],
36 "verificationMethod": [
37 {
38 "id": "#zUC76grJYJ2PgnV9awfH",
39 "controller": "",
40 "type": "JsonWebKey2020",
41 "publicKeyJwk": {
42 "kty": "OKP",
43 "crv": "Bls12381G2",
44 "x": "kLaKCUJ5IxaLVplYGq3MOjo9wouzk5zYm9lqj04QORcRMF8Zko6a8LnLG7U6zgI9AgEKPNfiDV7KWLqOL0868WaQeZS6g0T3sca3tPJZAP6dNLo1VgS6l6m5afT5pTde"
45 }
46 },
47 {
48 "id": "#z6LSqPrtC9FqEZbiCE3J",
49 "controller": "",
50 "type": "JsonWebKey2020",
51 "publicKeyJwk": {
52 "kty": "OKP",
53 "crv": "X25519",
54 "x": "y9WnKvE68IJ1OHC3Dn6nG8nr0Kx7D0R5rUKKZamQV1o"
55 }
56 }
57 ],
58 "authentication": [
59 "#zUC76grJYJ2PgnV9awfH"
60 ],
61 "assertionMethod": [
62 "#zUC76grJYJ2PgnV9awfH"
63 ],
64 "capabilityDelegation": [
65 "#zUC76grJYJ2PgnV9awfH"
66 ],
67 "capabilityInvocation": [
68 "#zUC76grJYJ2PgnV9awfH"
69 ],
70 "keyAgreement": [
71 "#z6LSqPrtC9FqEZbiCE3J"
72 ]
73 }
74 }
75}
The resulting DID can now be used to create credentials, either directly , using OpenID Provisioning or via the OIDC Bridge that will result in them being ZKP-enabled.
For ION DIDs that use a bls12381g2
key type, there are limitations on other actions that can be performed with the DID.
Message encryption is possible by specifying the appropriate
keyAgreement
keyMessage signing is not possible at this time using DIDs that contain
bls12381g2
keys.