-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.html
1372 lines (1188 loc) · 65.7 KB
/
index.html
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
<!DOCTYPE html>
<html>
<head>
<title>The did:orb Method v0.2</title>
<meta charset='utf-8'>
<script src='https://www.w3.org/Tools/respec/respec-w3c' async class='remove'></script>
<script class='remove'>
var respecConfig = {
specStatus: "unofficial",
subtitle: "A DID Method for a fediverse of interconnected nodes and witnesses",
editors: [{
name: "Troy Ronda", url: "https://www.linkedin.com/in/troyronda/",
company: "SecureKey", companyURL: "https://securekey.com/"
}],
github: "https://github.com/trustbloc/did-method-orb",
localBiblio: {
"ACTIVITYANCHORS": {
title: "Activity Anchors",
href: "https://trustbloc.github.io/activityanchors/",
authors: ["T. Ronda"],
publisher: "TrustBloc",
},
"SIDETREE": {
title: "Sidetree v1.0.0",
href: "https://identity.foundation/sidetree/spec/v1.0.0/",
authors: ["D. Buchner, O. Steele, T. Ronda"],
publisher: "Decentralized Identity Foundation",
status: "DIF Ratified Specification"
},
"DIDRESOLUTION": {
title: "Decentralized Identifier Resolution (DID Resolution)",
href: "https://w3c-ccg.github.io/did-resolution/",
publisher: "W3C CCG",
status: "Draft Community Group Report"
},
"LDPROOF": {
title: "Linked Data Proofs 1.0",
href: "https://w3c-ccg.github.io/ld-proofs/",
publisher: "W3C CCG",
status: "Draft Community Group Report"
},
"HASHLINK": {
title: "Cryptographic Hyperlinks",
date: "May 2021",
href: "https://tools.ietf.org/html/draft-sporny-hashlink-07",
authors: [
"M. Sporny",
"L. Rosenthol"
],
status: "Internet-Draft",
publisher: "IETF"
},
"LINKSET": {
title: "Linkset: Media Types and a Link Relation Type for Link Sets",
date: "February 2022",
href: "https://tools.ietf.org/html/draft-ietf-httpapi-linkset-08",
authors: [
"E. Wilde",
"H. Van de Sompel"
],
status: "Internet-Draft",
publisher: "IETF"
},
"MULTIHASH": {
title: "The Multihash Data Format",
date: "February 2021",
href: "https://tools.ietf.org/html/draft-multiformats-multihash-02",
authors: [
"J. Benet",
"M. Sporny"
],
status: "Internet-Draft",
publisher: "IETF"
},
"MULTIBASE": {
title: "The Multibase Data Format",
date: "February 2021",
href: "https://tools.ietf.org/html/draft-multiformats-multibase-03",
authors: [
"J. Benet",
"M. Sporny"
],
status: "Internet-Draft",
publisher: "IETF"
}
}
};
</script>
</head>
<body>
<section id='abstract'>
<p>
Orb is a decentralized identifier (DID) method based on a federated and replicated
<a href="https://www.w3.org/TR/did-core/#dfn-verifiable-data-registry">Verifiable Data Registry</a> (VDR).
The decentralized network consists of Orb servers that write, monitor, witness, and propagate batches of DID operations.
The batches form a graph that is propagated and replicated between the servers as content-addressable objects.
These content-addressable objects can be located via both domain and distributed hash table (DHT) mechanisms.
Each Orb witness server observes a subset of batches in the graph and includes them in their ledgers (as append-only Merkle Tree logs).
The servers coordinate by propagating batches of DID operations and by monitoring the applicable witness servers' ledgers.
The Orb servers form a decentralized network without reliance on a common blockchain for coordination.
</p>
<p>
This document specifies the Orb DID Method along with a data model and rules for representing a graph of batches,
the Orb server API, a registry of protocol versions and parameters,
an [[[ACTIVITYSTREAMS-CORE]]] vocabulary and an [[[ACTIVITYPUB]]] profile for propagating batches,
a [[[RFC7033]]] profile for discovering endpoints, a [[[SIDETREE]]] protocol profile for encoding DID operations,
and a [[[RFC6962]]] profile for witness ledgers.
</p>
</section>
<section id='sotd'>
<p>
</p>
</section>
<section class="informative">
<h2>Introduction</h2>
<p>
The Orb DID method enables users or entities to create <a href="https://identity.foundation/sidetree/spec/#did-uri-composition">self certifying</a>
decentralized identifiers (DIDs) that are propagated across a decentralized network without reliance on a common blockchain for coordination.
Decentralized identifiers [[DID-CORE]] are a fundamental building block to enable persons and entities to prove that they control an identifier
that is attached to digital objects such as Verifiable Credentials [[VC-DATA-MODEL]].
</p>
<p>
Systems that rely on <i>self certifying</i> DIDs need a
mechanism to propagate the ordered updates to DID documents from the server writing operations to their DID resolver.
As an example, operations can be distributed via a content-addressable network (such as <a href="https://ipfs.io">IPFS</a>)
and announced on a public blockchain (such as <a href="https://bitcoin.org">Bitcoin</a>) or a permissioned blockchain
(such as <a href="https://www.hyperledger.org/use/fabric">Hyperledger Fabric</a>). This DID method, instead, makes use of
decentralized federation protocols to propagate announcements and replicate content in a <a href="https://en.wikipedia.org/wiki/Gossip_protocol">gossip manner</a>.
By using a decentralized federation mechanism, we have no need to choose a common blockchain nor rely on a consortium's
<a href="https://en.wikipedia.org/wiki/Distributed_ledger">distributed ledger</a> (DLT) for coordination.
Orb has the ability to enable use cases where a public blockchain is not acceptable to stakeholders and also avoids lock-in to a single DLT.
</p>
<p>
As operations on DIDs can be originated by different writers in a decentralized network, it is also beneficial to enable a mechanism for determining
the latest operations for a particular suffix. For example, when all DID operations are announced by the same blockchain, the other systems can
monitor that blockchain for the latest operations. These blockchains can also provide relative timing in cases of
<a href="https://identity.foundation/sidetree/spec/#late-publishing">late publishing</a>. This DID method, instead, makes use of independent witness ledgers
that the DID controller can associate with their DID. These witness ledgers can be monitored as additional propagation sources and proofs from these ledgers can
also provide relative timing confidence in cases of late publishing. Rather than being a global chain of all operation announcements, these ledgers contain
a subset of the announcements that propagate through the decentralized federation protocols.
</p>
<p>
The property of self certifying DIDs is obtained due to Orb being an extension of the [[[SIDETREE]]] protocol.
By using the Sidetree protocol, the DID controller forms their own verifiable chain of patches from inception to the current state of the DID document.
These verifiable chains are included into larger batches by one of the independent Orb servers and encoded as content-addressable objects. We also
inherit the scalability properties of the Sidetree protocol batch strategy.
</p>
<p>
Our motivation for the Orb DID method is to enable many independent organizations to create <a href="https://www.w3.org/TR/did-core/#dfn-verifiable-data-registry">
Verifiable Data Registries</a> (VDRs) that can become connected over time.
In designing Orb, we have the goal to enable these VDRs to interconnect into a decentralized network without the need to choose a common public
blockchain or to rely on special-purpose consortiums to form (and remain in operation). By using decentralized federation protocols and witness ledgers,
we enable <i>self-certifying</i> DIDs even in use cases where leveraging a public blockchain or a consortium DLT is not acceptable to stakeholders.
Orb enables a federated, replicated and scalable VDR based on a decentralized network for propagating, witnessing and replicating changes to DID documents.
</p>
</section>
<section class="normative">
<h2>Concepts</h2>
<p>
Orb uses a propagation model where servers announce transactions to other servers that are following them.
In general, <i>Orb Servers</i> have the capability to propagate transactions and replicate Orb
<a href="https://www.w3.org/TR/did-core/#dfn-verifiable-data-registry"> Verifiable Data Registries</a> (VDRs).
Beyond propagation and replication, there are three primary <i>Orb Server</i> roles in the transaction flow:
</p>
<ul>
<li>Writer: Accepts operations from DID controllers to update their DIDs, batches operations, and creates an Orb transaction from each batch.</li>
<li>Witness: Provides decentralized timestamping and partial ledger histories for Orb transactions. Accepts <i>preannouncements</i> of Orb transactions from Writers.</li>
<li>Resolver: Responds to Requesting Party (RP) requests for DID resolution.</li>
</ul>
<figure>
<img src="diagrams/flow-model.svg" style="max-width: 50%;"/>
<figcaption>
Orb transaction propagation model
</figcaption>
</figure>
<p>
Orb servers apply both the DID controller's intention and also observed timings to resolve scenarios where a DID update is applied
at the same sequence position in the DID's operation chain.
As the DID controller is fully responsible for the changes to their DIDs, they can create a new branch in their operation chain even after time has passed.
Orb Servers use rules to determine the <i>first published branch</i> and use observations to assist in that decision as follows:
</p>
<ul>
<li>Operation timestamps are used to limit inclusion into a new transaction: allow the DID controller to signal that an operation is stale.</li>
<li>Transaction and propagation timestamps from Orb servers indicate when they first observed a transaction.</li>
<li>Independent decisions on the trustworthiness of an Orb server based on the ability to monitor their consistency over time (and other independent factors for each system).</li>
<li>Ability to monitor the consistency of a Witness server's timestamps and relative ordering of transactions based on their append-only ledger.</li>
<li>The ability for a DID controller to associate to a Witness ledger. The DID controller's behavior, as observed by that Witness, has extra weight as a tie-breaker.</li>
</ul>
<p>
The following diagram provides an example of applying the stale rule to <i>DID B</i> and the usage of a Witness associated to <i>DID A</i> as a tie-breaker to resolve a branch.
</p>
<figure>
<img src="diagrams/branch-model.svg" style="max-width: 50%;"/>
<figcaption>
Orb branch rules example
</figcaption>
</figure>
<p>
Transactions are structured as a content-addressable graph.
An Orb server accepts operations from DID controllers and periodically creates a Sidetree batch consisting of operations from multiple DIDs.
From the batch, a <i>pretransaction</i> is created that includes hashlinks [[HASHLINK]] of the most recent transaction for each DID from the <i>Writer server's point of view</i>.
The Writer <i>preannounces</i> the transaction to a set of Witnesses.
Each Witness promises to include the transaction in their ledger by returning a timestamped and signed pretransaction.
The Orb server then propagates the combination of the pretransaction with the timestamped witness signatures as a new transaction.
</p>
<p>
Orb enables the VDR to be replicated between independent systems to increase the overall resilience of the ecosystem.
The transaction model includes Witness signatures as a common Orb format regardless of the Witness ledger implementation.
To achieve our system monitoring properties, we assume a Witness holds a <i>monitorable</i> ledger that stores timestamped transactions with an append-only model.
Witness ledgers can be replicated and monitored for consistent behavior.
In particular, monitoring systems validate:
</p>
<ul>
<li>The ledger contains the transactions that were promised to be included.</li>
<li>Consistency between Merkle Tree heads (append-only).</li>
<li>Consistency of timestamping - time moves forward as new Merkle Tree heads are created.</li>
</ul>
<figure>
<img src="diagrams/data-model.svg" style="max-width: 50%;"/>
<figcaption>
Orb transaction data model
</figcaption>
</figure>
We enable both a Web API for content-addressable storage (including endpoint discovery) and also <a href="https://en.wikipedia.org/wiki/Distributed_ledger">Distributed Hash Tables</a> (DHTs) such as <a href="https://ipfs.io">IPFS</a>.
This specification also includes a Witness ledger profile based on certificate transparency [[RFC6962]].
<section class="normative">
<h3>Self Certifying Decentralized Identifiers</h3>
<p>
Orb DIDs are <i>self certifying</i>.
The data structure that encodes the ordered updates to a DID document form their own verifiable chain from inception to the current state of the DID document.
We inherit this property due to our usage of the [[[SIDETREE]]] protocol for encoding the DID document updates.
</p>
</section>
<section class="normative">
<h3>Propagation via Decentralized Federation</h3>
<p>
Orb makes use of decentralized federation protocols to propagate announcements and replicate content in a
<a href="https://en.wikipedia.org/wiki/Gossip_protocol">gossip manner</a>. We use [[[ACTIVITYSTREAMS-CORE]]] and [[[ACTIVITYPUB]]].
In later sections, we describe the vocabulary and profile for using these protocols in Orb.
</p>
<p>
Orb does not rely on public blockchains nor DLTs to coordinate - there is no need for network consensus. Instead, we rely on
self certifying DIDs being propagated and the ability to replicate VDRs in a gossip manner.
</p>
</section>
<section class="normative">
<h3>DID Updates Are Batched</h3>
<p>
Modifications to DID documents that are sent to an Orb servers are aggregated into batches prior to being announced on the decentralized network.
By supporting batching, we enhance the scalability properties due to a reduction in messages and objects being stored.
We inherit this property due to our usage of the [[[SIDETREE]]] protocol for encoding the DID document updates.
</p>
</section>
<section class="normative">
<h3>DID Updates Batches Form a Graph</h3>
<p>
When writing a batch of DID document updates, an Orb server also includes immutable references to the prior batches.
These references form a graph (in the form of a Merkle Tree) such that the ancestor operations can be processed prior to a newly observed batch.
This property is needed in the Orb data structures since we do not have a common blockchain to provide this history.
</p>
<p>
When a DID controller supplies their DID, they also include a reference to a batch in their DID string. This reference allows an Orb server to discover
the graph where a DID was created (or more generally where a <a href="https://identity.foundation/sidetree/spec/#core-index-file">core Sidetree</a> update occurred).
This reference also enables the DID controller to specify a minimum version of the DID document that must be discovered in order to resolve.
</p>
</section>
<section class="normative">
<h3>CAS-based Verifiable Data Registry</h3>
<p>
The Orb VDR leverages <a href="https://en.wikipedia.org/wiki/Content-addressable_storage">Content-Addressable Storage</a> (CAS) to hold the DID document batch files.
The processed batch files result in hosting resolvable DID documents.
By supporting a CAS, we enhance the ability to replicate immutable content across the decentralized network.
We inherit this property due to our usage of the [[[SIDETREE]]] protocol for encoding the DID document updates and batches.
</p>
<p>
We also leverage the CAS to hold the graph of batches. The immutable references to prior batches are in the form of hashlinks [[HASHLINK]].
</p>
</section>
<section class="normative">
<h3>Witnesses Resolve Late Publishing</h3>
<p>
The Orb method relies on decentralized federation, gossip and CAS replication mechanisms to propagate
the VDR among servers. The self certifying nature of Orb DIDs enables confidence in the DID validity without the need
for network consensus.
As the DID controller is fully responsible for the changes to their DIDs, they can create a new branch in their operation chain even after time has passed.
This situation is called <a href="https://identity.foundation/sidetree/spec/#late-publishing">late publishing</a>.
The resolver systems require a mechanism to decide which branch should be used to represent the current DID state.
It is also beneficial to create rules that enable a consistent viewpoint of the active branch among interconnected Orb servers.
Resolver systems use rules to determine the <i>first published branch</i> and use observations from Witness systems to assist in that decision.
</p>
<p>
In the absence of Witnesses, we start with a simple rule: the first branch of a DID observed by an Orb server is the first published branch
for that DID <i>from that server's point of view</i>. As Orb servers become increasingly interconnected, batches are gossiped between
the Orb servers. Each server that forwards a batch includes a signed timestamp of when they observed the batch. The Orb Server MAY
designate some of the other Orb servers as <i>trusted</i>. These trusted servers are then used to determine relative timing between batches.
In the case that a majority viewpoint of itself and the other <i>trusted</i> Orb servers exists, that majority viewpoint will be used to
determine the relative timing of the batches. From the relative timing of the batches, we also resolve the relative timing of the branch in the DID.
An Orb server does not wait for consensus - its viewpoint may eventually converge to a majority view, over time, in these situations.
</p>
<p>
Rules exist to resolve the active branch so that Orb servers can consistently resolve the DID controller's intended and current DID document.
To mitigate against initial divergences, we also introduce the Witness role to observe a transaction prior to propagation.
The Orb transaction writer <i>preannounces</i> the existence of an Orb transaction by submitting it to a Witness.
A Witness creates a proof that they observed an Orb transaction at a certain time.
Witnesses have the capability to provide timestamping and also host a Witness Ledger to provide relative ordering between merged sets of Orb Transactions.
</p>
<p>
Although each Orb Server decides who to designate as trusted, it is also important that an Orb Server's behavior can be monitored.
We use a Witness ledger as the mechanism for monitoring behavior - if inconsistencies are detected, other systems can adjust their viewpoint
for trustworthiness.
A Witness ledger is responsible for recording individual Orb transactions, providing signed transaction timestamps
that can be embedded within a propagated Orb transaction, providing ledger consistency proofs, and providing an API that exposes their ledger.
A Witness ledger is not responsible for maintaining the Orb transaction graph structure nor is it responsible for maintaining a complete history of Orb transactions.
An Orb server is monitorable by exposing a Witness ledger API.
</p>
<p>
We structure witnesses ledgers in a similar manner to certificate transparency [[RFC6962]], as append-only Merkle Trees with proof capabilities.
A Witness ledger promises to include a submitted Orb transaction within a time period known as the Maximum Merge Delay (MMD).
Once the ledger merges a set of Orb transactions into the Merkle Tree, a Signed Tree Head (STH) is produced.
The STH (and associated Merkle Proofs) is used to validate consistency between older and newer ledger revisions.
</p>
<p>
When an Orb server creates a transaction, the server requests other Orb servers (as Witnesses) to include the transaction into their Witness ledger.
The Orb server <i>preannounces</i> a transaction to Witnesses after preparing and writing the Sidetree CAS objects.
The transaction announcement is then sent to Witnesses for validation and inclusion by the Witnesses.
Each witnesses validates the Orb transaction structure and that it was issued within an acceptable delta of their current time.
Upon successful validation, each witness returns a signed transaction timestamp and a promise to include the Orb transaction into their Ledger.
The Orb transaction (combined with the signed transaction timestamps) is then written into the CAS and propagated.
When an Orb Server receives a propagated transaction, they invalidate (as stale) each Sidetree operation that has a timestamp that is not within an acceptable delta of the Orb transaction's timestamp.
When these proofs originate from <i>trusted</i> servers, their timing information is immediately applied after receiving an Orb transaction propagation.
An Orb server that receives witnessed transactions from trusted servers likely holds the majority timing view immediately in these situations.
</p>
</section>
<section class="normative">
<h3>Witnesses Propagate for a DID</h3>
<p>
As Orb relies on gossip replication, it is possible for a resolver system to miss transactions originating from other servers that they do not follow.
To mitigate this issue for a particular DID, we allow the DID controller to specify a witness policy.
This policy contains a set of witnesses that MUST be used when an Orb transaction includes changes to the associated DID.
The Writer server ensures that, according to the DID's policy, a sufficient number of these server(s) are also acceptable as Witnesses to the Writer server.
If the DID's policy is unacceptable to the Writer server, the operation MUST be rejected and not included into the Orb transaction. The
DID policy ensures that the Resolver Servers can determine if they have the latest propagations and that the DID controller can use any
Writer server that has mutually acceptable policies.
</p>
<p>
As a DID can be associated to a particular Witness, that Witness provides observations of the DID controller's behavior.
In addition to propagating for a DID, the associated Witness is also given extra weight as a tie-breaker for resolving the late publishing scenario described in the previous section.
</p>
<p>
The ability to set (or change) the policy is an operation that is included into a propagated <a href="https://identity.foundation/sidetree/spec/#core-index-file">Sidetree core index</a>.
</p>
</section>
<section class="normative">
<h3>Web Discovery APIs are Supported</h3>
<p>
The Orb DID method enables CAS discovery and usage via Web APIs. The WebFinger protocol [[RFC7033]] allows systems to query for both
[[ACTIVITYPUB]] endpoints and also for CAS endpoints for a given resource. By enabling a fully Web-enabled model, we do not introduce
a requirement on <a href="https://en.wikipedia.org/wiki/Distributed_hash_table">Distributed Hash Table</a> (DHT) usage into the method.
</p>
</section>
<section class="normative">
<h3>Distributed Hash Tables are Supported</h3>
<p>
Although Orb DIDs can be created that do not have a dependency on DHTs, we also enable optional support for registering CAS resources on a DHT.
Orb servers MAY choose to expose their CAS-based VDRs on a <a href="https://en.wikipedia.org/wiki/Distributed_hash_table">Distributed Hash Table</a> (DHT) network such as IPFS.
When using a DHT, we gain the advantage of not needing to specify any Web domain to be queried for discovery.
</p>
</section>
<section class="normative">
<h3>Graphs Enable Propagation Discovery</h3>
<p>
The Orb transaction graph that is stored into the content-addressable storage (CAS) also enables discovery of propagation properties.
Each node in the transaction graph includes known CAS discovery information and witness endpoints.
The CAS discovery information enable Orb servers to include additional endpoints when responding to WebFinger [[RFC7033]] queries.
The witness endpoints enable Orb servers to follow additional systems for propagation.
</p>
</section>
</section>
<section class="normative">
<h2 id="format">The did:orb Format</h2>
<p>
The format for the <tt>did:orb</tt> method conforms to the [[[DID-CORE]]] specification.
The DID scheme consists of the did:orb prefix, the mechanism for discovering content-addressable objects,
a multihash (with a multibase prefix) for the minimum node in the DID operation batch graph, and the unique suffix of the DID.
</p>
<p>
The method uses the following ABNF [[RFC5234]] format:
</p>
<pre>
did-orb-format = "did:orb:" (orb-scheme-did / orb-long-form-did / orb-canonical-did)
orb-canonical-did = anchor-hash ":" did-suffix
orb-long-form-did = anchor-hash ":" did-suffix ":" did-suffix-data
orb-scheme-did = scheme path ":" orb-metadata-did
orb-metadata-did = anchor-hash [":" hash-metadata] ":" did-suffix [":" did-suffix-data]
scheme = 1*idchar
path = *(":" segment)
segment = 1*idchar ; more constrained than [RFC3986]
anchor-hash = 1*idchar
hash-metadata = 1*idchar
did-suffix = 1*idchar
did-suffix-data = 1*idchar
</pre>
<p>
See [[?RFC3986]] for the original definition of <i>scheme</i> and <i>path</i> and [[DID-CORE]] for the definition of <i>idchar</i>.
[[SIDETREE]] provides additional explanation for the <i>did-suffix</i> and <i>did-suffix-data</i> elements.
[[MULTIHASH]] and [[MULTIBASE]] defines the multihash and multibase formats that are used for the <i>anchor-hash</i> element.
</p>
<p>
The canonical Orb DID includes a multihash of the latest anchor object that contains a create or recovery operation for the Sidetree DID suffix.
The first segment after `did:orb` contains the anchor multihash and the second segment contains the Sidetree DID suffix.
</p>
<pre class="example" title="A canonical Orb DID">
did:orb:uEiDlXjleTwr4eZalpXVy086zs-TPK-h54ojbpl7EBvZeHQ:EiDyOQbbZAa3aiRzeCkV7LOx3SERjjH93EXoIM3UoN4oWg
</pre>
<p>
In cases where the anchoring information is not included into the DID string, the graph multihash will be represented by the identity code (`0x00`) with a 0 length output.
The base64url representation of an unknown anchor object is: `uAAA`.
For example: when a DID is initially created, the graph multihash is not known until the DID is added to an anchor object.
In this case, the anchor object cannot be included into the DID string so the unknown anchor object is included.
</p>
<pre class="example" title="An Orb DID without anchoring information">
did:orb:uAAA:EiDyOQbbZAa3aiRzeCkV7LOx3SERjjH93EXoIM3UoN4oWg
</pre>
</section>
<section class="normative">
<h2>Client-to-Server Operations</h2>
<p>
The Orb DID method extends the operations specified in the [[SIDETREE]] specification.
</p>
<section class="normative">
<h3>Create</h3>
<p>
An Orb DID is created by submitting a <i>create</i> to the operations endpoint of an Orb Server,
as specified in <a href="https://identity.foundation/sidetree/spec/#create">Sidetree</a>.
</p>
<p>
Detailed steps are specified in the <a href="https://identity.foundation/sidetree/api/#create">Sidetree API</a>.
</p>
</section>
<section class="normative">
<h3>Read</h3>
<p>
An Orb Server exposes a DID resolution API as defined in [[DID-CORE]] using the HTTP(S) Binding specified by [[DIDRESOLUTION]].
</p>
<p>
Detailed steps and additional method metadata properties are specified in the <a href="https://identity.foundation/sidetree/api/#sidetree-resolution">Sidetree API</a>.
</p>
</section>
<section class="normative">
<h3>Update</h3>
<p>
An Orb DID is created by submitting an <i>update</i> to the operations endpoint of an Orb Server,
as specified in <a href="https://identity.foundation/sidetree/spec/#update">Sidetree</a>.
</p>
<p>
Detailed steps are specified in the <a href="https://identity.foundation/sidetree/api/#update">Sidetree API</a>.
</p>
</section>
<section class="normative">
<h3>Recover</h3>
<p>
An Orb DID is recovered by submitting a <i>recover</i> to the operations endpoint of an Orb Server,
as specified in <a href="https://identity.foundation/sidetree/spec/#recover">Sidetree</a>.
</p>
<p>
Detailed steps are specified in the <a href="https://identity.foundation/sidetree/api/#recover">Sidetree API</a>.
</p>
</section>
<section class="normative">
<h3>Deactivate</h3>
<p>
An Orb DID is deactivated by submitting a <i>deactivate</i> to the operations endpoint of an Orb Server,
as specified in <a href="https://identity.foundation/sidetree/spec/#deactivate">Sidetree</a>.
</p>
<p>
Detailed steps are specified in the <a href="https://identity.foundation/sidetree/api/#deactivate">Sidetree API</a>.
</p>
</section>
<section class="normative">
<h3>Propagation Delay and Canonical IDs</h3>
Orb DIDs support Sidetree <a href="https://identity.foundation/sidetree/spec/#did-uri-composition">DID URI Composition</a>
for the <i>did-suffix</i> and <i>did-suffix-data</i> elements.
An Orb resolver with previous knowledge of a particular suffix (or with the inclusion of <i>did-suffix-data</i>) is able
to return a resolution result without additional prefix information.
This situation typically occurs when there is a need to immediately use a freshly created DID suffix that hasn't yet been propagated.
<pre class="example highlight" title="Not yet propagated DID only known to example.com">
did:orb:https:example.com:uAAA:EiA329wd6Aj36YRmp7NGkeB5ADnVt8ARdMZMPzfXsjwTJA
</pre>
<pre class="example highlight" title="Long-form DID">
did:orb:https:example.com:uAAA:EiA329wd6Aj36YRmp7NGkeB5ADnVt8ARdMZMPzfXsjwTJA:ey...
</pre>
When an Orb Server has propagation information for a resolved DID, the server includes the <i>anchor-hash</i> segment within the <i>canonicalId</i>
property of the returned DID document metadata.
The <i>anchor-hash</i> is set to the multihash (with multibase prefix) of the latest known AnchorCredential that contains a <i>Create</i> or <i>Recover</i> operation for the DID.
After a DID controller sends a <i>Create</i> or <i>Recover</i> operation to an Orb Server, the resolution result may have no (or an outdated) <i>anchor-hash</i> segment.
The DID controller may need to retry resolution until the operation has been propagated and the multihash becomes available.
Once the multihash is available, resolution responses contain the updated <i>canonicalId</i> property.
</section>
<section class="normative">
<h3>CAS Discovery and Equivalent IDs</h3>
Orb DIDs support hints to enable a resolver to discover a CAS that is hosting the anchor-hash in the DID string.
A hint can be added to an Orb DID string by adding a <i>scheme</i> prefix to the multihash.
Please see <a href="#format">did:orb format</a> for more information about discovery schemes and examples.
These DIDs are treated as equivalent to the canonical DID.
An Orb resolution response MAY contain an <i>equivalentId</i> property that is populated with <i>orb-scheme-did</i> format DIDs.
</section>
<section class="normative">
<h3>Discovery</h3>
<section class="normative">
<h4>Domain Endpoint Discovery</h4>
<p>
A client discovers a domain's endpoints for DID resolution and DID operations using a .well-known scheme [[RFC8615]].
The domain declares its own endpoints for resolution and operations.
</p>
<pre class="example highlight" title="Client endpoint discovery (request)">
GET /.well-known/did-orb HTTP/1.1
Host: alice.example.com
Accept-Encoding: gzip, deflate
</pre>
<p>
When the discovery profile exists, an HTTP 200 status code is returned.
</p>
<pre class="example highlight" title="Client endpoint discovery (response)">
HTTP/1.1 200 OK
Date: Sat, 30 Jan 2021 18:31:58 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
{
"resolutionEndpoint": "https://alice.example.com/sidetree/0.1/identifiers",
"operationEndpoint": "https://alice.example.com/sidetree/0.1/operations"
}
</pre>
</section>
<section class="normative">
<h4>Shared Resolution Domain</h4>
<p>
A shared domain may be used to enable a group of organizations to share resolution responsibilities.
This model enables a resolution client to have increased confidence by validating a resolution result against multiple entities.
A domain is a shared domain model when it declares its linked domains and an n-of-m policy in its well-known configuration.
Linked domains indicate to clients that these domains have an synchronized (eventually consistent) relationship and can be used n-of-m for resolution.
These domains and policy are fetched using a WebFinger [[RFC7033]] query.
When using linked domain resolution, the client performs the following steps to obtain higher confidence in the resolution results:
</p>
<ol>
<li>Lookup <i>n</i> from the <i>https://trustbloc.dev/ns/min-resolvers</i> property.</li>
<li>Choose <i>n</i> of the links from the WebFinger result.</li>
<li>Fetches the configurations at each chosen link using WebFinger.</li>
<li>Validates that each well-known configuration has the same policy for <i>n</i> and that all of the chosen links are listed in the <i>n</i> fetched configurations.</li>
<li>Resolve the DID at each of the <i>n</i> chosen links.</li>
<li>Ensure that the DID resolution result matches (other than resolver-specific metadata such as timestamps).</li>
<li>In case of a mismatch, additional links may need to be chosen until the client has <i>n</i> matches.</li>
</ol>
<pre class="example highlight" title="Client shared domain discovery (request)">
GET /.well-known/did-orb HTTP/1.1
Host: shared.example.com
Accept-Encoding: gzip, deflate
</pre>
<p>
When the discovery profile for the shared domain exists, an HTTP 200 status code is returned.
</p>
<pre class="example highlight" title="Client shared domain discovery (response)">
HTTP/1.1 200 OK
Date: Sat, 30 Jan 2021 18:31:58 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
{
"resolutionEndpoint": "https://shared.example.com/sidetree/0.1/identifiers",
"operationEndpoint": "https://shared.example.com/sidetree/0.1/operations"
}
</pre>
<pre class="example highlight" title="Client shared domain discovery (request)">
GET /.well-known/webfinger?resource=https%3A%2F%2Fshared.example.com%2Fsidetree%2F0.1%2Fidentifiers HTTP/1.1
Host: shared.example.com
Accept-Encoding: gzip, deflate
</pre>
<p>
When the DID resolution capability exists, an HTTP 200 status code is returned.
</p>
<pre class="example highlight" title="Client shared domain discovery (response)">
HTTP/1.1 200 OK
Date: Sat, 30 Jan 2021 18:31:58 GMT
Content-Type: application/jrd+json
Connection: keep-alive
Access-Control-Allow-Origin: *
{
"subject": "https://shared.example.com/sidetree/0.1/identifiers",
"properties": {
"https://trustbloc.dev/ns/min-resolvers": 2
},
"links": [
{
"rel": "self",
"href": "https://shared.example.com/sidetree/0.1/identifiers"
},
{
"rel": "alternate",
"href": "https://charlie.example.com/sidetree/0.1/identifiers"
},
{
"rel": "alternate",
"href": "https://oscar.example.com/sidetree/0.1/identifiers"
},
{
"rel": "alternate",
"href": "https://mike.example.com/sidetree/0.1/identifiers"
}
]
}
</pre>
</section>
</section>
<section class="normative">
<h3>Operation Origin and Policy</h3>
<p>
The DID controller declares their origin policy by setting the URI of their desired witness into the <i>anchorOrigin</i> property in the <i>Create</i> or <i>Replace</i> operation.
</p>
<p class="issue" title="Additional policy">
TODO: In a followup revision, we might specify additional origin policy information.
</p>
</section>
<section class="normative">
<h3>Operation Anchoring Validity</h3>
<p>
The DID Controller includes their skew-adjusted current timestamp in the <i>anchorFrom</i> property of an operation's data object payload.
To allow for clock skew, the DID Controller subtracts five minutes from their current timestamp.
The timestamp is formatted as a [[RFC7519]] <i>NumericDate</i>.
</p>
<p>
The DID Controller includes their skew-adjusted current timestamp in the <i>anchorUntil</i> property of an operation's data object payload.
To allow for batching and clock skew, the DID Controller adds 25 minutes to their current timestamp.
The timestamp is formatted as a [[RFC7519]] <i>NumericDate</i>.
</p>
<p>
The delta range between <i>anchorFrom</i> and <i>anchorUntil</i> is 30 minutes.
</p>
<p class="issue" title="Protocol parameter for maximum time delta">
TODO: In a followup revision, we will specify protocol parameters to constrain the delta range.
</p>
</section>
</section>
<section class="normative">
<h2>Server-to-Server APIs</h2>
<p>
An Orb Server exposes the [[[ACTIVITYANCHORS]]] API for propagation, content-addressable storage, discovery, and witnessing.
</p>
<section class="normative">
<h3>Anchor Properties</h3>
<p>
Orb specifies anchoring metadata for the Sidetree core index file.
This metadata includes each DID included in the index along with a hashlink to the previous anchor.
The metadata is formatted as a Linkset [[LINKSET]].
</p>
<p>
The <i>anchor</i> property contains the hashlink to the Sidetree core index file.
The <i>profile</i> property contains the version of the Orb spec (e.g., <i>https://w3id.org/orb#v1</i>).
The <i>author</i> property contains the Orb server URI that published the anchor.
The <i>item</i> property contains a collection of the DIDs contained in the Sidetree files (referenced by <i>anchor</i>).
The <i>previous</i> property (within an <i>item</i> contains a hashlink to the previous anchor that contained a Sidetree operation for the DID.
</p>
<pre class="example highlight" title="Orb Anchor Properties">
{
"linkset": [
{
"anchor": "hl:uEiDkZV2rw2XKdqPoGKy6Vg0HEk36HfsxyWfnY3jp3Q2K-g",
"author": "https://orb.domain2.com/services/orb",
"item":[
{"href": "did:orb:uAAA:EiBTRfNkzKwW3ZVDl6WwXsYhre6HPE8jQ7e9l3m6pii-iw"},
{
"href": "did:orb:uAAA:EiCUt537plK2HuI0k2rQNP3MgDtq1T5Wj_LZ7yQOJY2gcA",
"previous": ["hl:uEiA30C_KU_wogvUhJKLUA8bXHqSM_75X1QZQN3z_4VacXQ"]
},
{"href": "did:orb:uAAA:EiDpy0--tFbSNGG-UNce9_yXfRBFQ9kkme8SREFLUiaK6g"},
{"href": "did:orb:uAAA:EiAVOBVLnwIgF6f83JfJUi82mhfAQ2oVKpsZCfkt5tX2aQ"}
],
"profile": "https://w3id.org/orb#v1"
}
]
}
</pre>
</section>
</section>
<section class="normative">
<h2>Anchor Discovery</h2>
<section class="normative">
<h3>Schemes</h3>
<table class="simple">
<thead>
<tr>
<th>Orb URI Scheme</th>
<th>Description</th>
<th>Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td>hl</td>
<td>Hashlink retrieval of anchor</td>
<td><a href="#hashlink"></a></td>
</tr>
<tr>
<td>https</td>
<td>Hostmeta discovery (via https)</td>
<td><a href="#hostmeta"></a></td>
</tr>
<tr>
<td>ipns</td>
<td>Hostmeta discovery (via ipns)</td>
<td><a href="#hostmeta"></a></td>
</tr>
<tr>
<td>ipfs</td>
<td>IPFS retrieval of anchor</td>
<td><a href="#ipfs"></a></td>
</tr>
</tbody>
</table>
</section>
<section class="normative">
<h3>Hashlink</h3>
<p>
The scheme uses a hashlink [[HASHLINK]] including the multihash of the latest anchor object and metadata containing URLs to the anchor object.
The first segment after `did:orb` contains the anchor multihash, the second segment contains the hashlink metadata and the third segment contains the Sidetree DID suffix.
</p>
<pre class="example" title="An Orb DID that uses a Hashlink for anchor retrieval">
did:orb:hl:uEiDlXjleTwr4eZalpXVy086zs-TPK-h54ojbpl7EBvZeHQ:uoQ-Bc2h0dHBzOi8vZXhhbXBsZS5jb20:EiDyOQbbZAa3aiRzeCkV7LOx3SERjjH93EXoIM3UoN4oWg
</pre>
</section>
<section class="normative">
<h3>Hostmeta</h3>
<p>
The hostmeta schemes fetch service discovery information using the JRD form of hostmeta [[RFC6415]].
To retrieve `host-meta.json`, the `scheme` and `path` segments of the Orb DID are converted into a URL.
The DID is transformed into a URL by replacing `:` in the `path` segments with `/` and prefixing the `scheme`.
From the transformed URL, the host-meta.json can be retrieved according to [[RFC6415]].
</p>
<pre class="example" title="An Orb DID that uses the hostmeta HTTPS scheme for anchor discovery">
did:orb:https:example.com:uEiDlXjleTwr4eZalpXVy086zs-TPK-h54ojbpl7EBvZeHQ:EiDyOQbbZAa3aiRzeCkV7LOx3SERjjH93EXoIM3UoN4oWg
</pre>
<pre class="example" title="An Orb DID that uses the hostmeta IPNS scheme for anchor discovery">
did:orb:ipns:k51qzi5uqu5dl3ua2aal8vdw82j4i8s112p495j1spfkd2blqygghwccsw1z0p:uEiDlXjleTwr4eZalpXVy086zs-TPK-h54ojbpl7EBvZeHQ:EiDyOQbbZAa3aiRzeCkV7LOx3SERjjH93EXoIM3UoN4oWg
</pre>
<p class="issue" title="Describe JRD">
Add description and example of Orb JRD.
</p>
<pre class="example" title="Hostmeta JRD">
</pre>
</section>
<section class="normative">
<h3>IPFS</h3>
<p>
The scheme retrieves the anchor object from IPFS.
To retrieve the anchor object, the multihash must be converted into an IPFS URL (containing an IPFS CID).
The multihash is transformed into a CID as follows:
</p>
<ul>
<li>Multibase: base32</li>
<li>CID version: 1</li>
<li>Multicodec: raw (0x55)</li>
<li>Multihash: the anchor multihash in the DID</li>
</ul>
<pre class="example" title="Converting anchor multihash to an IPFS URL containing a CID v1 (base32)">
DID: did:orb:ipfs:uEiDlXjleTwr4eZalpXVy086zs-TPK-h54ojbpl7EBvZeHQ:EiDyOQbbZAa3aiRzeCkV7LOx3SERjjH93EXoIM3UoN4oWg
URL: ipfs://bafkreihfly4v4tyk7b4znjnfovznhtvtwpsm6k7iphrirw5gl3can5s6du
</pre>
</section>
</section>
<section class="normative">
<h2>Witness Ledger</h2>
<section class="normative">
<h3>Ledger Types</h3>
<table class="simple">
<thead>
<tr>
<th>Type Code</th>
<th>Description</th>
<th>Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td>vct-v1</td>
<td>Verifiable Credential Transparency</td>
<td><a href="#vct-v1"></a></td>
</tr>
</tbody>
</table>
</section>
<section class="normative">
<h3>Discovery</h3>
<p>
The linked data proof includes a domain property that indicates the ledger that promises to include an Orb transaction.
The type of the ledger can be determined using the WebFinger protocol [[RFC7033]] along with known replicas, if any.
The replica links have the relation field set to <i>alternate</i>.
</p>
<pre class="example highlight" title="Ledger discovery (request)">
GET /.well-known/webfinger?resource=https%3A%2F%2Fwitness1.example.com%2Fledgers%2Fmaple2021 HTTP/1.1
Host: witness1.example.com
Accept-Encoding: gzip, deflate
</pre>
<p>
When the ledger exists, an HTTP 200 status code is returned.
</p>
<pre class="example highlight" title="Client shared domain discovery (response)">
HTTP/1.1 200 OK
Date: Sat, 30 Jan 2021 18:31:58 GMT
Content-Type: application/jrd+json
Connection: keep-alive
Access-Control-Allow-Origin: *
{
"subject": "https://witness1.example.com/ledgers/maple2021",
"properties": {
"https://trustbloc.dev/ns/ledger-type": "vct-v1"
},
"links": [
{
"rel": "self",
"href": "https://witness1.example.com/ledgers/maple2021"
},
{
"rel": "alternate",
"href": "https://replica.example.com/ledgers/maple2021"
}
]
}
</pre>
</section>
<section class="normative" id="vct-v1">
<h3>Verifiable Credential Transparency (VCT)</h3>
<p>
The Verifiable Credential Transparency (VCT) Witness ledger is based on on certificate transparency [[RFC6962]].
The Anchor Credentials are included into VCT ledgers (as append-only Merkle Tree logs).
VCT ledgers may be named to enable rollover.
</p>
<p>
We extend [[RFC6962]] to include Verifiable Credential (VC) [[VC-DATA-MODEL]] objects.
The following subsections describe the endpoints and the additional VC type for the Merkle Tree.
</p>
<section class="normative">
<h4>Add Verifiable Credential</h4>
<p>
Orb <i>AnchorCredentials</i> are added using the process described in <a href='https://trustbloc.github.io/activityanchors/#witness-activitypub'></a>, as required by Orb.
</p>
</section>
<section class="normative">
<h4>Latest Signed Tree Head</h4>
<p>
The <i>Retrieve Latest Signed Tree Head</i> endpoint is described in <a href="https://tools.ietf.org/html/rfc6962#section-4.3">RFC6962</a>.