forked from oauth-wg/oauth-selective-disclosure-jwt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
draft-ietf-oauth-selective-disclosure-jwt-00.xml
1113 lines (1030 loc) · 56.9 KB
/
draft-ietf-oauth-selective-disclosure-jwt-00.xml
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
<?xml version="1.0" encoding="utf-8"?>
<!-- name="GENERATOR" content="github.com/mmarkdown/mmark Mmark Markdown Processor - mmark.miek.nl" -->
<rfc version="3" ipr="trust200902" docName="draft-ietf-oauth-selective-disclosure-jwt-00" submissionType="IETF" category="std" xml:lang="en" xmlns:xi="http://www.w3.org/2001/XInclude" consensus="true">
<front>
<title abbrev="SD-JWT">Selective Disclosure for JWTs (SD-JWT)</title><seriesInfo value="draft-ietf-oauth-selective-disclosure-jwt-00" stream="IETF" status="standard" name="Internet-Draft"></seriesInfo>
<author initials="D." surname="Fett" fullname="Daniel Fett"><organization>yes.com</organization><address><postal><street></street>
</postal><email>[email protected]</email>
<uri>https://danielfett.de/</uri>
</address></author>
<author initials="K." surname="Yasuda" fullname="Kristina Yasuda"><organization>Microsoft</organization><address><postal><street></street>
</postal><email>[email protected]</email>
</address></author>
<date/>
<area>Security</area>
<workgroup>Web Authorization Protocol</workgroup>
<keyword>security</keyword>
<keyword>oauth2</keyword>
<abstract>
<t>This document specifies conventions for creating JSON Web Token (JWT)
documents that support selective disclosure of JWT claim values.</t>
</abstract>
</front>
<middle>
<section anchor="Introduction"><name>Introduction</name>
<t>The JSON-based representation of claims in a signed JSON Web Token (JWT) <xref target="RFC7519"></xref> is
secured against modification using JSON Web Signature (JWS) <xref target="RFC7515"></xref> digital
signatures. A consumer of a signed JWT that has checked the
signature can safely assume that the contents of the token have not been
modified. However, anyone receiving an unencrypted JWT can read all of the
claims and likewise, anyone with the decryption key receiving an encrypted JWT
can also read all of the claims.</t>
<t>This document describes a format for signed JWTs that supports selective
disclosure (SD-JWT), enabling sharing only a subset of the claims included in
the original signed JWT instead of releasing all the claims to every verifier.
During issuance, an SD-JWT is sent from the issuer to the holder alongside an
SD-JWT Salt/Value Container (SVC), a JSON object that contains the mapping
between raw claim values contained in the SD-JWT and the salts for each claim
value.</t>
<t>This document also defines a format for SD-JWT Releases (SD-JWT-R), which convey
a subset of the claim values of an SD-JWT to the verifier. For presentation, the
holder creates an SD-JWT-R and sends it together with the SD-JWT to the
verifier. To verify claim values received in SD-JWT-R, the verifier uses the
salts values in the SD-JWT-R to compute the hash digests of the claim values and
compare them to the ones in the SD-JWT.</t>
<t>One of the common use cases of a signed JWT is representing a user's identity
created by an issuer. As long as the signed JWT is one-time use, it typically
only contains those claims the user has consented to release to a specific
verifier. However, when a signed JWT is intended to be multi-use, it needs to
contain the superset of all claims the user might want to release to verifiers
at some point. The ability to selectively disclose a subset of these claims
depending on the verifier becomes crucial to ensure minimum disclosure and
prevent verifiers from obtaining claims irrelevant for the transaction at hand.</t>
<t>One example of such a multi-use JWT is a verifiable credential, a
tamper-evident credential with a cryptographically verifiable authorship that
contains claims about a subject. SD-JWTs defined in this document enable such
selective disclosure of claims.</t>
<t>While JWTs for claims describing natural persons are a common use case, the
mechanisms defined in this document can be used for many other use cases as
well.</t>
<t>This document also describes holder binding, or the concept of binding SD-JWT to
key material controlled by the subject of SD-JWT. Holder binding is optional to
implement.</t>
<section anchor="conventions-and-terminology"><name>Conventions and Terminology</name>
<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED",
"MAY", and "OPTIONAL" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"></xref> <xref target="RFC8174"></xref> when, and only when, they
appear in all capitals, as shown here.</t>
<t><strong>base64url</strong> denotes the URL-safe base64 encoding without padding defined in
Section 2 of <xref target="RFC7515"></xref>.</t>
</section>
</section>
<section anchor="terms-and-definitions"><name>Terms and Definitions</name>
<dl>
<dt>Selectively Disclosable JWT (SD-JWT)</dt>
<dd><t>A JWT <xref target="RFC7515"></xref> created by the issuer, which is signed as a JWS <xref target="RFC7515"></xref>,
that supports selective disclosure as defined in this document.</t>
</dd>
<dt>SD-JWT Salt/Value Container (SVC)</dt>
<dd><t>A JSON object created by the issuer that contains mapping between
raw claim values contained in the SD-JWT and the salts for each claim value.</t>
</dd>
<dt>SD-JWT Release (SD-JWT-R)</dt>
<dd><t>A JWT created by the holder that contains a subset of the claim values of an SD-JWT in a verifiable way.</t>
</dd>
<dt>Holder binding</dt>
<dd><t>Ability of the holder to prove legitimate possession of SD-JWT by proving
control over the same private key during the issuance and presentation. SD-JWT signed by the issuer contains
a public key or a reference to a public key that matches to the private key controlled by the holder.</t>
</dd>
<dt>Issuer</dt>
<dd><t>An entity that creates SD-JWTs (2.1).</t>
</dd>
<dt>Holder</dt>
<dd><t>An entity that received SD-JWTs (2.1) from the issuer and has control over them.</t>
</dd>
<dt>Verifier</dt>
<dd><t>An entity that requests, checks and extracts the claims from SD-JWT-R (2.2)</t>
</dd>
</dl>
<t>Note: discuss if we want to include Client, Authorization Server for the purpose of
ensuring continuity and separating the entity from the actor.</t>
</section>
<section anchor="flow-diagram"><name>Flow Diagram</name>
<figure><name>SD-JWT Issuance and Presentation Flow
</name>
<sourcecode type="ascii-art"> +------------+
| |
| Issuer |
| |
+------------+
|
Issues
SD-JWT and SVC
|
v
+------------+
| |
| Holder |
| |
+------------+
|
Presents
SD-JWT-R and SD-JWT
|
v
+-------------+
| |+
| Verifiers ||+
| |||
+-------------+||
+-------------+|
+-------------+
</sourcecode>
</figure>
</section>
<section anchor="concepts"><name>Concepts</name>
<t>In the following, the contents of SD-JWTs and SD-JWT Releases are described at a
conceptual level, abstracting from the data formats described afterwards.</t>
<section anchor="creating-an-sd-jwt"><name>Creating an SD-JWT</name>
<t>An SD-JWT, at its core, is a digitally signed document containing hash digests over the claim values with unique random salts and other metadata.
It MUST be digitally signed using the issuer's private key.</t>
<artwork>SD-JWT-DOC = (METADATA, SD-CLAIMS)
SD-JWT = SD-JWT-DOC | SIG(SD-JWT-DOC, ISSUER-PRIV-KEY)
</artwork>
<t><tt>SD-CLAIMS</tt> can be a simple object with claim names mapped to hash digests over the claim values with unique random salts:</t>
<artwork>SD-CLAIMS = (
CLAIM-NAME: HASH(SALT | CLAIM-VALUE)
)*
</artwork>
<t><tt>SD-CLAIMS</tt> can also be nested deeper to capture more complex objects, as will be shown later.</t>
<t><tt>SD-JWT</tt> is sent from the issuer to the holder, together with the mapping of the plain-text claim values, the salt values, and potentially some other information.</t>
</section>
<section anchor="creating-an-sd-jwt-release"><name>Creating an SD-JWT Release</name>
<t>To disclose to a verifier a subset of the SD-JWT claim values, a holder creates a JWT such as the
following:</t>
<artwork>SD-JWT-RELEASE-DOC = (METADATA, SD-RELEASES)
SD-JWT-RELEASE = SD-JWT-RELEASE-DOC
</artwork>
<t><tt>SD-RELEASES</tt> follows the structure of <tt>SD-CLAIMS</tt> and can be a simple object with claim names mapped to values and salts:</t>
<artwork>SD-RELEASES = (
CLAIM-NAME: (DISCLOSED-SALT, DISCLOSED-VALUE)
)
</artwork>
<t>Just as <tt>SD-CLAIMS</tt>, <tt>SD-RELEASES</tt> can be more complex as well.</t>
<t><tt>SD-JWT-RELEASE</tt> is sent together with <tt>SD-JWT</tt> from the holder to the
verifier.</t>
</section>
<section anchor="optional-holder-binding"><name>Optional Holder Binding</name>
<t>Some use-cases may require holder binding.</t>
<t>If holder binding is desired, <tt>SD-JWT</tt> must contain information about key material controlled by the holder:</t>
<artwork>SD-JWT-DOC = (METADATA, HOLDER-PUBLIC-KEY, SD-CLAIMS)
</artwork>
<t>Note: How the public key is included in SD-JWT is out of scope of this document. It can be passed by value or by reference.</t>
<t>With holder binding, the <tt>SD-JWT-RELEASE</tt> is signed by the holder using its private key. It therefore looks as follows:</t>
<artwork>SD-JWT-RELEASE = SD-JWT-RELEASE-DOC | SIG(SD-JWT-RELEASE-DOC, HOLDER-PRIV-KEY)
</artwork>
</section>
<section anchor="verifying-an-sd-jwt-release"><name>Verifying an SD-JWT Release</name>
<t>A verifier checks that</t>
<ul>
<li><t>for each claim in <tt>SD-JWT-RELEASE</tt>, the hash digest <tt>HASH(DISCLOSED-SALT | DISCLOSED-VALUE)</tt>
matches the one under the given claim name in <tt>SD-JWT</tt>.</t>
</li>
<li><t>if holder binding is used, the <tt>SD-JWT-RELEASE</tt> was signed by
the private key belonging to <tt>HOLDER-PUBLIC-KEY</tt>.</t>
</li>
</ul>
<t>The detailed algorithm is described below.</t>
</section>
</section>
<section anchor="data-formats"><name>Data Formats</name>
<t>This section defines data formats for SD-JWTs (containing hash digests of the salted
claim values), SD-JWT Salt/Value Containers (containing the mapping of the
plain-text claim values and the salt values), and SD-JWT Releases (containing a
subset of the same mapping).</t>
<section anchor="format-of-an-sd-jwt"><name>Format of an SD-JWT</name>
<t>An SD-JWT is a JWT that MUST be signed using the issuer's private key. The
payload of an SD-JWT MUST contain the <tt>sd_digests</tt> and <tt>sd_hash_alg</tt> claims
described in the following, and MAY contain a holder's public key or a reference
thereto, as well as further claims such as <tt>iss</tt>, <tt>iat</tt>, etc. as defined or
required by the application using SD-JWTs.</t>
<section anchor="sd-digests-claim-digests-of-selectively-disclosable-claims"><name><tt>sd_digests</tt> Claim (Digests of Selectively Disclosable Claims)</name>
<t>An SD-JWT MUST include hash digests of the salted claim values that are included by the issuer
under the property <tt>sd_digests</tt>.</t>
<t>The issuer MUST choose a unique and cryptographically random salt value
for each claim value. Each salt value
SHOULD contain at least 128 bits of pseudorandom data, making it hard for an
attacker to guess. The salt value MUST then be encoded as a string. It is
RECOMMENDED to base64url-encode the salt value.</t>
<t>The issuer MUST build the digests by hashing over a string that is formed by
JSON-encoding an ordered array containing the salt and the claim value, e.g.:
<tt>["6qMQvRL5haj","Peter"]</tt>. The digest value is then base64url-encoded. Note that
the precise JSON encoding can vary, and therefore, the JSON encodings MUST be
sent to the holder along with the SD-JWT, as described below.</t>
<section anchor="flat-and-structured-sd-digests-objects"><name>Flat and Structured <tt>sd_digests</tt> objects</name>
<t>The <tt>sd_digests</tt> object can be a 'flat' object, directly containing all claim
names and hashed claim values without any deeper structure. The <tt>sd_digests</tt>
object can also be a 'structured' object, where some claims and their respective
hash digests are contained in places deeper in the structure. It is at the issuer's
discretion whether to use a 'flat' or 'structured' <tt>sd_digests</tt> SD-JWT object,
and how to structure it such that it is suitable for the use case.</t>
<t>Example 1 below is a non-normative example of an SD-JWT using a 'flat'
<tt>sd_digests</tt> object and Example 2 in the appendix shows a non-normative example
of an SD-JWT using a 'structured' <tt>sd_digests</tt> object. The difference between
the examples is how the <tt>address</tt> claim is disclosed.</t>
<t>Appendix 2 shows a more complex example using claims from eKYC (todo:
reference).</t>
</section>
</section>
<section anchor="hash-function-claim"><name>Hash Function Claim</name>
<t>The claim <tt>sd_hash_alg</tt> indicates the hash algorithm used by the Issuer to generate
the hashes of the salted claim values. The hash algorithm identifier MUST be a
value from the "Hash Name String" column in the IANA "Named Information Hash
Algorithm" registry [IANA.Hash.Algorithms]. SD-JWTs with hash algorithm
identifiers not found in this registry are not considered valid and MUST NOT be
accepted by verifiers.</t>
<t>To promote interoperability, implementations MUST support the SHA-256 hash algorithm.</t>
</section>
<section anchor="holder-public-key-claim"><name>Holder Public Key Claim</name>
<t>If the issuer wants to enable holder binding, it MAY include a public key
associated with the holder, or a reference thereto.</t>
<t>It is out of the scope of this document to describe how the holder key pair is
established. For example, the holder MAY provide a key pair to the issuer,
the issuer MAY create the key pair for the holder, or
holder and issuer MAY use pre-established key material.</t>
<t>Note: Examples in this document use <tt>cnf</tt> Claim defined in <xref target="RFC7800"></xref> to include raw public key by value in SD-JWT.</t>
</section>
</section>
<section anchor="example-1-sd-jwt"><name>Example 1: SD-JWT</name>
<t>This example and Example 2 in the appendix use the following object as the set
of claims that the Issuer is issuing:</t>
<sourcecode anchor="example-simple-user_claims" type="json">{
"sub": "6c5c0a49-b589-431d-bae7-219122a9ec2c",
"given_name": "John",
"family_name": "Doe",
"email": "[email protected]",
"phone_number": "+1-202-555-0101",
"address": {
"street_address": "123 Main St",
"locality": "Anytown",
"region": "Anystate",
"country": "US"
},
"birthdate": "1940-01-01"
}
</sourcecode>
<t>The following non-normative example shows the payload of an SD-JWT. The issuer
is using a flat structure, i.e., all of the claims the <tt>address</tt> claim can only
be disclosed in full.</t>
<sourcecode anchor="example-simple-sd_jwt_payload" type="json">{
"iss": "https://example.com/issuer",
"cnf": {
"jwk" : {
"kty": "RSA",
"n": "pm4bOHBg-oYhAyPWzR56AWX3rUIXp11_ICDkGgS6W3ZWLts-hzwI3x65659kg4hVo9dbGoCJE3ZGF_eaetE30UhBUEgpGwrDrQiJ9zqprmcFfr3qvvkGjtth8Zgl1eM2bJcOwE7PCBHWTKWYs152R7g6Jg2OVph-a8rq-q79MhKG5QoW_mTz10QT_6H4c7PjWG1fjh8hpWNnbP_pv6d1zSwZfc5fl6yVRL0DV0V3lGHKe2Wqf_eNGjBrBLVklDTk8-stX_MWLcR-EGmXAOv0UBWitS_dXJKJu-vXJyw14nHSGuxTIK2hx1pttMft9CsvqimXKeDTU14qQL1eE7ihcw",
"e": "AQAB"
}
},
"iat": 1516239022,
"exp": 1516247022,
"sd_hash_alg": "sha-256",
"sd_digests": {
"sub": "z4xgEco94diTaSruISPiE7o_wtmcOfnH_8R7X9Pa578",
"given_name": "PvU7cWjuHUq6w-i9XFpQZhjT-uprQL3GH3mKsAJl0e0",
"family_name": "H-Relr4cEBMlenyK1gvyx16QVpnt4MEclT5tP0aTLFU",
"email": "ET2A1JQLF85ZpBulh6UFstGrSfR4B3KM-bjQVllhxqY",
"phone_number": "SJnciB2DIRVA5cXBrdKoH6n45788mZyUn2rnv74uMVU",
"address": "0FldqLfGnERPPVDC17od9xb4w3iRJTEQbW_Yk9AmnDw",
"birthdate": "-L0kMgIbLXe3OEkKTUGwz_QKhjehDeofKGwoPrxLuo4"
}
}
</sourcecode>
<t>The SD-JWT is then signed by the issuer to create a document like the following:</t>
<artwork anchor="example-simple-serialized_sd_jwt">eyJhbGciOiAiUlMyNTYiLCAia2lkIjogImNBRUlVcUowY21MekQxa3pHemhlaUJhZzBZUk
F6VmRsZnhOMjgwTmdIYUEifQ.eyJpc3MiOiAiaHR0cHM6Ly9leGFtcGxlLmNvbS9pc3N1Z
XIiLCAic3ViX2p3ayI6IHsia3R5IjogIlJTQSIsICJuIjogInBtNGJPSEJnLW9ZaEF5UFd
6UjU2QVdYM3JVSVhwMTFfSUNEa0dnUzZXM1pXTHRzLWh6d0kzeDY1NjU5a2c0aFZvOWRiR
29DSkUzWkdGX2VhZXRFMzBVaEJVRWdwR3dyRHJRaUo5enFwcm1jRmZyM3F2dmtHanR0aDh
aZ2wxZU0yYkpjT3dFN1BDQkhXVEtXWXMxNTJSN2c2SmcyT1ZwaC1hOHJxLXE3OU1oS0c1U
W9XX21UejEwUVRfNkg0YzdQaldHMWZqaDhocFdObmJQX3B2NmQxelN3WmZjNWZsNnlWUkw
wRFYwVjNsR0hLZTJXcWZfZU5HakJyQkxWa2xEVGs4LXN0WF9NV0xjUi1FR21YQU92MFVCV
2l0U19kWEpLSnUtdlhKeXcxNG5IU0d1eFRJSzJoeDFwdHRNZnQ5Q3N2cWltWEtlRFRVMTR
xUUwxZUU3aWhjdyIsICJlIjogIkFRQUIifSwgImlhdCI6IDE1MTYyMzkwMjIsICJleHAiO
iAxNTE2MjQ3MDIyLCAiaGFzaF9hbGciOiAic2hhLTI1NiIsICJzZF9kaWdlc3RzIjogeyJ
zdWIiOiAiejR4Z0Vjbzk0ZGlUYVNydUlTUGlFN29fd3RtY09mbkhfOFI3WDlQYTU3OCIsI
CJnaXZlbl9uYW1lIjogIlB2VTdjV2p1SFVxNnctaTlYRnBRWmhqVC11cHJRTDNHSDNtS3N
BSmwwZTAiLCAiZmFtaWx5X25hbWUiOiAiSC1SZWxyNGNFQk1sZW55SzFndnl4MTZRVnBud
DRNRWNsVDV0UDBhVExGVSIsICJlbWFpbCI6ICJFVDJBMUpRTEY4NVpwQnVsaDZVRnN0R3J
TZlI0QjNLTS1ialFWbGxoeHFZIiwgInBob25lX251bWJlciI6ICJTSm5jaUIyRElSVkE1Y
1hCcmRLb0g2bjQ1Nzg4bVp5VW4ycm52NzR1TVZVIiwgImFkZHJlc3MiOiAiMEZsZHFMZkd
uRVJQUFZEQzE3b2Q5eGI0dzNpUkpURVFiV19ZazlBbW5EdyIsICJiaXJ0aGRhdGUiOiAiL
Uwwa01nSWJMWGUzT0VrS1RVR3d6X1FLaGplaERlb2ZLR3dvUHJ4THVvNCJ9fQ.TSxRFVMl
Nlt_drWLqQuzz9Sc19Bo5r-cgXZ0to8PfadImEJuPbhfkxCSt1xCT5IWQJrD6p_47h8Ac-
5yOtuu8s-wxrQzCUAU7OS2ThQGKiDKsGv0oiH3KQX4QyCAOIIaWOLxO6VQRxI7Kn6RFT0M
5jQxBNFmL582n_uJR31ANBO45Jc_pgp4iSTn2vf1lxxwU7B3bgrad0vHmvwmv1lu17Ov79
SGmT_fTjoybIJfHavTq61xCJ3UrMAGCEqm-_laOTxB1HRbPF38va0iuhqSSk2QaUpfDsVb
9VsPBVIx_MsGlK3kYUWcHzkJ0BBPIVu0xnVcLkg1_SO_5gPSxFWZ4g
</artwork>
<t>(Line breaks for presentation only.)</t>
</section>
<section anchor="format-of-a-sd-jwt-salt-value-container-svc"><name>Format of a SD-JWT Salt/Value Container (SVC)</name>
<t>Besides the SD-JWT itself, the holder needs to learn the raw claim values that
are contained in the SD-JWT, along with the precise input to the hash
calculation, and the salts. There MAY be other information the issuer needs to
communicate to the holder, such as a private key if the issuer selected the
holder key pair.</t>
<t>A SD-JWT Salt/Value Container (SVC) is a JSON object containing at least the
top-level property <tt>sd_release</tt>. Its structure mirrors the one of <tt>sd_digests</tt> in
the SD-JWT, but the values are the inputs to the hash calculations the issuer
used, as strings.</t>
<t>The SVC MAY contain further properties, for example, to transport the holder
private key.</t>
</section>
<section anchor="example-svc-for-the-flat-sd-jwt-in-example-1"><name>Example: SVC for the Flat SD-JWT in Example 1</name>
<t>The SVC for Example 1 is as follows:</t>
<sourcecode anchor="example-simple-svc_payload" type="json">{
"sd_release": {
"sub": "[\"2GLC42sKQveCfGfryNRN9w\", \"6c5c0a49-b589-431d-bae7-219122a9ec2c\"]",
"given_name": "[\"eluV5Og3gSNII8EYnsxA_A\", \"John\"]",
"family_name": "[\"6Ij7tM-a5iVPGboS5tmvVA\", \"Doe\"]",
"email": "[\"eI8ZWm9QnKPpNPeNenHdhQ\", \"[email protected]\"]",
"phone_number": "[\"Qg_O64zqAxe412a108iroA\", \"+1-202-555-0101\"]",
"address": "[\"AJx-095VPrpTtN4QMOqROA\", {\"street_address\": \"123 Main St\", \"locality\": \"Anytown\", \"region\": \"Anystate\", \"country\": \"US\"}]",
"birthdate": "[\"Pc33JM2LchcU_lHggv_ufQ\", \"1940-01-01\"]"
}
}
</sourcecode>
<t>Important: As described above, hash digests are calculated over the string formed by
serializing a JSON array containing the salt and the claim value. This ensures
that issuer and verifier use the same input to their hash functions and avoids
issues with canonicalization of JSON values that would lead to different hash
digests. The SVC therefore maps claim names to JSON-encoded arrays.</t>
</section>
<section anchor="sending-sd-jwt-and-svc-during-issuance"><name>Sending SD-JWT and SVC during Issuance</name>
<t>For transporting the SVC together with the SD-JWT from the issuer to the holder,
the SVC is base64url-encoded and appended to the SD-JWT using a period character <tt>.</tt> as the
separator.</t>
<t>The SVC and SD-JWT are implicitly linked through the hash values of the claims
in the SVC that is included in the SD-JWT. To ensure that the correct SVC and
SD-JWT pairings are being used, the holder SHOULD verify the binding between
SVC and SD-JWT as defined in the Verification Section of this document.</t>
<t>For Example 1, the combined format looks as follows:</t>
<artwork anchor="example-simple-combined_sd_jwt_svc">eyJhbGciOiAiUlMyNTYiLCAia2lkIjogImNBRUlVcUowY21MekQxa3pHemhlaUJhZzBZUk
F6VmRsZnhOMjgwTmdIYUEifQ.eyJpc3MiOiAiaHR0cHM6Ly9leGFtcGxlLmNvbS9pc3N1Z
XIiLCAic3ViX2p3ayI6IHsia3R5IjogIlJTQSIsICJuIjogInBtNGJPSEJnLW9ZaEF5UFd
6UjU2QVdYM3JVSVhwMTFfSUNEa0dnUzZXM1pXTHRzLWh6d0kzeDY1NjU5a2c0aFZvOWRiR
29DSkUzWkdGX2VhZXRFMzBVaEJVRWdwR3dyRHJRaUo5enFwcm1jRmZyM3F2dmtHanR0aDh
aZ2wxZU0yYkpjT3dFN1BDQkhXVEtXWXMxNTJSN2c2SmcyT1ZwaC1hOHJxLXE3OU1oS0c1U
W9XX21UejEwUVRfNkg0YzdQaldHMWZqaDhocFdObmJQX3B2NmQxelN3WmZjNWZsNnlWUkw
wRFYwVjNsR0hLZTJXcWZfZU5HakJyQkxWa2xEVGs4LXN0WF9NV0xjUi1FR21YQU92MFVCV
2l0U19kWEpLSnUtdlhKeXcxNG5IU0d1eFRJSzJoeDFwdHRNZnQ5Q3N2cWltWEtlRFRVMTR
xUUwxZUU3aWhjdyIsICJlIjogIkFRQUIifSwgImlhdCI6IDE1MTYyMzkwMjIsICJleHAiO
iAxNTE2MjQ3MDIyLCAiaGFzaF9hbGciOiAic2hhLTI1NiIsICJzZF9kaWdlc3RzIjogeyJ
zdWIiOiAiejR4Z0Vjbzk0ZGlUYVNydUlTUGlFN29fd3RtY09mbkhfOFI3WDlQYTU3OCIsI
CJnaXZlbl9uYW1lIjogIlB2VTdjV2p1SFVxNnctaTlYRnBRWmhqVC11cHJRTDNHSDNtS3N
BSmwwZTAiLCAiZmFtaWx5X25hbWUiOiAiSC1SZWxyNGNFQk1sZW55SzFndnl4MTZRVnBud
DRNRWNsVDV0UDBhVExGVSIsICJlbWFpbCI6ICJFVDJBMUpRTEY4NVpwQnVsaDZVRnN0R3J
TZlI0QjNLTS1ialFWbGxoeHFZIiwgInBob25lX251bWJlciI6ICJTSm5jaUIyRElSVkE1Y
1hCcmRLb0g2bjQ1Nzg4bVp5VW4ycm52NzR1TVZVIiwgImFkZHJlc3MiOiAiMEZsZHFMZkd
uRVJQUFZEQzE3b2Q5eGI0dzNpUkpURVFiV19ZazlBbW5EdyIsICJiaXJ0aGRhdGUiOiAiL
Uwwa01nSWJMWGUzT0VrS1RVR3d6X1FLaGplaERlb2ZLR3dvUHJ4THVvNCJ9fQ.TSxRFVMl
Nlt_drWLqQuzz9Sc19Bo5r-cgXZ0to8PfadImEJuPbhfkxCSt1xCT5IWQJrD6p_47h8Ac-
5yOtuu8s-wxrQzCUAU7OS2ThQGKiDKsGv0oiH3KQX4QyCAOIIaWOLxO6VQRxI7Kn6RFT0M
5jQxBNFmL582n_uJR31ANBO45Jc_pgp4iSTn2vf1lxxwU7B3bgrad0vHmvwmv1lu17Ov79
SGmT_fTjoybIJfHavTq61xCJ3UrMAGCEqm-_laOTxB1HRbPF38va0iuhqSSk2QaUpfDsVb
9VsPBVIx_MsGlK3kYUWcHzkJ0BBPIVu0xnVcLkg1_SO_5gPSxFWZ4g.eyJzZF9yZWxlYXN
lIjogeyJzdWIiOiAiW1wiMkdMQzQyc0tRdmVDZkdmcnlOUk45d1wiLCBcIjZjNWMwYTQ5L
WI1ODktNDMxZC1iYWU3LTIxOTEyMmE5ZWMyY1wiXSIsICJnaXZlbl9uYW1lIjogIltcImV
sdVY1T2czZ1NOSUk4RVluc3hBX0FcIiwgXCJKb2huXCJdIiwgImZhbWlseV9uYW1lIjogI
ltcIjZJajd0TS1hNWlWUEdib1M1dG12VkFcIiwgXCJEb2VcIl0iLCAiZW1haWwiOiAiW1w
iZUk4WldtOVFuS1BwTlBlTmVuSGRoUVwiLCBcImpvaG5kb2VAZXhhbXBsZS5jb21cIl0iL
CAicGhvbmVfbnVtYmVyIjogIltcIlFnX082NHpxQXhlNDEyYTEwOGlyb0FcIiwgXCIrMS0
yMDItNTU1LTAxMDFcIl0iLCAiYWRkcmVzcyI6ICJbXCJBSngtMDk1VlBycFR0TjRRTU9xU
k9BXCIsIHtcInN0cmVldF9hZGRyZXNzXCI6IFwiMTIzIE1haW4gU3RcIiwgXCJsb2NhbGl
0eVwiOiBcIkFueXRvd25cIiwgXCJyZWdpb25cIjogXCJBbnlzdGF0ZVwiLCBcImNvdW50c
nlcIjogXCJVU1wifV0iLCAiYmlydGhkYXRlIjogIltcIlBjMzNKTTJMY2hjVV9sSGdndl9
1ZlFcIiwgXCIxOTQwLTAxLTAxXCJdIn19
</artwork>
<t>(Line breaks for presentation only.)</t>
</section>
<section anchor="format-of-an-sd-jwt-release"><name>Format of an SD-JWT Release</name>
<t>SD-JWT-R contains claim values and the salts of the claims that the holder
has consented to release to the Verifier. This enables the Verifier to verify
the claims received from the holder by computing the hash digests of the claim
values and the salts revealed in the SD-JWT-R using the hashing algorithm
specified in SD-JWT and comparing them to the hash digests included in SD-JWT.</t>
<t>For each claim, an array of the salt and the claim value is contained in the
<tt>sd_release</tt> object. The structure of <tt>sd_release</tt> object in the SD-JWT-R is the same as in SD-JWT.</t>
<t>The SD-JWT-R MAY contain further claims, for example, to ensure a binding
to a concrete transaction (in the example the <tt>nonce</tt> and <tt>aud</tt> claims).</t>
<t>When the holder sends the SD-JWT-R to the Verifier, the SD-JWT-R MUST be a JWS
represented as the JWS Compact Serialization as described in
Section 7.1 of <xref target="RFC7515"></xref>.</t>
<t>If holder binding is desired, the SD-JWT-R is signed by the holder. If no
holder binding is to be used, the <tt>none</tt> algorithm is used, i.e., the document
is not signed. TODO: Change to plain base64 to avoid alg=none issues</t>
</section>
<section anchor="example-sd-jwt-release-for-example-1"><name>Example: SD-JWT Release for Example 1</name>
<t>The following is a non-normative example of the contents of an SD-JWT-R for Example 1:</t>
<sourcecode anchor="example-simple-sd_jwt_release_payload" type="json">{
"nonce": "XZOUco1u_gEPknxS78sWWg",
"aud": "https://example.com/verifier",
"sd_release": {
"given_name": "[\"eluV5Og3gSNII8EYnsxA_A\", \"John\"]",
"family_name": "[\"6Ij7tM-a5iVPGboS5tmvVA\", \"Doe\"]",
"address": "[\"AJx-095VPrpTtN4QMOqROA\", {\"street_address\": \"123 Main St\", \"locality\": \"Anytown\", \"region\": \"Anystate\", \"country\": \"US\"}]"
}
}
</sourcecode>
<t>For each claim, an array of the salt and the claim value is contained in the
<tt>sd_release</tt> object.</t>
<t>Again, the SD-JWT-R follows the same structure as the <tt>sd_digests</tt> in the SD-JWT.</t>
<t>Below is a non-normative example of a representation of the SD-JWT-R JWS Compact
Serialization:</t>
<artwork anchor="example-simple-serialized_sd_jwt_release">eyJhbGciOiAiUlMyNTYiLCAia2lkIjogIkxkeVRYd0F5ZnJpcjRfVjZORzFSYzEwVThKZE
xZVHJFQktKaF9oNWlfclUifQ.eyJub25jZSI6ICJYWk9VY28xdV9nRVBrbnhTNzhzV1dnI
iwgImF1ZCI6ICJodHRwczovL2V4YW1wbGUuY29tL3ZlcmlmaWVyIiwgInNkX3JlbGVhc2U
iOiB7ImdpdmVuX25hbWUiOiAiW1wiZWx1VjVPZzNnU05JSThFWW5zeEFfQVwiLCBcIkpva
G5cIl0iLCAiZmFtaWx5X25hbWUiOiAiW1wiNklqN3RNLWE1aVZQR2JvUzV0bXZWQVwiLCB
cIkRvZVwiXSIsICJhZGRyZXNzIjogIltcIkFKeC0wOTVWUHJwVHRONFFNT3FST0FcIiwge
1wic3RyZWV0X2FkZHJlc3NcIjogXCIxMjMgTWFpbiBTdFwiLCBcImxvY2FsaXR5XCI6IFw
iQW55dG93blwiLCBcInJlZ2lvblwiOiBcIkFueXN0YXRlXCIsIFwiY291bnRyeVwiOiBcI
lVTXCJ9XSJ9fQ.j5jtArW1QDK1BNM13sJbQaE00GsAhhiPRYi6oK-iJRtLWE6DAgcWxDir
TvxTnuo7Mbb6gSqGTmdEEtmscWxweFfGQoddObPTDiapjWiR1bUMMqPDKNNkRe0CBkU-pW
ieYWN-fQxlRa4BKUqs18jcvGtTGA8Ye-i6t2xLROeXf2U_Seko8b7MQWIFHdbc0LvEFt_-
JAcqeshH5wjVkwhHofVuZq1vGLlINKBveKA2dmn6wuEzi6XRceTwFrG_hTECagfobdO-bY
MF3FSiCQM2KxC_6_aLApYo0aH3zjBv9rm0qNmnL_JGN5FIu6YqwhvPzfdsfkjMd68o8LTW
d7F6kQ
</artwork>
<t>(Line breaks for presentation only.)</t>
</section>
<section anchor="sending-sd-jwt-and-sd-jwt-r-during-presentation"><name>Sending SD-JWT and SD-JWT-R during Presentation</name>
<t>The SD-JWT and the SD-JWT-R can be combined into one document using period character <tt>.</tt> as a separator (here for Example 1):</t>
<artwork anchor="example-simple-combined_sd_jwt_sd_jwt_release">eyJhbGciOiAiUlMyNTYiLCAia2lkIjogImNBRUlVcUowY21MekQxa3pHemhlaUJhZzBZUk
F6VmRsZnhOMjgwTmdIYUEifQ.eyJpc3MiOiAiaHR0cHM6Ly9leGFtcGxlLmNvbS9pc3N1Z
XIiLCAic3ViX2p3ayI6IHsia3R5IjogIlJTQSIsICJuIjogInBtNGJPSEJnLW9ZaEF5UFd
6UjU2QVdYM3JVSVhwMTFfSUNEa0dnUzZXM1pXTHRzLWh6d0kzeDY1NjU5a2c0aFZvOWRiR
29DSkUzWkdGX2VhZXRFMzBVaEJVRWdwR3dyRHJRaUo5enFwcm1jRmZyM3F2dmtHanR0aDh
aZ2wxZU0yYkpjT3dFN1BDQkhXVEtXWXMxNTJSN2c2SmcyT1ZwaC1hOHJxLXE3OU1oS0c1U
W9XX21UejEwUVRfNkg0YzdQaldHMWZqaDhocFdObmJQX3B2NmQxelN3WmZjNWZsNnlWUkw
wRFYwVjNsR0hLZTJXcWZfZU5HakJyQkxWa2xEVGs4LXN0WF9NV0xjUi1FR21YQU92MFVCV
2l0U19kWEpLSnUtdlhKeXcxNG5IU0d1eFRJSzJoeDFwdHRNZnQ5Q3N2cWltWEtlRFRVMTR
xUUwxZUU3aWhjdyIsICJlIjogIkFRQUIifSwgImlhdCI6IDE1MTYyMzkwMjIsICJleHAiO
iAxNTE2MjQ3MDIyLCAiaGFzaF9hbGciOiAic2hhLTI1NiIsICJzZF9kaWdlc3RzIjogeyJ
zdWIiOiAiejR4Z0Vjbzk0ZGlUYVNydUlTUGlFN29fd3RtY09mbkhfOFI3WDlQYTU3OCIsI
CJnaXZlbl9uYW1lIjogIlB2VTdjV2p1SFVxNnctaTlYRnBRWmhqVC11cHJRTDNHSDNtS3N
BSmwwZTAiLCAiZmFtaWx5X25hbWUiOiAiSC1SZWxyNGNFQk1sZW55SzFndnl4MTZRVnBud
DRNRWNsVDV0UDBhVExGVSIsICJlbWFpbCI6ICJFVDJBMUpRTEY4NVpwQnVsaDZVRnN0R3J
TZlI0QjNLTS1ialFWbGxoeHFZIiwgInBob25lX251bWJlciI6ICJTSm5jaUIyRElSVkE1Y
1hCcmRLb0g2bjQ1Nzg4bVp5VW4ycm52NzR1TVZVIiwgImFkZHJlc3MiOiAiMEZsZHFMZkd
uRVJQUFZEQzE3b2Q5eGI0dzNpUkpURVFiV19ZazlBbW5EdyIsICJiaXJ0aGRhdGUiOiAiL
Uwwa01nSWJMWGUzT0VrS1RVR3d6X1FLaGplaERlb2ZLR3dvUHJ4THVvNCJ9fQ.TSxRFVMl
Nlt_drWLqQuzz9Sc19Bo5r-cgXZ0to8PfadImEJuPbhfkxCSt1xCT5IWQJrD6p_47h8Ac-
5yOtuu8s-wxrQzCUAU7OS2ThQGKiDKsGv0oiH3KQX4QyCAOIIaWOLxO6VQRxI7Kn6RFT0M
5jQxBNFmL582n_uJR31ANBO45Jc_pgp4iSTn2vf1lxxwU7B3bgrad0vHmvwmv1lu17Ov79
SGmT_fTjoybIJfHavTq61xCJ3UrMAGCEqm-_laOTxB1HRbPF38va0iuhqSSk2QaUpfDsVb
9VsPBVIx_MsGlK3kYUWcHzkJ0BBPIVu0xnVcLkg1_SO_5gPSxFWZ4g.eyJhbGciOiAiUlM
yNTYiLCAia2lkIjogIkxkeVRYd0F5ZnJpcjRfVjZORzFSYzEwVThKZExZVHJFQktKaF9oN
WlfclUifQ.eyJub25jZSI6ICJYWk9VY28xdV9nRVBrbnhTNzhzV1dnIiwgImF1ZCI6ICJo
dHRwczovL2V4YW1wbGUuY29tL3ZlcmlmaWVyIiwgInNkX3JlbGVhc2UiOiB7ImdpdmVuX2
5hbWUiOiAiW1wiZWx1VjVPZzNnU05JSThFWW5zeEFfQVwiLCBcIkpvaG5cIl0iLCAiZmFt
aWx5X25hbWUiOiAiW1wiNklqN3RNLWE1aVZQR2JvUzV0bXZWQVwiLCBcIkRvZVwiXSIsIC
JhZGRyZXNzIjogIltcIkFKeC0wOTVWUHJwVHRONFFNT3FST0FcIiwge1wic3RyZWV0X2Fk
ZHJlc3NcIjogXCIxMjMgTWFpbiBTdFwiLCBcImxvY2FsaXR5XCI6IFwiQW55dG93blwiLC
BcInJlZ2lvblwiOiBcIkFueXN0YXRlXCIsIFwiY291bnRyeVwiOiBcIlVTXCJ9XSJ9fQ.j
5jtArW1QDK1BNM13sJbQaE00GsAhhiPRYi6oK-iJRtLWE6DAgcWxDirTvxTnuo7Mbb6gSq
GTmdEEtmscWxweFfGQoddObPTDiapjWiR1bUMMqPDKNNkRe0CBkU-pWieYWN-fQxlRa4BK
Uqs18jcvGtTGA8Ye-i6t2xLROeXf2U_Seko8b7MQWIFHdbc0LvEFt_-JAcqeshH5wjVkwh
HofVuZq1vGLlINKBveKA2dmn6wuEzi6XRceTwFrG_hTECagfobdO-bYMF3FSiCQM2KxC_6
_aLApYo0aH3zjBv9rm0qNmnL_JGN5FIu6YqwhvPzfdsfkjMd68o8LTWd7F6kQ
</artwork>
<t>(Line breaks for presentation only.)</t>
</section>
</section>
<section anchor="verification"><name>Verification</name>
<section anchor="verification-by-the-holder-when-receiving-sd-jwt-and-svc"><name>Verification by the Holder when Receiving SD-JWT and SVC</name>
<t>The holder SHOULD verify the binding between SD-JWT and SVC by performing the following steps:
1. Check that all the claims in the SVC are present in the SD-JWT and that there are no claims in the SD-JWT that are not in the SVC
2. Check that the hashes of the claims in the SVC match those in the SD-JWT</t>
</section>
<section anchor="verification-by-the-verifier-when-receiving-sd-jwt-and-sd-jwt-r"><name>Verification by the Verifier when Receiving SD-JWT and SD-JWT-R</name>
<t>Verifiers MUST follow <xref target="RFC8725"></xref> for checking the SD-JWT and, if signed, the
SD-JWT Release.</t>
<t>Verifiers MUST go through (at least) the following steps before
trusting/using any of the contents of an SD-JWT:</t>
<ol>
<li><t>Determine if holder binding is to be checked for the SD-JWT. Refer to <xref target="holder_binding_security"></xref> for details.</t>
</li>
<li><t>Check that the presentation consists of six period-separated (<tt>.</tt>) elements; if holder binding is not required, the last element can be empty.</t>
</li>
<li><t>Separate the SD-JWT from the SD-JWT Release.</t>
</li>
<li><t>Validate the SD-JWT:</t>
<ol>
<li><t>Ensure that a signing algorithm was used that was deemed secure for the application. Refer to <xref target="RFC8725"></xref>, Sections 3.1 and 3.2 for details.</t>
</li>
<li><t>Validate the signature over the SD-JWT.</t>
</li>
<li><t>Validate the issuer of the SD-JWT and that the signing key belongs to this issuer.</t>
</li>
<li><t>Check that the SD-JWT is valid using <tt>nbf</tt>, <tt>iat</tt>, and <tt>exp</tt> claims, if provided in the SD-JWT.</t>
</li>
<li><t>Check that the claim <tt>sd_digests</tt> is present in the SD-JWT.</t>
</li>
<li><t>Check that the <tt>sd_hash_alg</tt> claim is present and its value is understand
and the hash algorithm is deemed secure.</t>
</li>
</ol></li>
<li><t>Validate the SD-JWT Release:</t>
<ol>
<li><t>If holder binding is required, validate the signature over the SD-JWT using the same steps as for the SD-JWT plus the following steps:</t>
<ol>
<li><t>Determine that the public key for the private key that used to sign the SD-JWT-R is bound to the SD-JWT, i.e., the SD-JWT either contains a reference to the public key or contains the public key itself.</t>
</li>
<li><t>Determine that the SD-JWT-R is bound to the current transaction and was created for this verifier (replay protection). This is usually achieved by a <tt>nonce</tt> and <tt>aud</tt> field within the SD-JWT Release.</t>
</li>
</ol></li>
<li><t>For each claim in the SD-JWT Release:</t>
<ol>
<li><t>Ensure that the claim is present as well in <tt>sd_release</tt> in the SD-JWT.
If <tt>sd_release</tt> is structured, the claim MUST be present at the same
place within the structure.</t>
</li>
<li><t>Compute the base64url-encoded hash of a claim revealed from the Holder
using the claim value and the salt included in the SD-JWT-R and
the <tt>sd_hash_alg</tt> in SD-JWT.</t>
</li>
<li><t>Compare the hash digests computed in the previous step with the one of the same claim in the SD-JWT.
Accept the claim only when the two hash digests match.</t>
</li>
<li><t>Ensure that the claim value in the SD-JWT-R is a JSON-encoded
array of exactly two values.</t>
</li>
<li><t>Store the second of the two values.</t>
</li>
</ol></li>
<li><t>Once all necessary claims have been verified, their values can be
validated and used according to the requirements of the application. It
MUST be ensured that all claims required for the application have been
released.</t>
</li>
</ol></li>
</ol>
<t>If any step fails, the input is not valid and processing MUST be aborted.</t>
</section>
</section>
<section anchor="security_considerations"><name>Security Considerations</name>
<section anchor="mandatory-hash-computation-of-the-revealed-claim-values-by-the-verifier"><name>Mandatory hash computation of the revealed claim values by the Verifier</name>
<t>ToDo: add text explaining mechanisms that should be adopted to ensure that
verifiers validate the claim values received in SD-JWT-R by calculating the
hashes of those values and comparing them with the hashes in the SD-JWT:
- create a test suite that forces hash computation by the Verifiers,
and includes negative test cases in test vectors
- use only implementations/libraries that are compliant to the test suite
- etc.</t>
</section>
<section anchor="mandatory-signing-of-the-sd-jwt"><name>Mandatory signing of the SD-JWT</name>
<t>The SD-JWT MUST be signed by the issuer to protect integrity of the issued
claims. An attacker can modify or add claims if an SD-JWT is not signed (e.g.,
change the "email" attribute to take over the victim's account or add an
attribute indicating a fake academic qualification).</t>
<t>The verifier MUST always check the SD-JWT signature to ensure that the SD-JWT
has not been tampered with since its issuance. If the signature on the SD-JWT
cannot be verified, the SD-JWT MUST be rejected.</t>
</section>
<section anchor="entropy-and-uniqueness-of-the-salt"><name>Entropy and Uniqueness of the salt</name>
<t>The security model relies on the fact that the salt is not learned or guessed by
the attacker. It is vitally important to adhere to this principle. As such, the
salt MUST be created in such a manner that it is cryptographically random,
long enough and has high entropy that it is not practical for the attacker to
guess. Each salt value MUST be unique.</t>
</section>
<section anchor="minimum-length-of-the-salt"><name>Minimum length of the salt</name>
<t>The length of the randomly-generated portion of the salt MUST be at least 128 bits.</t>
</section>
<section anchor="choice-of-a-hash-function"><name>Choice of a hash function</name>
<t>For the security of this scheme, the hash function is required to be preimage and collision
resistant, i.e., it is infeasible to calculate the salt and claim value that result in
a particular digest, and it is infeasible to find a different salt and claim value pair that
result in a matching digest, respectively.</t>
<t>Furthermore the hash algorithms MD2, MD4, MD5, RIPEMD-160, and SHA-1
revealed fundamental weaknesses and they MUST NOT be used.</t>
</section>
<section anchor="holder_binding_security"><name>Holder Binding</name>
<t>TBD</t>
</section>
</section>
<section anchor="privacy_considerations"><name>Privacy Considerations</name>
<section anchor="claim-names"><name>Claim Names</name>
<t>Claim names are not hashed in the SD-JWT and are used as keys in a key-value pair, where the value is the hash.
This is because SD-JWT already reveals information about the issuer and the schema,
and revealing the claim names does not provide any additional information.</t>
</section>
<section anchor="unlinkability"><name>Unlinkability</name>
<t>Colluding issuer/verifier or verifier/verifier pairs could link issuance/presentation or two presentation sessions
to the same user on the basis of unique values encoded in the SD-JWT
(issuer signature, salts, digests, etc.). More advanced cryptographic schemes, outside the scope of
this specification, can be used to prevent this type of linkability.</t>
</section>
</section>
<section anchor="Acknowledgements"><name>Acknowledgements</name>
<t>We would like to thank
Alen Horvat,
Brian Campbell,
Christian Paquin,
Fabian Hauck,
Giuseppe De Marco,
Kushal Das,
Mike Jones,
Nat Sakimura,
Pieter Kasselman, and
Torsten Lodderstedt
for their contributions (some of which substantial) to this draft and to the initial set of implementations.</t>
<t>The work on this draft was started at OAuth Security Workshop 2022 in Trondheim, Norway.</t>
</section>
<section anchor="iana_considerations"><name>IANA Considerations</name>
<t>TBD</t>
</section>
</middle>
<back>
<references><name>Normative References</name>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7519.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7515.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
</references>
<references><name>Informative References</name>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7800.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8725.xml"/>
<reference anchor="VC_DATA" target="https://www.w3.org/TR/vc_data">
<front>
<title>Verifiable Credentials Data Model 1.0</title>
<author fullname="Manu Sporny">
<organization>Digital Bazaar</organization>
</author>
<author fullname="Grant Noble">
<organization>ConsenSys</organization>
</author>
<author fullname="Dave Longley">
<organization>Digital Bazaar</organization>
</author>
<author fullname="Daniel C. Burnett">
<organization>ConsenSys</organization>
</author>
<author fullname="Brent Zundel">
<organization>Evernym</organization>
</author>
<author fullname="David Chadwick">
<organization>University of Kent</organization>
</author>
<date year="2019" month="Nov" day="19"></date>
</front>
</reference>
</references>
<section anchor="additional-examples"><name>Additional Examples</name>
<section anchor="example-2-structured-sd-jwt"><name>Example 2 - Structured SD-JWT</name>
<t>This non-normative example is based on the same claim values as Example 1, but
this time the issuer decided to create a structured object for the hashes. This
allows for the release of individual members of the address claim separately.</t>
<sourcecode anchor="example-simple_structured-sd_jwt_payload" type="json">{
"iss": "https://example.com/issuer",
"cnf": {
"jwk" : {
"kty": "RSA",
"n": "pm4bOHBg-oYhAyPWzR56AWX3rUIXp11_ICDkGgS6W3ZWLts-hzwI3x65659kg4hVo9dbGoCJE3ZGF_eaetE30UhBUEgpGwrDrQiJ9zqprmcFfr3qvvkGjtth8Zgl1eM2bJcOwE7PCBHWTKWYs152R7g6Jg2OVph-a8rq-q79MhKG5QoW_mTz10QT_6H4c7PjWG1fjh8hpWNnbP_pv6d1zSwZfc5fl6yVRL0DV0V3lGHKe2Wqf_eNGjBrBLVklDTk8-stX_MWLcR-EGmXAOv0UBWitS_dXJKJu-vXJyw14nHSGuxTIK2hx1pttMft9CsvqimXKeDTU14qQL1eE7ihcw",
"e": "AQAB"
}
},
"iat": 1516239022,
"exp": 1516247022,
"sd_hash_alg": "sha-256",
"sd_digests": {
"sub": "z4xgEco94diTaSruISPiE7o_wtmcOfnH_8R7X9Pa578",
"given_name": "PvU7cWjuHUq6w-i9XFpQZhjT-uprQL3GH3mKsAJl0e0",
"family_name": "H-Relr4cEBMlenyK1gvyx16QVpnt4MEclT5tP0aTLFU",
"email": "ET2A1JQLF85ZpBulh6UFstGrSfR4B3KM-bjQVllhxqY",
"phone_number": "SJnciB2DIRVA5cXBrdKoH6n45788mZyUn2rnv74uMVU",
"address": {
"street_address": "O7_Isd6CmZqcSobPVpMgmJwB41hPUHHG8jg5LJ8YzfY",
"locality": "w-zTF6ljkQLTvVyp_JNyD3t5Waj-B2vb0AXH1q8OsjI",
"region": "nTvoKpGA6YQwEZipVBIM4WVH9KWEnwiqsRjEhrxhQz4",
"country": "u-O1yDQqDTTqOgUBSjWilgkMLzg_QOTELMfZrRT5e6k"
},
"birthdate": "TipyoxD43PZJF8ZEmKPrbxMElpFX_M7aBLkUpC-W53o"
}
}
</sourcecode>
<t>The SVC for this SD-JWT is as follows:</t>
<sourcecode anchor="example-simple_structured-svc_payload" type="json">{
"sd_release": {
"sub": "[\"2GLC42sKQveCfGfryNRN9w\", \"6c5c0a49-b589-431d-bae7-219122a9ec2c\"]",
"given_name": "[\"eluV5Og3gSNII8EYnsxA_A\", \"John\"]",
"family_name": "[\"6Ij7tM-a5iVPGboS5tmvVA\", \"Doe\"]",
"email": "[\"eI8ZWm9QnKPpNPeNenHdhQ\", \"[email protected]\"]",
"phone_number": "[\"Qg_O64zqAxe412a108iroA\", \"+1-202-555-0101\"]",
"address": {
"street_address": "[\"AJx-095VPrpTtN4QMOqROA\", \"123 Main St\"]",
"locality": "[\"Pc33JM2LchcU_lHggv_ufQ\", \"Anytown\"]",
"region": "[\"G02NSrQfjFXQ7Io09syajA\", \"Anystate\"]",
"country": "[\"lklxF5jMYlGTPUovMNIvCA\", \"US\"]"
},
"birthdate": "[\"nPuoQnkRFq3BIeAm7AnXFA\", \"1940-01-01\"]"
}
}
</sourcecode>
<t>An SD-JWT-R for the SD-JWT above that discloses only <tt>region</tt> and <tt>country</tt> of
the <tt>address</tt> property:</t>
<sourcecode anchor="example-simple_structured-sd_jwt_release_payload" type="json">{
"nonce": "XZOUco1u_gEPknxS78sWWg",
"aud": "https://example.com/verifier",
"sd_release": {
"given_name": "[\"eluV5Og3gSNII8EYnsxA_A\", \"John\"]",
"family_name": "[\"6Ij7tM-a5iVPGboS5tmvVA\", \"Doe\"]",
"birthdate": "[\"nPuoQnkRFq3BIeAm7AnXFA\", \"1940-01-01\"]",
"address": {
"region": "[\"G02NSrQfjFXQ7Io09syajA\", \"Anystate\"]",
"country": "[\"lklxF5jMYlGTPUovMNIvCA\", \"US\"]"
}
}
}
</sourcecode>
</section>
<section anchor="example-3-complex-structured-sd-jwt"><name>Example 3 - Complex Structured SD-JWT</name>
<t>In this example, a complex object such as those used for OIDC4IDA (todo reference) is used.</t>
<t>In this example, the Issuer is using a following object as a set of claims to issue to the Holder:</t>
<sourcecode anchor="example-complex-user_claims" type="json">{
"verified_claims": {
"verification": {
"trust_framework": "de_aml",
"time": "2012-04-23T18:25Z",
"verification_process": "f24c6f-6d3f-4ec5-973e-b0d8506f3bc7",
"evidence": [
{
"type": "document",
"method": "pipp",
"time": "2012-04-22T11:30Z",
"document": {
"type": "idcard",
"issuer": {
"name": "Stadt Augsburg",
"country": "DE"
},
"number": "53554554",
"date_of_issuance": "2010-03-23",
"date_of_expiry": "2020-03-22"
}
}
]
},
"claims": {
"given_name": "Max",
"family_name": "Meier",
"birthdate": "1956-01-28",
"place_of_birth": {
"country": "DE",
"locality": "Musterstadt"
},
"nationalities": [
"DE"
],
"address": {
"locality": "Maxstadt",
"postal_code": "12344",
"country": "DE",
"street_address": "An der Weide 22"
}
}
},
"birth_middle_name": "Timotheus",
"salutation": "Dr.",
"msisdn": "49123456789"
}
</sourcecode>
<t>The following shows the resulting SD-JWT payload:</t>
<sourcecode anchor="example-complex-sd_jwt_payload" type="json">{
"iss": "https://example.com/issuer",
"cnf": {
"jwk" : {
"kty": "RSA",
"n": "pm4bOHBg-oYhAyPWzR56AWX3rUIXp11_ICDkGgS6W3ZWLts-hzwI3x65659kg4hVo9dbGoCJE3ZGF_eaetE30UhBUEgpGwrDrQiJ9zqprmcFfr3qvvkGjtth8Zgl1eM2bJcOwE7PCBHWTKWYs152R7g6Jg2OVph-a8rq-q79MhKG5QoW_mTz10QT_6H4c7PjWG1fjh8hpWNnbP_pv6d1zSwZfc5fl6yVRL0DV0V3lGHKe2Wqf_eNGjBrBLVklDTk8-stX_MWLcR-EGmXAOv0UBWitS_dXJKJu-vXJyw14nHSGuxTIK2hx1pttMft9CsvqimXKeDTU14qQL1eE7ihcw",
"e": "AQAB"
}
},
"iat": 1516239022,
"exp": 1516247022,
"sd_hash_alg": "sha-256",
"sd_digests": {
"verified_claims": {
"verification": {
"trust_framework": "w1mP4oPc_J9thBex0TaQi1vgxFmruQJxZYLFnkNFMaI",
"time": "Pu3i0CWrPVLJW-LT30yF1bFBPP15B6-uKk3PnGDflv8",
"verification_process": "8HqIXRmczsdYOZzGcLqI5-l9xN5QbK2XDtXmdfH7z-4",
"evidence": [
{
"type": "TnLuqGGQm6jfeOoa5uX1diKANUPuh-zHrpBFdX9MR-g",
"method": "SagmakoSu-X-XUPIC3EgdrEEwIWxRWXX4-i68X9TyEo",
"time": "ld2c5oYDRtQcfU6PzogPkx_95WYqhqIJNVRMnfcsicY",
"document": {
"type": "ufWjDaAa54MnHeji2ZUUHDdnpZ9zx6CUG6uR28VMtsQ",
"issuer": {
"name": "a4GMucU7Zb060r0Svd7huY6Qho1bIf3v1U5BvPR8q6Y",
"country": "135k9M0m2SCnYRuOfHuYScYVS2q3eeY7IItgyRsaBT8"
},
"number": "cUvOxLUp8RV7TTVliEiu-TQIel-LsE8E-XfUgfqk5gk",
"date_of_issuance": "NIs8olJnJOv4J1qIEBKuTs2sEFs4fgGJhNqM6xdQt7E",
"date_of_expiry": "HTR37vLtANT6MWk-9dBqekFpCvaTG7zNf1ze56rnV64"
}
}
]
},
"claims": {
"given_name": "NB9XH_yJKqKOhXDmXkZKpMCkRbOmOTd8bqJFYDJYQnQ",
"family_name": "hAUbJ66ZYL9VJLbjsDpmSs2e9Ff_Ohim_WR4bwZyvoQ",
"birthdate": "6XOR4k56BgWk5tnNismbmEHvoGX7RRfy6Z8HENl96cU",
"place_of_birth": {
"country": "CLTlhuy13WWc3_ISon1kEypFwvCmfhLSpGUMCyAUg68",
"locality": "AQoX8ixGpz-ipweEGlC-2umqwyQdhjIeiUB_TKWcE2E"
},
"nationalities": "nfoc__QKlMUHodmxwlY-Kp-6ewgX3CdK7Ia0RJHIXVo",
"address": "ngnO4uQeOktM7YdFD8x82doS7WJnlZnq-rQE_RfuBSI"
}
},
"birth_middle_name": "FeFSwd9drypEPtWVgIZ42N9j_yostt1Ds5PBpxT3Rng",
"salutation": "57CMhvASQMNuzuQ0a_B1_VX5XdH73TcuPxyWGiorj5g",
"msisdn": "leKbB0ro6q3jrVraCqt443uaGZVZisD3iGrKuKE2mqM"
}
}
</sourcecode>
<t>The SD-JWT is then signed by the issuer to create a document like the following:</t>
<artwork anchor="example-complex-serialized_sd_jwt">eyJhbGciOiAiUlMyNTYiLCAia2lkIjogImNBRUlVcUowY21MekQxa3pHemhlaUJhZzBZUk
F6VmRsZnhOMjgwTmdIYUEifQ.eyJpc3MiOiAiaHR0cHM6Ly9leGFtcGxlLmNvbS9pc3N1Z
XIiLCAic3ViX2p3ayI6IHsia3R5IjogIlJTQSIsICJuIjogInBtNGJPSEJnLW9ZaEF5UFd
6UjU2QVdYM3JVSVhwMTFfSUNEa0dnUzZXM1pXTHRzLWh6d0kzeDY1NjU5a2c0aFZvOWRiR
29DSkUzWkdGX2VhZXRFMzBVaEJVRWdwR3dyRHJRaUo5enFwcm1jRmZyM3F2dmtHanR0aDh
aZ2wxZU0yYkpjT3dFN1BDQkhXVEtXWXMxNTJSN2c2SmcyT1ZwaC1hOHJxLXE3OU1oS0c1U
W9XX21UejEwUVRfNkg0YzdQaldHMWZqaDhocFdObmJQX3B2NmQxelN3WmZjNWZsNnlWUkw
wRFYwVjNsR0hLZTJXcWZfZU5HakJyQkxWa2xEVGs4LXN0WF9NV0xjUi1FR21YQU92MFVCV
2l0U19kWEpLSnUtdlhKeXcxNG5IU0d1eFRJSzJoeDFwdHRNZnQ5Q3N2cWltWEtlRFRVMTR
xUUwxZUU3aWhjdyIsICJlIjogIkFRQUIifSwgImlhdCI6IDE1MTYyMzkwMjIsICJleHAiO
iAxNTE2MjQ3MDIyLCAiaGFzaF9hbGciOiAic2hhLTI1NiIsICJzZF9kaWdlc3RzIjogeyJ
2ZXJpZmllZF9jbGFpbXMiOiB7InZlcmlmaWNhdGlvbiI6IHsidHJ1c3RfZnJhbWV3b3JrI
jogIncxbVA0b1BjX0o5dGhCZXgwVGFRaTF2Z3hGbXJ1UUp4WllMRm5rTkZNYUkiLCAidGl
tZSI6ICJQdTNpMENXclBWTEpXLUxUMzB5RjFiRkJQUDE1QjYtdUtrM1BuR0RmbHY4IiwgI
nZlcmlmaWNhdGlvbl9wcm9jZXNzIjogIjhIcUlYUm1jenNkWU9aekdjTHFJNS1sOXhONVF
iSzJYRHRYbWRmSDd6LTQiLCAiZXZpZGVuY2UiOiBbeyJ0eXBlIjogIlRuTHVxR0dRbTZqZ
mVPb2E1dVgxZGlLQU5VUHVoLXpIcnBCRmRYOU1SLWciLCAibWV0aG9kIjogIlNhZ21ha29
TdS1YLVhVUElDM0VnZHJFRXdJV3hSV1hYNC1pNjhYOVR5RW8iLCAidGltZSI6ICJsZDJjN
W9ZRFJ0UWNmVTZQem9nUGt4Xzk1V1lxaHFJSk5WUk1uZmNzaWNZIiwgImRvY3VtZW50Ijo
geyJ0eXBlIjogInVmV2pEYUFhNTRNbkhlamkyWlVVSERkbnBaOXp4NkNVRzZ1UjI4Vk10c
1EiLCAiaXNzdWVyIjogeyJuYW1lIjogImE0R011Y1U3WmIwNjByMFN2ZDdodVk2UWhvMWJ
JZjN2MVU1QnZQUjhxNlkiLCAiY291bnRyeSI6ICIxMzVrOU0wbTJTQ25ZUnVPZkh1WVNjW
VZTMnEzZWVZN0lJdGd5UnNhQlQ4In0sICJudW1iZXIiOiAiY1V2T3hMVXA4UlY3VFRWbGl
FaXUtVFFJZWwtTHNFOEUtWGZVZ2ZxazVnayIsICJkYXRlX29mX2lzc3VhbmNlIjogIk5Jc
zhvbEpuSk92NEoxcUlFQkt1VHMyc0VGczRmZ0dKaE5xTTZ4ZFF0N0UiLCAiZGF0ZV9vZl9
leHBpcnkiOiAiSFRSMzd2THRBTlQ2TVdrLTlkQnFla0ZwQ3ZhVEc3ek5mMXplNTZyblY2N
CJ9fV19LCAiY2xhaW1zIjogeyJnaXZlbl9uYW1lIjogIk5COVhIX3lKS3FLT2hYRG1Ya1p
LcE1Da1JiT21PVGQ4YnFKRllESllRblEiLCAiZmFtaWx5X25hbWUiOiAiaEFVYko2NlpZT
DlWSkxianNEcG1TczJlOUZmX09oaW1fV1I0YndaeXZvUSIsICJiaXJ0aGRhdGUiOiAiNlh
PUjRrNTZCZ1drNXRuTmlzbWJtRUh2b0dYN1JSZnk2WjhIRU5sOTZjVSIsICJwbGFjZV9vZ
l9iaXJ0aCI6IHsiY291bnRyeSI6ICJDTFRsaHV5MTNXV2MzX0lTb24xa0V5cEZ3dkNtZmh
MU3BHVU1DeUFVZzY4IiwgImxvY2FsaXR5IjogIkFRb1g4aXhHcHotaXB3ZUVHbEMtMnVtc
Xd5UWRoakllaVVCX1RLV2NFMkUifSwgIm5hdGlvbmFsaXRpZXMiOiAibmZvY19fUUtsTVV
Ib2RteHdsWS1LcC02ZXdnWDNDZEs3SWEwUkpISVhWbyIsICJhZGRyZXNzIjogIm5nbk80d
VFlT2t0TTdZZEZEOHg4MmRvUzdXSm5sWm5xLXJRRV9SZnVCU0kifX0sICJiaXJ0aF9taWR
kbGVfbmFtZSI6ICJGZUZTd2Q5ZHJ5cEVQdFdWZ0laNDJOOWpfeW9zdHQxRHM1UEJweFQzU
m5nIiwgInNhbHV0YXRpb24iOiAiNTdDTWh2QVNRTU51enVRMGFfQjFfVlg1WGRINzNUY3V
QeHlXR2lvcmo1ZyIsICJtc2lzZG4iOiAibGVLYkIwcm82cTNqclZyYUNxdDQ0M3VhR1pWW
mlzRDNpR3JLdUtFMm1xTSJ9fQ.i6xjiYhdM0pnDamaDfvsLWrjD2JOQBYbkWpLAykGFenK
B4nBN1E2gfbexMvlyRJc1AcU2wKdGQnRZsaNR-UYZ7yQPXrlBQH2RMkbRuQcI0K4n9KP8c
I8JnUVgERRBQSbtrInYrgRDvQ9K7nlyj4y6ULvVybcZpbw2sUv5YJwdBsdB8kAvGWKCEkW
NMvk-UGKZAKO78RPemWOTezLZq3Ubfj5GinITb6SN_Gu1rdLgA3ebKNkVqDBjI9q483d-9
g_MP8owwGzE_tCd8oj2bjRlRE1YgwN1lxAAGVpDrIJwWbuivh7BqUArvblEHe4L0ZITMhz
F5KKsEkYhkrr8q6qFg
</artwork>
<t>(Line breaks for presentation only.)</t>
<t>A SD-JWT-R for some of the claims:</t>
<sourcecode anchor="example-complex-sd_jwt_release_payload" type="json">{
"nonce": "XZOUco1u_gEPknxS78sWWg",
"aud": "https://example.com/verifier",
"sd_release": {
"verified_claims": {
"verification": {
"trust_framework": "[\"2GLC42sKQveCfGfryNRN9w\", \"de_aml\"]",
"time": "[\"eluV5Og3gSNII8EYnsxA_A\", \"2012-04-23T18:25Z\"]",
"evidence": [
{
"type": "[\"eI8ZWm9QnKPpNPeNenHdhQ\", \"document\"]"
}
]
},
"claims": {
"given_name": "[\"y1sVU5wdfJahVdgwPgS7RQ\", \"Max\"]",
"family_name": "[\"HbQ4X8srVW3QDxnIJdqyOA\", \"Meier\"]",
"birthdate": "[\"C9GSoujviJquEgYfojCb1A\", \"1956-01-28\"]",
"place_of_birth": {
"country": "[\"kx5kF17V-x0JmwUx9vgvtw\", \"DE\"]"
}
}
}
}
}
</sourcecode>
</section>
<section anchor="example-4-w3c-verifiable-credentials-data-model"><name>Example 4 - W3C Verifiable Credentials Data Model</name>