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.

http
Copy to clipboard.
1POST https://YOUR_TENANT_URL/v1/dids

Request

json
Copy to clipboard.
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

json
Copy to clipboard.
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.

json
Copy to clipboard.
1"authentication": [
2    "#z6MkvvCxe4mL1ghEEgKL"
3]

Which references

json
Copy to clipboard.
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.

http
Copy to clipboard.
1GET https://YOUR_TENANT_URL/v1/dids/did:ion:EiABhoVuB1ORgFuZlZP0Cg9WhZWUIg4S1APBxeNTL5z_iw
json
Copy to clipboard.
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).

https://www.datocms-assets.com/38428/1630036381-dif-uniresolver-ion.png?auto=format

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:

http
Copy to clipboard.
1POST https://YOUR_TENANT_URL/v1/dids

Request

Include an options body with the BLS key type.

json
Copy to clipboard.
1{
2  "method": "ion",
3  "options": {
4      "keyType": "bls12381g2"
5  }
6}

Response

json
Copy to clipboard.
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 key

  • Message signing is not possible at this time using DIDs that contain bls12381g2 keys.