generated from w3c-ccg/markdown-to-spec
-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.bs
1027 lines (800 loc) · 41.1 KB
/
index.bs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<pre class='metadata'>
Title: DID-Linked Resources
Shortname: DID-Linked Resources
Level: 1
Status: w3c/CG-DRAFT
Group: w3c-ccg
URL: https://w3c-ccg.github.io/did-linked-resources
Editor: Alex Tweeddale, https://github.com/Tweeddalex
Abstract: This specification creates a standardized way of referencing, dereferencing, and fetching digital resources. This includes associating digital resources with Decentralized Identifiers (DIDs) and organizing digital resources into DID-Linked Collections, where each individual resource is identifiable through its own DID URL.
</pre>
Introduction {#intro}
=====================
DID-Linked Resources are digital files that can be retrieved and referenced using a persistent and unique DID URL.
This specification defines common requirements, patterns, algorithms including their request formats and response formats, architectural options, and various considerations for how DID-Linked Resources SHOULD act as persistent identifiers for referencing and retrieving digital Resources (such as data schemas, status lists, trust registries, governance documents, or policy definitions). This specification complements the <a href="https://w3c-ccg.github.io/did-resolution/">DID Resolution Specification</a>, including its patterns and algorithms for DID URL resolution and dereferencing.
By using DID URLs which remain conformant with W3C Decentralized Identifiers (DIDs) v1.0 Recommendation [[DID-CORE]] and the <a href="https://w3c-ccg.github.io/did-resolution/">DID Resolution Specification</a>, existing DID Resolvers will be able to dereference these DID URLs to retrieve the identified resources using the DID URL query syntax in this specification.
<div class="note"> <b>Note:</b> while this specification defines some base-level functionality for DID URL dereferencing, the actual steps required to communicate with a DID's verifiable data registry are defined by the applicable DID method specification. </div>
Conformance {#conformance}
---------------------
In addition to sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MAY, MUST, MUST NOT, OPTIONAL, and SHOULD in this document are to be interpreted as described in BCP 14 [[RFC2119]] [[RFC8174]] when, and only when, they appear in all capitals, as shown here.
Terminology {#terminology}
=====================
<dfn>DID controller</dfn>: As defined in [[DID-CORE]].
<dfn>DID document</dfn>: As defined in [[DID-CORE]].
<dfn>DID URL</dfn>: As defined in [[DID-CORE]].
<dfn>DID URL Dereferencing</dfn>: As defined in [[DID-CORE]].
<dfn>DID-Linked Resource</dfn>: Digital files that can be retrieved and referenced using persistent and unique DID URLs.
<dfn>Resource Collection</dfn>: An organized and structured set of digital resources, collectively and individually identifiable using persistent and unique DID URLs.
<dfn>Resource ID</dfn>: A unique identifier for a specified DID-Linked Resource.
DID-Linked Resources {#resources}
=====================
This section explains the context for building DID-Linked Resources, as well as their fundamental components for construction.
DID-Linked Resources context {#context}
---------------------
The [[DID-CORE]] specification defines an interoperable standard for DID documents and associated core properties, however it does not currently have a standardized way to specify properties of Resources associated with DIDs, nor how to consistently reference nor retrieve them.
Digital Resources are generally stored on traditional centralized-storage endpoints, but this comes with certain drawbacks:
1. <b>Digital Resources could be tampered with by compromising the hosting provider</b>: Digital Resources stored at a centralized web endpoint can be compromised and replaced by malicious actors.
2. <b>Hosting providers could unilaterally cease to host particular clients</b>: Hosting providers could terminate accounts due to factors such as non-payment of fees, violation of Terms of Service, etc.
3. <b><a href="https://dbpedia.org/resource/Single_point_of_failure">Single point of failure (SPOF)</a></b>: Even with highly-trusted and sophisticated hosting providers who may not present a risk of infrastructure being compromised, a service outage at the hosting provider can make a Resource anchored on their systems inaccessible.
Despite these issues, many decentralized identity or Digital Credential implementations, even ones that use ledgers or other distributed systems for DIDs, often utilize centralized storage. From the <a href="https://w3c.github.io/vc-imp-guide/#creating-new-credential-types">W3C Verifiable Credential Implementation Guide</a>.
Example schema.org address with full URLs:
```json
{
"@type": "http://schema.org/Person",
"http://schema.org/address": {
"@type": "http://schema.org/PostalAddress",
"http://schema.org/streetAddress": "123 Main St.",
"http://schema.org/addressLocality": "Blacksburg",
"http://schema.org/addressRegion": "VA",
"http://schema.org/postalCode": "24060",
"http://schema.org/addressCountry": "US"
}
}
```
Using traditional web endpoints to store digital resources that are critical for a Verifiable Credential to function, detracts from the proper functioning and utility that persistently-accessible Decentralized Identifiers offer. This has also resulted in inconsistent and unstandardized approaches to storing, referencing, and retrieving digital resources such as schemas, trusted issuer lists and status lists.
DID-Linked Resources construction {#contruction}
---------------------
"Resources" SHOULD be identifiable using a Decentralized Identifier (DID) and a permanently-accessible unique identifier to fetch the Resource from a Verifiable Data Registry or other storage endpoint. We refer to this identifier as the "Resource ID".
Using unique identifiers increases confidence that no two identical Resource IDs will ever be created. This is important for ensuring the integrity and unambiguity of each individual DID-Linked Resource. Throughout this specification, we will therefore use UUIDs for the Resource IDs in examples, although different method implementations may specify other Resource ID formats.
The following path-based syntax is an example of how a DID Method may construct a DID URL to point to a DID-Linked Resource:
```json
did:example:<unique-identifier>/resources/<unique-identifier>
```
<div class="note"> <b>Note:</b> The above path-based syntax would be an implementation-specific way of referencing a resource. </div>
DID-Linked Resource Collections {#collections}
---------------------
Resources are organized into groups or sets called "Collections". Each DID may have an associated Collection, and the Collection ID is derived from the unique identifier of the DID.
The most important concept used in this design is that each Collection is identified using a DID and is described using a DID document.
The DID document acts as metadata, providing information about the Collection, such as who is able to update it, when it was created, and what are the latest and/or deprecated versions of Resources within the Collection.
For example, the following DID:
```json
did:example:0a5b94d0-a417-48ed-a6f5-4abc9e95888d
```
will derive the Collection ID:
```json
0a5b94d0-a417-48ed-a6f5-4abc9e95888d
```
<div class="note"> <b>Note:</b> The Collection ID may take the syntactical form of the DID method that the DID-Linked Resource is associated with. </div>
DID-Linked Resources Algorithm {#algorithm}
=====================
To create a "DID-Linked Resource", you MUST first create a "parent" DID, from which the Collection ID can be derived, and under which the associated Resources will be linked.
Next, to create a digital Resource associated with the "parent" DID, you MUST provide the following Request inputs:
1. `resourceId`: Generate a new, unique identifier for the Resource
2. `collectionId`: Specify the Collection ID as the same unique identifier of the parent DID
3. `resourceName`: Provide a name for the Resource of your choice
4. `resourceType`: Specify the type of Resource and make reference to the DID Spec Registries to utilise consistent and registered Resource Types.
5. `data`: pass the Resource file as a path or Base64 encoded in-line.
5. Sign the transaction using the same Verification Method keys as those within the parent DID Document.
As a response, the DID Document SHOULD append metadata about the DID-Linked Resource into the existing DID Document Metadata.
```json
{
"@context": "https://w3id.org/did-resolution/v1",
"didResolutionMetadata": {
"contentType": "application/did+ld+json",
"retrieved": "2023-06-23T11:21:20Z",
"did": {
"didString": "did:example:0a5b94d0-a417-48ed-a6f5-4abc9e95888d",
"methodSpecificId": "0a5b94d0-a417-48ed-a6f5-4abc9e95888d",
"method": "example"
}
},
"didDocument": {
"@context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "did:example:0a5b94d0-a417-48ed-a6f5-4abc9e95888d",
"controller": [
"did:example:0a5b94d0-a417-48ed-a6f5-4abc9e95888d"
],
"verificationMethod": [
{
"id": "did:example:0a5b94d0-a417-48ed-a6f5-4abc9e95888d#key-1",
"type": "Ed25519VerificationKey2020",
"controller": "did:example:0a5b94d0-a417-48ed-a6f5-4abc9e95888d",
"publicKeyMultibase": "z6Mkphkdz97NJXYSbj7eGDkWR242kP58LEEkVrSseTtAzbWE"
}
],
"authentication": [
"did:example:0a5b94d0-a417-48ed-a6f5-4abc9e95888d#key-1"
],
"service": [
{
"id": "did:example:0a5b94d0-a417-48ed-a6f5-4abc9e95888d#website",
"type": "LinkedDomains",
"serviceEndpoint": [
"https://foo.com"
]
}
]
},
"didDocumentMetadata": {
"created": "2023-03-22T07:19:47Z",
"versionId": "15be3e0f-12e9-4c26-9b60-a02bf5746313",
"linkedResourceMetadata": [
{
"resourceURI": "did:example:0a5b94d0-a417-48ed-a6f5-4abc9e95888d/resources/4e1104f9-2ee9-4bde-adc2-ab8ba72b124a",
"resourceCollectionId": "0a5b94d0-a417-48ed-a6f5-4abc9e95888d",
"resourceId": "4e1104f9-2ee9-4bde-adc2-ab8ba72b124a",
"resourceName": "ExampleResource",
"resourceType": "StatusList2021Revocation",
"mediaType": "application/json",
"resourceVersion": "",
"created": "2023-03-24T12:13:45Z",
"checksum": "6819aaecd4073173b159fedf8077c38e14939d03d58e7f4e2a0ddfe034eb2ed4",
"previousVersionId": null,
"nextVersionId": null
}
]
}
}
```
Linking DIDs to Resources and Collections {#linkage}
=====================
Multiple Resources can be stored within a Collection and linked to the same DID; for example, this could be new versions of the same Resource over a period of time, or entirely different resources. This enables unique resources to be stored directly on a Verifiable Data Registry (VDR) and be retrievable through DID resolution and DID URL dereferencing.
Once you have created a resource, the DID document will automatically reference the resource and the collection within the `didDocumentMetadata` in a newly defined section called `linkedResourceMetadata`.
Architecture Overview {#archoverview}
=====================
The relationship between DIDs, Resource Collections and Resources is shown in the diagram below:
<img src="DID-Linked-Resources-Relationship.png" alt="DID-Linked Resources Architecture Overview">
Design principles {#principles}
=====================
The following design principles should be taken into consideration. DID-Linked Resources SHOULD:
1. Use existing, familiar DID Core Spec patterns where possible
2. Support existing DID Resolvers and principles of DID URL dereferencing
3. Protect against linkrot for long-term retrieval
4. Enable resources to be versioned and organized, with individual versions being able to be fetched
5. Include semantic linkage between DID documents and associated resources (via metadata or otherwise)
Resource Request Parameters {#request}
=====================
The following list defines which specific parameters are required and are optional for a request to create a resource:
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Type</th>
<th>Required?</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>"resourceCollectionId"</code></td>
<td>A <a href="https://infra.spec.whatwg.org/#string">String</a> that conforms to a unique identifier format for an associated DID method</td>
<td>Yes</td>
</tr>
<tr>
<td><code>"resourceId"</code></td>
<td>A <a href="https://infra.spec.whatwg.org/#string">String</a>, such as a UUID, that uniquely identifies the resource</td>
<td>Yes</td>
</tr>
<tr>
<td><code>"resourceName"</code></td>
<td>A <a href="https://infra.spec.whatwg.org/#string">String</a> that names and identifies a resource. This property, along with the <code>resourceType</code> below, can be used to track version changes within a resource</td>
<td>Yes</td>
</tr>
<tr>
<td><code>"resourceType"</code></td>
<td>A <a href="https://infra.spec.whatwg.org/#string">String</a> that uniquely identifies the type of resource</td>
<td>Yes</td>
</tr>
<tr>
<td><code>"resourceVersion"</code></td>
<td>A <a href="https://infra.spec.whatwg.org/#string">String</a> that identifies the version of the resource. This property, along with the <code>resourceName</code> above, can be used to track version changes within a resource</td>
<td>No</td>
</tr>
<tr>
<td><code>"alsoKnownAs"</code></td>
<td>An <a href="https://infra.spec.whatwg.org/#array">array</a> that describes alternative URIs for the resource</td>
<td>No</td>
</tr>
</tbody>
</table>
Resource Response Parameters {#response}
=====================
The following list defines which specific parameters are required and which are optional for a response, following the creation of a Resource:
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong><code>resourceUri</code></strong></td>
<td>A string or a map that conforms to the rules of <a href="https://tools.ietf.org/html/rfc3986" target="_blank">RFC3986</a> URIs which SHOULD directly lead to a location where the resource can be accessed. For example: <code>did:example:46e2af9a-2ea0-4815-999d-730a6778227c/resources/0f964a80-5d18-4867-83e3-b47f5a756f02</code>.</td>
</tr>
<tr>
<td><strong><code>resourceCollectionId</code></strong></td>
<td>A string that conforms to a method-specific supported unique identifier format. For example, a UUID: <code>46e2af9a-2ea0-4815-999d-730a6778227c</code>.</td>
</tr>
<tr>
<td><strong><code>resourceId</code></strong></td>
<td>A string that uniquely identifies the resource. For example, a UUID: <code>0f964a80-5d18-4867-83e3-b47f5a756f02</code>.</td>
</tr>
<tr>
<td><strong><code>resourceName</code></strong></td>
<td>A string that uniquely names and identifies a resource. This property, along with the <code>resourceType</code> below, can be used to track version changes within a resource.</td>
</tr>
<tr>
<td><strong><code>resourceType</code></strong></td>
<td>A string that identifies the type of resource. This property, along with the <code>resourceName</code> above, can be used to track version changes within a resource. Not to be confused with <code>mediaType</code>.</td>
</tr>
<tr>
<td><strong><code>resourceVersion</code></strong></td>
<td>(Optional) A string that identifies the version of the resource. This property is provided by the client and can be any value.</td>
</tr>
<tr>
<td><strong><code>alsoKnownAs</code></strong></td>
<td>(Optional) An array that describes alternative URIs for the resource.</td>
</tr>
<tr>
<td><strong><code>mediaType</code></strong></td>
<td>A string that identifies the IANA-media type of the resource.</td>
</tr>
<tr>
<td><strong><code>created</code></strong></td>
<td>A string that identifies the time the resource was created, as an XML date-time.</td>
</tr>
<tr>
<td><strong><code>updated</code></strong></td>
<td>(Optional) A string that identifies the time the resource was updated, as an XML date-time.</td>
</tr>
<tr>
<td><strong><code>checksum</code></strong></td>
<td>A string that may be used to prove that the resource has not been tampered with.</td>
</tr>
<tr>
<td><strong><code>previousVersionId</code></strong></td>
<td>(Optional) A string that identifies the previous version of the resource.</td>
</tr>
<tr>
<td><strong><code>nextVersionId</code></strong></td>
<td>(Optional) A string that identifies the next version of the resource.</td>
</tr>
</tbody>
</table>
Discoverability via DIDDoc Metadata {#discoverability}
---------------------
Once a Resource has been created under a Resource Collection, the parent DID document will automatically have an updated `didDocumentMetadata` section, including `linkedResourceMetadata`.
The syntax of the linked Resource metadata is as follows:
```json
"didDocumentMetadata": {
"created": "2020-12-20T19:17:47Z",
"updated": "",
"deactivated": false,
"versionId": "bdab59b0-66f5-42d3-b809-1829bdcc0408",
"previousVersion": "",
"nextVersion": "",
"linkedResourceMetadata": [
{ // First version of a Resource called PassportSchema
"resourceURI": "did:example:13d5ad44-9e99-428f-81e9-274458cefddc/resources/44547089-170b-4f5a-bcbc-06e46e0089e4",
"resourceCollectionId": "13d5ad44-9e99-428f-81e9-274458cefddc", // Common collection ID
"resourceId": "44547089-170b-4f5a-bcbc-06e46e0089e4", // Old Resource ID and version number
"resourceName": "PassportSchema", // Resource name must remain the same
"resourceType": "CL-Schema", // Resource type must remain the same
"resourceVersion": "1.0.1", // A user-set version
"mediaType": "application/json",
"created": "2022-07-19T08:40:00Z",
"checksum": "7b2022636f6e74656e74223a202274657374206461746122207d0ae3b0c44298", // Old version checksum
"previousVersionId": "", // empty string, since no previous version
"nextVersionId": "bb2118f3-5e55-4510-b420-33ef9e1726d2", // Points to next version below
},
{ // Second version of a Resource called PassportSchema
"resourceURI": "did:example:13d5ad44-9e99-428f-81e9-274458cefddc/resources/bb2118f3-5e55-4510-b420-33ef9e1726d2",
"resourceCollectionId": "13d5ad44-9e99-428f-81e9-274458cefddc", // Common collection ID
"resourceId": "bb2118f3-5e55-4510-b420-33ef9e1726d2", // New Resource ID and version number
"resourceName": "PassportSchema", // Resource name must remain the same
"resourceType": "JSONSchema2020", // Resource type must remain the same
"resourceVersion" "1.0.1" // user-set semantic version control
"mediaType": "application/json",
"created": "2022-08-07T08:40:00Z",
"checksum": "9123dcbb0b42652b0e105956c68d3ca2ff34584f324fa41a29aedd32b883e131", // New version checksum
"previousVersionId": "44547089-170b-4f5a-bcbc-06e46e0089e4", // Points to previous version above
"nextVersionId": "0be87654-4a48-4f8e-8789-15ec3589ccdd" // Points to next version. Empty string if no new version
}
]
}
```
Importantly, we decided not to populate the `didDocumentMetadata` with the actual resource data, but instead, populate what we refer to as a <b>Resource Preview</b> which contains all the metadata about the associated resources.
Composition of Resource Preview {#preview}
---------------------
Resource previews will appear within DID document metadata. These do not include the actual core data of the resource and only reference the metadata:
* Resource Collection ID: (`did:example:...:`) (supplied client-side)\*\*
* Resource ID: identifier ➝ specific to resource, also effectively a version number (supplied client-side)
* Resource Name: String (e.g., `JSONSchema2020` (supplied client-side))
* Resource Type (supplied client-side)
* Resource Version (supplied client-side)
* MediaType: (e.g., `application/json`/`image`/`application/octet-stream`/`text/plain`) (computed VDR-side)
* Created: XMLDatetime (computed VDR-side)
* Checksum: SHA-256 (computed VDR-side)
* previousVersionId: empty string if first, otherwise ID as long as `Name`, `ResourceType`, and `MimeType` match previous version (computed VDR-side)
* nextVersionId: empty string if first/latest, otherwise ID as long as `Name`, `ResourceType`, and `MimeType` match previous version (computed VDR-side)
* Also known as: a list of alternative URIs that can be used to get the resource.
Example:
```json
{
"resourceUri": "did:example:13d5ad44-9e99-428f-81e9-274458cefddc/resources/bb2118f3-5e55-4510-b420-33ef9e1726d2",
"resourceCollectionId": "13d5ad44-9e99-428f-81e9-274458cefddc",
"resourceId": "bb2118f3-5e55-4510-b420-33ef9e1726d2",
"resourceName": "PassportSchema",
"resourceType": "CL-SChema",
"resourceVersion": "1.0.1",
"mediaType": "application/json",
"created": "2022-04-20T20:19:19Z",
"checksum": "a7c369ee9da8b25a2d6e93973fa8ca939b75abb6c39799d879a929ebea1adc0a",
"previousVersionId": "67f2df00-0b6e-404b-8c70-1d63200e6412",
"nextVersionId": "98922424-c214-4439-b52c-f68ddb450b40",
"alsoKnownAs": [{
"uri": "https://example.com/alternative-uri",
"description": "Alternative URI description"
},
{
"uri": "https://example.com/alternative-uri",
"description": "Alternative URI description"
}]
}
```
Resolution and Dereferecing process {#process}
=====================
This section outlines the process for resolving a DID URL to retrieve the linked resource.
DID Resolution and Dereferencing {#resolution}
---------------------
When you resolve a DID you get a DID Document as by DID Core. When you dereference a DID, you may get the DID Document, a portion of a DID document, or the resource at the end of a service endpoint (if the DID contains a service component). You can only resolve a DID to return a DID document, and you can only dereference a DID reference to return a digital resource.
Resource resolution and dereferencing {#dereferencing}
---------------------
Normal DID URL dereferencing can be conceived in two steps:
1. A DID is resolved to a DID Document;
2. A resource within / associated with the DID Document is identified, based on the portion of the DID URL that follows the DID (path, query, fragment as defined by the ABNF in section 3.2 of the [[DID-CORE]] specification.).
Requests to fetch Resources are considered as a DID URL Dereferencing scenario it uses [DID URL paths](https://w3c.github.io/did-core/#path) to lead to a Resource object, rather than a DIDDoc.
On the other hand, Resources metadata requests are handled like DID URL Resolution since the result is a subsection of `didDocumentMetadata` specific to that resource.
Resource resolution and dereferencing parameters
---------------------
Here we have an ability to specify different parameters to filter to particular DID-Linked Resources.
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>resourceId</code></td>
<td>A <a href="https://infra.spec.whatwg.org/#string">string</a> that conforms to a method specific unique identifier format.</td>
<td>The unique identifier of a particular DID-Linked Resource.</td>
</tr>
<tr>
<td><code>resourceCollectionId</code></td>
<td>A <a href="https://infra.spec.whatwg.org/#string">string</a> that conforms to a method specific unique identifier format.</td>
<td>Can be used to query all resources associated with a DID if combined with <code>resourceMetadata=true</code>.</td>
</tr>
<tr>
<td><code>resourceName</code></td>
<td>A <a href="https://infra.spec.whatwg.org/#string">string</a>.</td>
<td>The specific name of a DID-Linked Resource.</td>
</tr>
<tr>
<td><code>resourceType</code></td>
<td>A <a href="https://infra.spec.whatwg.org/#string">string</a>.</td>
<td>The specific type of a DID-Linked Resource.</td>
</tr>
<tr>
<td><code>resourceVersionTime</code></td>
<td>A <a href="https://www.rfc-editor.org/rfc/rfc8259#section-7">JSON String</a> serialized as an <a href="https://www.w3.org/TR/xmlschema11-2/#dateTime">XML Datetime</a> normalized to UTC 00:00:00 and without sub-second decimal precision.</td>
<td>Used to fetch a version of a resource at a specific point in time.</td>
</tr>
<tr>
<td><code>checksum</code></td>
<td>A <a href="https://infra.spec.whatwg.org/#string">string</a>.</td>
<td>Used to specify a particular resource checksum to demonstrate it is untampered.</td>
</tr>
<tr>
<td><code>resourceMetadata</code></td>
<td><a href="https://infra.spec.whatwg.org/#booleans">Boolean</a>.</td>
<td>Used to fetch metadata related to a specific resource or group of resources.</td>
</tr>
</tbody>
</table>
Like with DIDDoc query parameters, these can all be chained together to create complex requests for specific DID-Linked Resources at particular points in time or associated with particular DIDDoc versions. 
Rules and logic for handling ambiguous queries
---------------------
It is important to understand how our resolver logically handles more complex dereferencing requests. We have set some baseline defaults and rules to ensure a logical and consistent experience for clients who use our resolver.
### Ambiguity generally throws an error
If the request specifies a parameter where there are multiple potential results, such as where the DID has two resources of the same `resourceType` but `resourceName` is not the same, an error will be thrown because there is not enough information to discern which resource is being requested.
### Multiple versions of the same resource
If there are multiple resources with the same `resourceType` and `resourceName` but with different `versionIds,` and there is no parameter specified to fetch a particular version, <b>the resolver will fetch the latest resource by default</b>.
This is because the query is not ambiguous in terms of discerning which set of resources to dereference to, but is only ambiguous in terms of which version of that resource to fetch. 
### Ambiguity + resourceMetadata=true
If there is an ambiguous query, such as where there are two resources with the same name but different types, AND there is a resourceMetadata=true parameter, resource data pertaining to all the resources which could potentially be seen as being ambiguous will be returned. 
For example, in the below example, there are multiple resources with the `resourceType= string`, but with different `resourceName` parameters:
<details>
<summary>Request format</summary>
```json
did:example:c1685ca0-1f5b-439c-8eb8-5c0e85ab7cd0?resourceType=String&resourceMetadata=true
```
</details>
<details>
<summary>Response format</summary>
```json
{
"@context": "https://w3id.org/did-resolution/v1",
"dereferencingMetadata": {
"contentType": "application/did+ld+json",
"retrieved": "2023-04-26T15:38:26Z",
"did": {
"didString": "did:example:c1685ca0-1f5b-439c-8eb8-5c0e85ab7cd0",
"methodSpecificId": "c1685ca0-1f5b-439c-8eb8-5c0e85ab7cd0",
"method": "example"
}
},
"contentStream": {
"created": "2023-01-25T11:58:10.390039347Z",
"versionId": "e5615fc2-6f13-42b1-989c-49576a574cef",
"linkedResourceMetadata": [
{
"resourceURI": "did:example:c1685ca0-1f5b-439c-8eb8-5c0e85ab7cd0/resources/9ba3922e-d5f5-4f53-b265-fc0d4e988c77",
"resourceCollectionId": "c1685ca0-1f5b-439c-8eb8-5c0e85ab7cd0",
"resourceId": "9ba3922e-d5f5-4f53-b265-fc0d4e988c77",
"resourceName": "exampleResourceName",
"resourceType": "exampleResourceType",
"mediaType": "application/json",
"resourceVersion": "",
"created": "2023-01-25T12:08:39.63Z",
"checksum": "e1dbc03b50bdb995961dc8843df6539b79d03bf49787ed6462189ee97d27eaf3",
"previousVersionId": null,
"nextVersionId": null
},
{
"resourceURI": "did:example:c1685ca0-1f5b-439c-8eb8-5c0e85ab7cd0/resources/e733ebb7-c8dd-41ed-9d42-33bceea70952",
"resourceCollectionId": "c1685ca0-1f5b-439c-8eb8-5c0e85ab7cd0",
"resourceId": "e733ebb7-c8dd-41ed-9d42-33bceea70952",
"resourceName": "exampleResourceName",
"resourceType": "exampleResourceType",
"mediaType": "application/json",
"resourceVersion": "",
"created": "2023-01-25T12:04:52.26Z",
"checksum": "cffd829b06797f85407be9353056db722ca3eca0c05ab0462a42d30f19cdef09",
"previousVersionId": null,
"nextVersionId": null
}
]
},
"contentMetadata": {}
}
```
</details>
Resolution and Dereferecing examples {#examples}
=====================
ResourceId
---------------------
`ResourceId` parameter can be used for filtering a particular resource version by specifically identifying its unique ID.
For example:
<details>
<summary>Request format</summary>
```json
did:example:b5d70adf-31ca-4662-aa10-d3a54cd8f06c?resourceId=5e16a3f9-7c6e-4b6b-8e28-20f56780ee25
```
</details>
<details>
<summary>Response format</summary>
```json
{
"title": "Example Verifiable Credential Schema",
"description": "Example schema for DID-Linked Resources spec",
"type": "object",
"properties": {
"@context": {
"description": "Defines semantic context of the Example Credential",
"type": "array",
"items": {
"type": "string",
"format": "uri"
}
}
}
}
```
</details>
ResourceCollectionId
---------------------
`resourceCollectionId` parameter filters all the resource by `collectionId` field. By default cause we are asking for resources for a particular DID it already includes all the resource with the same `collectionId` and this parameter can used mostly as sanity check. Without `resourceMetadata=true` parameter will return the latest created resource if there is only one resource or an unambiguous resource.
For example:
<details>
<summary>Request format</summary>
```json
did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c?resourceCollectionId=d8ac0372-0d4b-413e-8ef5-8e8f07822b2c
```
</details>
<details>
<summary>Response format</summary>
```json
{
"title": "Example Verifiable Credential Schema",
"description": "Example schema for DID-Linked Resources spec",
"type": "object",
"properties": {
"@context": {
"description": "Defines semantic context of the Example Credential",
"type": "array",
"items": {
"type": "string",
"format": "uri"
}
}
}
}
```
</details>
ResourceType
---------------------
This parameter is also just a filter by `Type` field through resources. But there is a corner case if the user asks about exact resource (exact data). If after applying all the parameters in request several resources are left with the same `Name` - the latest one will be responded. Otherwise - error `NotFoundError` will be raised.
For example:
<details>
<summary>Request format</summary>
```json
did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c?resourceType=exampleResourceType
```
</details>
<details>
<summary>Response format</summary>
```json
{
"title": "Example Verifiable Credential Schema",
"description": "Example schema for DID-Linked Resources spec",
"type": "object",
"properties": {
"@context": {
"description": "Defines semantic context of the Example Credential",
"type": "array",
"items": {
"type": "string",
"format": "uri"
}
}
}
}
```
</details>
ResourceName
---------------------
Behavior of this parameter is similar with [resourceType](adr-005-did-resolution-and-did-url-dereferencing.md#resourcetype) one. If there is no ambiguous resource, it will be fetched. Otherwise greater specifity is required. 
For example:
<details>
<summary>Request format</summary>
```json
did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c?resourceName=exampleResourceName
```
</details>
<details>
<summary>Response format</summary>
```json
{
"title": "Example Verifiable Credential Schema",
"description": "Example schema for DID-Linked Resources spec",
"type": "object",
"properties": {
"@context": {
"description": "Defines semantic context of the Example Credential",
"type": "array",
"items": {
"type": "string",
"format": "uri"
}
}
}
}
```
</details>
ResourceVersion
---------------------
This parameter filters by `Version` field. We introduced it with latest network upgrade and can be optionally set to identify a version of a resource with a particular string.
For example:
<details>
<summary>Request format</summary>
```json
did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c?resourceVersion=b9029cf7-c40b-4850-b9a1-9bfad46a68d7
```
</details>
<details>
<summary>Response format</summary>
```json
{
"title": "Example Verifiable Credential Schema",
"description": "Example schema for DID-Linked Resources spec",
"type": "object",
"properties": {
"@context": {
"description": "Defines semantic context of the Example Credential",
"type": "array",
"items": {
"type": "string",
"format": "uri"
}
}
}
}
```
</details>
ResourceVersionTime
---------------------
<div class="note"> <b>Important:</b> This parameter must always be accompanied by another resource query qualifier. </div>
The main goal here is to get the nearest resource for `resourceVersionTime` value. "Nearest" means that if we are asking for time between `resource1` and `resource2` were created - `resource1` will be returned. In case if requested `resourceVersionTime` is before the first resource created - `NotFoundError` will be returned. The most useful use-case here is checking that some "Credential" (driver's license) was active at `resourceVersionTime` (was not revoked from Revocation Registry for example).
For example:
<details>
<summary>Request format</summary>
```json
did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c?resourceVersionTime=2023-02-22T06:58:18.61Z&resourceVersion=1.14.41
```
</details>
<details>
<summary>Response format</summary>
```json
{
"title": "Example Verifiable Credential Schema",
"description": "Example schema for DID-Linked Resources spec",
"version": "1.14.41",
"type": "object",
"properties": {
"@context": {
"description": "Defines semantic context of the Example Credential",
"type": "array",
"items": {
"type": "string",
"format": "uri"
}
}
}
}
```
</details>
Checksum
---------------------
It just checks that `checksum` is the same as resource's metadata and also can used as a sanity check. For example, if the user knows what is exact checksum then it may be checked before actual downloading.
For example:
<details>
<summary>Request format</summary>
```json
did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c?checksum=27ad51a49f079a6634b18bbc3ac08dd2d91f13fabf72ea8e5d83692fe4820058
```
</details>
<details>
<summary>Response format</summary>
```json
{
"title": "Example Verifiable Credential Schema",
"description": "Example schema for DID-Linked Resources spec",
"version": "1.14.41",
"type": "object",
"properties": {
"@context": {
"description": "Defines semantic context of the Example Credential",
"type": "array",
"items": {
"type": "string",
"format": "uri"
}
}
}
}
```
</details>
ResourceMetadata
---------------------
This parameter a kind of modifier which works in the same manner as [metadata](adr-005-did-resolution-and-did-url-dereferencing.md#metadata) but applies to resources. It allows to get only Metadata information about resource(s) without downloading. Also it changes the flow for `resourceType` and `resourceName` parameters and general meaning of this parameter - just filter. So, here it allows to create a chain of parameters and apply all of them to the resourceCollection and get only interested resource metadata. Possible variants:
* `resourceMetadata=true`
* `resourceMetadata=false`
* Unused
For example:
<details>
<summary>Request format</summary>
```json
did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c?resourceType=exampleSchema&resourceMetadata=true
```
</details>
<details>
<summary>Response format</summary>
```json
{
"@context": "https://w3id.org/did-resolution/v1",
"dereferencingMetadata": {
"contentType": "application/did+ld+json",
"retrieved": "2023-04-27T11:10:17Z",
"did": {
"didString": "did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c",
"methodSpecificId": "d8ac0372-0d4b-413e-8ef5-8e8f07822b2c",
"method": "example"
}
},
"contentStream": {
"created": "2023-02-21T14:28:47.40Z",
"versionId": "44f49254-8106-40ee-99ad-e50ac9517346",
"linkedResourceMetadata": [
{
"resourceURI": "did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c/resources/bae5cb6c-564a-4ed4-8c0e-d5c3b0f8ae0a",
"resourceCollectionId": "d8ac0372-0d4b-413e-8ef5-8e8f07822b2c",
"resourceId": "bae5cb6c-564a-4ed4-8c0e-d5c3b0f8ae0a",
"resourceName": "exampleResourceName",
"resourceType": "exampleResourceType",
"mediaType": "application/json",
"resourceVersion": "1.14.41",
"created": "2023-02-22T08:57:23.34Z",
"checksum": "93ba6f3c55ee073e6278f98e820776e73cfd9d3e32dc5882507ee8effbdbfadd",
"previousVersionId": "40829caf-b415-4b1d-91a3-b56dfb6374f4",
"nextVersionId": null
},
{
"resourceURI": "did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c/resources/40829caf-b415-4b1d-91a3-b56dfb6374f4",
"resourceCollectionId": "d8ac0372-0d4b-413e-8ef5-8e8f07822b2c",
"resourceId": "40829caf-b415-4b1d-91a3-b56dfb6374f4",
"resourceName": "exampleResourceName",
"resourceType": "exampleResourceType",
"mediaType": "application/json",
"resourceVersion": "1.45.24",
"created": "2023-02-22T08:55:07.54Z",
"checksum": "2a6af570635ed49a39eae9a9c60ccb40d61466839d4ab2f17432a8ac705da489",
"previousVersionId": "547abdb3-99f8-4040-b030-3296c4668846",
"nextVersionId": "bae5cb6c-564a-4ed4-8c0e-d5c3b0f8ae0a"
},
{
"resourceURI": "did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c/resources/547abdb3-99f8-4040-b030-3296c4668846",
"resourceCollectionId": "d8ac0372-0d4b-413e-8ef5-8e8f07822b2c",
"resourceId": "547abdb3-99f8-4040-b030-3296c4668846",
"resourceName": "exampleResourceName",
"resourceType": "exampleResourceType",
"mediaType": "application/json",
"resourceVersion": "1.42.26",
"created": "2023-02-22T08:54:14.48Z",
"checksum": "4524f2193da6e5cc28d8a71f268d097891d053d4f206b045347ae117ce70d8ac",
"previousVersionId": null,
"nextVersionId": "40829caf-b415-4b1d-91a3-b56dfb6374f4"
}
]
},
"contentMetadata": {}
}
```
</details>
Security considerations {#security}
=====================
This section discusses the security considerations associated with linking and dereferencing DID-Linked Resources.