| rfc9901v2.txt | rfc9901.txt | |||
|---|---|---|---|---|
| Internet Engineering Task Force (IETF) D. Fett | Internet Engineering Task Force (IETF) D. Fett | |||
| Request for Comments: 9901 Authlete | Request for Comments: 9901 Authlete | |||
| Category: Standards Track K. Yasuda | Category: Standards Track K. Yasuda | |||
| ISSN: 2070-1721 Keio University | ISSN: 2070-1721 Keio University | |||
| B. Campbell | B. Campbell | |||
| Ping Identity | Ping Identity | |||
| November 2025 | November 2025 | |||
| Selective Disclosure for JSON Web Token (SD-JWT) | Selective Disclosure for JSON Web Tokens | |||
| Abstract | Abstract | |||
| This specification defines a mechanism for the selective disclosure | This specification defines a mechanism for the selective disclosure | |||
| of individual elements of a JSON data structure used as the payload | of individual elements of a JSON data structure used as the payload | |||
| of a JSON Web Signature (JWS). The primary use case is the selective | of a JSON Web Signature (JWS). The primary use case is the selective | |||
| disclosure of JSON Web Token (JWT) claims. | disclosure of JSON Web Token (JWT) claims. | |||
| Status of This Memo | Status of This Memo | |||
| skipping to change at line 157 ¶ | skipping to change at line 157 ¶ | |||
| address to one Verifier, and only the birthdate to a different | address to one Verifier, and only the birthdate to a different | |||
| Verifier. | Verifier. | |||
| Privacy principles of minimal disclosure in conjunction with this | Privacy principles of minimal disclosure in conjunction with this | |||
| model demand a mechanism enabling selective disclosure of data | model demand a mechanism enabling selective disclosure of data | |||
| elements while ensuring that Verifiers can still check the | elements while ensuring that Verifiers can still check the | |||
| authenticity of the data provided. This specification defines such a | authenticity of the data provided. This specification defines such a | |||
| mechanism for JSON payloads of JWSs, with JWTs as the primary use | mechanism for JSON payloads of JWSs, with JWTs as the primary use | |||
| case. | case. | |||
| SD-JWT is based on an approach called "salted hashes": For any data | Selectively Disclosable JWT (SD-JWT) is based on an approach called | |||
| element that should be selectively disclosable, the Issuer of the SD- | "salted hashes": For any data element that should be selectively | |||
| JWT does not include the cleartext of the data in the JSON payload of | disclosable, the Issuer of the SD-JWT does not include the cleartext | |||
| the JWS structure; instead, a digest of the data takes its place. | of the data in the JSON payload of the JWS structure; instead, a | |||
| For presentation to a Verifier, the Holder sends the signed payload | digest of the data takes its place. For presentation to a Verifier, | |||
| along with the cleartext of those claims it wants to disclose. The | the Holder sends the signed payload along with the cleartext of those | |||
| Verifier can then compute the digest of the cleartext data and | claims it wants to disclose. The Verifier can then compute the | |||
| confirm it is included in the signed payload. To ensure that | digest of the cleartext data and confirm it is included in the signed | |||
| Verifiers cannot guess cleartext values of non-disclosed data | payload. To ensure that Verifiers cannot guess cleartext values of | |||
| elements, an additional salt value is used when creating the digest | non-disclosed data elements, an additional salt value is used when | |||
| and sent along with the cleartext when disclosing it. | creating the digest and sent along with the cleartext when disclosing | |||
| it. | ||||
| To prevent attacks in which an SD-JWT is presented to a Verifier | To prevent attacks in which an SD-JWT is presented to a Verifier | |||
| without the Holder's consent, this specification additionally defines | without the Holder's consent, this specification additionally defines | |||
| a mechanism for binding the SD-JWT to a key under the control of the | a mechanism for binding the SD-JWT to a key under the control of the | |||
| Holder (Key Binding). When Key Binding is enforced, a Holder has to | Holder (Key Binding). When Key Binding is enforced, a Holder has to | |||
| prove possession of a private key belonging to a public key contained | prove possession of a private key belonging to a public key contained | |||
| in the SD-JWT itself. It usually does so by signing over a data | in the SD-JWT itself. It usually does so by signing over a data | |||
| structure containing transaction-specific data, herein defined as the | structure containing transaction-specific data, herein defined as the | |||
| Key Binding JWT. An SD-JWT with a Key Binding JWT is called "SD- | Key Binding JWT. An SD-JWT with a Key Binding JWT is called "SD- | |||
| JWT+KB" in this specification. | JWT+KB" in this specification. | |||
| skipping to change at line 221 ¶ | skipping to change at line 222 ¶ | |||
| transport of the SD-JWT and the KB-JWT. | transport of the SD-JWT and the KB-JWT. | |||
| 1.2. Conventions and Terminology | 1.2. Conventions and Terminology | |||
| The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | |||
| "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | |||
| "OPTIONAL" in this document are to be interpreted as described in | "OPTIONAL" in this document are to be interpreted as described in | |||
| BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all | BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all | |||
| capitals, as shown here. | capitals, as shown here. | |||
| *Base64url* denotes the URL-safe base64 encoding without padding | Base64url: | |||
| defined in Section 2 of [RFC7515]. | Denotes the URL-safe base64 encoding without padding defined in | |||
| Section 2 of [RFC7515]. | ||||
| Throughout this document, the term "claims" refers generally to | Claim: | |||
| object properties (name/value pairs) as well as array elements. | In this document, refers generally to object properties (name/ | |||
| value pairs) as well as array elements. | ||||
| Selective Disclosure: | Selective Disclosure: | |||
| Process of a Holder disclosing to a Verifier a subset of claims | Process of a Holder disclosing to a Verifier a subset of claims | |||
| contained in a JWT issued by an Issuer. | contained in a JWT issued by an Issuer. | |||
| Selectively Disclosable JWT (SD-JWT): | Selectively Disclosable JWT (SD-JWT): | |||
| A composite structure, consisting of an Issuer-signed JWT (JWS; | A composite structure, consisting of an Issuer-signed JWT (JWS; | |||
| see [RFC7515]) and zero or more Disclosures, which supports | see [RFC7515]) and zero or more Disclosures, which supports | |||
| selective disclosure as defined in this document. It can contain | selective disclosure as defined in this document. It can contain | |||
| both regular claims and digests of selectively disclosable claims. | both regular claims and digests of selectively disclosable claims. | |||
| skipping to change at line 407 ¶ | skipping to change at line 410 ¶ | |||
| * an SD-JWT (i.e., an Issuer-signed JWT and zero or more | * an SD-JWT (i.e., an Issuer-signed JWT and zero or more | |||
| Disclosures), and | Disclosures), and | |||
| * a Key Binding JWT. | * a Key Binding JWT. | |||
| The Issuer-signed JWT, Disclosures, and Key Binding JWT are explained | The Issuer-signed JWT, Disclosures, and Key Binding JWT are explained | |||
| in Sections 4.1, 4.2, and 4.3, respectively. | in Sections 4.1, 4.2, and 4.3, respectively. | |||
| The compact serialized format for the SD-JWT is the concatenation of | The compact serialized format for the SD-JWT is the concatenation of | |||
| each part delineated with a single tilde ('~') character as follows, | each part delineated with a single tilde ('~') character as follows, | |||
| where “D.1” to “D.N” represent the respective Disclosures: | where "D.1" to "D.N" represent the respective Disclosures: | |||
| <Issuer-signed JWT>~<D.1>~<D.2>~...~<D.N>~ | <Issuer-signed JWT>~<D.1>~<D.2>~...~<D.N>~ | |||
| The order of the concatenated parts MUST be the Issuer-signed JWT, a | The order of the concatenated parts MUST be the Issuer-signed JWT, a | |||
| tilde character, zero or more Disclosures each followed by a tilde | tilde character, zero or more Disclosures each followed by a tilde | |||
| character, and lastly the optional Key Binding JWT. In the case that | character, and lastly the optional Key Binding JWT. In the case that | |||
| there is no Key Binding JWT, the last element MUST be an empty string | there is no Key Binding JWT, the last element MUST be an empty string | |||
| and the last separating tilde character MUST NOT be omitted. | and the last separating tilde character MUST NOT be omitted. | |||
| The serialized format for an SD-JWT+KB extends the SD-JWT format by | The serialized format for an SD-JWT+KB extends the SD-JWT format by | |||
| concatenating a Key Binding JWT. | concatenating a Key Binding JWT. | |||
| <Issuer-signed JWT>~<D.1>~<D.2>~...~<D.N>~”<KB-JWT> | <Issuer-signed JWT>~<D.1>~<D.2>~...~<D.N>~<KB-JWT> | |||
| The two formats can be distinguished by the final ~ character that is | The two formats can be distinguished by the final ~ character that is | |||
| present on an SD-JWT. A Verifier that expects an SD-JWT MUST verify | present on an SD-JWT. A Verifier that expects an SD-JWT MUST verify | |||
| that the final tilde-separated component is empty. A Verifier that | that the final tilde-separated component is empty. A Verifier that | |||
| expects an SD-JWT+KB MUST verify that its final tilde-separated | expects an SD-JWT+KB MUST verify that its final tilde-separated | |||
| component is a valid KB-JWT. | component is a valid KB-JWT. | |||
| The Disclosures are linked to the Issuer-signed JWT through the | The Disclosures are linked to the Issuer-signed JWT through the | |||
| digest values included therein. | digest values included therein. | |||
| skipping to change at line 743 ¶ | skipping to change at line 746 ¶ | |||
| Disclosure digest as described in Section 4.2.4.2. | Disclosure digest as described in Section 4.2.4.2. | |||
| 4.2.4.1. Object Properties | 4.2.4.1. Object Properties | |||
| Digests of Disclosures for object properties are added to an array | Digests of Disclosures for object properties are added to an array | |||
| under the new key _sd in the object. The _sd key MUST refer to an | under the new key _sd in the object. The _sd key MUST refer to an | |||
| array of strings, each string being a digest of a Disclosure or a | array of strings, each string being a digest of a Disclosure or a | |||
| decoy digest as described in Section 4.2.5. An _sd key can be | decoy digest as described in Section 4.2.5. An _sd key can be | |||
| present at any level of the JSON object hierarchy, including at the | present at any level of the JSON object hierarchy, including at the | |||
| top-level, nested deeper as described in Section 6, or in recursive | top-level, nested deeper as described in Section 6, or in recursive | |||
| disclosures as described in Section 4.2.6. | Disclosures as described in Section 4.2.6. | |||
| The array MAY be empty in case the Issuer decided not to selectively | The array MAY be empty in case the Issuer decided not to selectively | |||
| disclose any of the claims at that level. However, it is RECOMMENDED | disclose any of the claims at that level. However, it is RECOMMENDED | |||
| to omit the _sd key in this case to save space. | to omit the _sd key in this case to save space. | |||
| The Issuer MUST hide the original order of the claims in the array. | The Issuer MUST hide the original order of the claims in the array. | |||
| To ensure this, it is RECOMMENDED to shuffle the array of hashes, | To ensure this, it is RECOMMENDED to shuffle the array of hashes, | |||
| e.g., by sorting it alphanumerically or randomly, after potentially | e.g., by sorting it alphanumerically or randomly, after potentially | |||
| adding decoy digests as described in Section 4.2.5. The precise | adding decoy digests as described in Section 4.2.5. The precise | |||
| method does not matter as long as it does not depend on the original | method does not matter as long as it does not depend on the original | |||
| skipping to change at line 819 ¶ | skipping to change at line 822 ¶ | |||
| For decoy digests, no Disclosure is sent to the Holder, i.e., the | For decoy digests, no Disclosure is sent to the Holder, i.e., the | |||
| Holder will see digests that do not correspond to any Disclosure. | Holder will see digests that do not correspond to any Disclosure. | |||
| See Section 10.4 for additional privacy considerations. | See Section 10.4 for additional privacy considerations. | |||
| To ensure readability and replicability, the examples in this | To ensure readability and replicability, the examples in this | |||
| specification do not contain decoy digests unless explicitly stated. | specification do not contain decoy digests unless explicitly stated. | |||
| For an example with decoy digests, see Appendix A.1. | For an example with decoy digests, see Appendix A.1. | |||
| 4.2.6. Recursive Disclosures | 4.2.6. Recursive Disclosures | |||
| The algorithms above are compatible with "recursive disclosures", in | The algorithms above are compatible with "recursive Disclosures", in | |||
| which one selectively disclosed field reveals the existence of more | which one selectively disclosed field reveals the existence of more | |||
| selectively disclosable fields. For example, consider the following | selectively disclosable fields. For example, consider the following | |||
| JSON structure: | JSON structure: | |||
| { | { | |||
| "family_name": "Möbius", | "family_name": "Möbius", | |||
| "nationalities": ["DE", "FR", "UK"] | "nationalities": ["DE", "FR", "UK"] | |||
| } | } | |||
| When the Holder has multiple nationalities, the Issuer may wish to | When the Holder has multiple nationalities, the Issuer may wish to | |||
| skipping to change at line 2154 ¶ | skipping to change at line 2157 ¶ | |||
| that results in the same digest. | that results in the same digest. | |||
| The hash function SHOULD also be collision resistant. Although not | The hash function SHOULD also be collision resistant. Although not | |||
| essential to the anticipated uses of SD-JWT, without collision | essential to the anticipated uses of SD-JWT, without collision | |||
| resistance an Issuer may be able to find multiple Disclosures that | resistance an Issuer may be able to find multiple Disclosures that | |||
| have the same hash value. In which case, the signature over the SD- | have the same hash value. In which case, the signature over the SD- | |||
| JWT would not then commit the Issuer to the contents of the JWT. The | JWT would not then commit the Issuer to the contents of the JWT. The | |||
| collision resistance of the hash function used to generate digests | collision resistance of the hash function used to generate digests | |||
| SHOULD match the collision resistance of the hash function used by | SHOULD match the collision resistance of the hash function used by | |||
| the signature scheme. For example, use of the ES512 signature | the signature scheme. For example, use of the ES512 signature | |||
| algorithm would require a disclosure hash function with at least | algorithm would require a Disclosure hash function with at least | |||
| 256-bit collision resistance, such as SHA-512. | 256-bit collision resistance, such as SHA-512. | |||
| Inclusion in the "Named Information Hash Algorithm Registry" | Inclusion in the "Named Information Hash Algorithm Registry" | |||
| [Hash.Algs] alone does not indicate a hash algorithm's suitability | [Hash.Algs] alone does not indicate a hash algorithm's suitability | |||
| for use in SD-JWT (it contains several heavily truncated digests, | for use in SD-JWT (it contains several heavily truncated digests, | |||
| such as sha-256-32 and sha-256-64, which are unfit for security | such as sha-256-32 and sha-256-64, which are unfit for security | |||
| applications). | applications). | |||
| 9.5. Key Binding | 9.5. Key Binding | |||
| skipping to change at line 4762 ¶ | skipping to change at line 4765 ¶ | |||
| "address": { | "address": { | |||
| "street_address": "Schulstr. 12", | "street_address": "Schulstr. 12", | |||
| "locality": "Schulpforta" | "locality": "Schulpforta" | |||
| } | } | |||
| ... | ... | |||
| or as | or as | |||
| ... | ... | |||
| "family_name": "Möbius", | "family_name": "Möbius", | |||
| "address": {"locality":"Schulpforta", "street_address":"Schulstr. 12"} | "address": {"locality":"Schulpforta", "street_address": | |||
| "Schulstr. 12"} | ||||
| ... | ... | |||
| The two representations of the value in family_name are very | The two representations of the value in family_name are very | |||
| different on the byte level, but they yield equivalent objects. The | different on the byte level, but they yield equivalent objects. The | |||
| same is true for the representations of address, which vary in white | same is true for the representations of address, which vary in white | |||
| space and order of elements in the object. | space and order of elements in the object. | |||
| The variations in white space, ordering of object properties, and | The variations in white space, ordering of object properties, and | |||
| encoding of Unicode characters are all allowed by the JSON | encoding of Unicode characters are all allowed by the JSON | |||
| specification, including further variations, e.g., concerning | specification, including further variations, e.g., concerning | |||
| End of changes. 10 change blocks. | ||||
| 22 lines changed or deleted | 26 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. | ||||