Hi Chad,

Thank you for your review of the specification! My comments below:

Am 03.04.25 um 08:57 schrieb Chad Parry:
The ellipsis name was introduced in version 5 of the specification, but the "_sd" name was retained. If an ellipsis is deemed more readable (section 4.2.4.2, and I agree it is), then why not use them instead of "_sd"? If the placeholder name needs to begin with an underscore, then presumably the existing ellipses usages are unsafe and need to be changed. In that case, "_..." would be fine too, as long as both object and array placeholders use a consistent name. In the payload above, I've used ellipses throughout.

The "_sd" with the underscore was chosen (long before ...) to avoid potential conflicts with existing keys in the structure. The underscore has no special meaning, but the hope is that it makes it visually clear that this key has a special role.

The "..." was chosen intentionally distinct from "_sd" to ensure that even when only parsing the structure without looking at the disclosures, the type of contents that can be expected in an object can be derived.


In the specification, the value of the _sd property is always an array while the ... property is always a string. It would be more consistent if both could always be arrays. If brevity is desired, then a single digest can be treated as if it were an array of one. In my example, I've used arrays only when there are multiple digests.

This creates polymorphism, which is usually not well-received by implementers, for good reasons.



Claim phone_number:
*  SHA-256 Hash: PorFbpKuVu6xymJagvkFsFXAbRoc2JGlAUA2BA4o7cI
*  Disclosure: WyJlSThaV205UW5LUHBOUGVOZW5IZGhRIiwgInBob25lX251bWJlciIsICIrMS0yMDItNTU1LTAxMDEiXQ *  Contents: ["eI8ZWm9QnKPpNPeNenHdhQ", {"phone_number": "+1-202-555-0101"}]

For this first disclosure, I've created an array with two elements instead of three. That makes the format even more consistent between object and array disclosures. The only disadvantage that I can think of is that it would suggest that a single disclosure is allowed to contain multiple claims. That brings me to my next example.

Multiple Claims:
*  SHA-256 Hash: 60MaroWpoFdZmSG82mkkN4-ksJzfrmUQ5oNtjLisBwg
*  Disclosure: WyJzb0FMX0JkUGhXQjVwZ2FlSWFPZ1hnIiwgeyJnaXZlbl9uYW1lIjogIkpvaG4iLCAiZmFtaWx5X25hbWUiOiAiRG9lIn1d *  Contents: ["soAL_BdPhWB5pgaeIaOgXg", {"given_name": "John", "family_name": "Doe"}]

This single disclosure includes both claims that comprise the principal's name. The entire object just needs to be merged with the payload. I didn't see this suggested yet in the archives, but I apologize if I just missed the discussion.

Whole Object Claim:
*  SHA-256 Hash: XzFrzwscM6Gn6CJDc6vVK8BkMnfG8vOSKfpPIZdAfdE
*  Disclosure: WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0 *  Contents: ["AJx-095VPrpTtN4QMOqROA", {"street_address": "123 Main St", "locality": "Anytown", "region": "Anystate", "country": "US"}]

As long as a disclosure can contain multiple fields, it could also contain all an object's fields, like with this address.

That is already possible with the existing structure.



Claim birthdate Value:
*  SHA-256 Hash: JL6Qz1obsng36vklAZGvir9NgVV2XsQa-1h4s7oHTrE
*  Disclosure: WyJXOC1KSmpuU0ZPN1dlVUJ1UmZWQ1N3IiwgIjE5NDAtMDEtMDEiXQ
*  Contents: ["W8-JJjnSFO7WeUBuRfVCSw", "1940-01-01"]

Continuing in the same vein, the disclosed value could be a primitive instead of an object. The payload has non-selectively-disclosed a claim with the name "birthdate" but has not revealed whether it is a string or number, much less its value. This makes the substitution rules for property values the same as for array elements, which could already hide the type. It would also relax the constraints described in section 9.6, "Blinding Claim Names."

Correct me if I'm wrong, but the same considerations would still apply. There would just be an additional option to always disclose the claim name.



Array Entry:
*  SHA-256 Hash: pFndjkZ_VCzmyTa6UjlZo3dh-ko8aIKQc9DlGzhaVYo
*  Disclosure: WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIlVTIl0
*  Contents: ["lklxF5jMYlGTPUovMNIvCA", "US"]

Array entries in this example look exactly the same as the specification already describes. However, now they fit into a more robust pattern, where all disclosures consist of a salt and a value. Substitution rules would work the same for object properties (name/value pairs), array elements, and property values: 1. The disclosed value replaces whichever target object contained the ellipsis. 2. Except that if the target object contains other claims or digests, then the disclosed value must be an object type and its claims get merged into the target object instead of replacing it.

As above, the price of this is that the structure itself is not self-explanatory anymore. In your example, without looking at the disclosures, I can't tell if nationalities is an array of strings or an array of objects.



Even though the format in this example is more powerful than in the current specification, I believe that greater consistency would make it easier for implementers. It would certainly reduce my cognitive load as a user. For example, to identify all embedded digests, (section 7.1, step 3.2), the verifier only needs to find all objects having a ... key that refers to a string or array of strings regardless of where it appears in the JWT.

Having implemented SD-JWT myself, I doubt that the consistency would make anything easier.

- With the rule "one digest is a string, multiple are an array" that you propose above, we have polymorphism. Without it, we have a structure like {"...": ["pFndjkZ_VCzmyTa6UjlZo3dh-ko8aIKQc9DlGzhaVYo"]} - which is hard to read and hard to explain.

- Consistency alone won't buy you anything. With the current structure, the processing of the SD-JWT is very clear, simple, and somewhat robust, as a three-valued disclosure would not be valid for an array entry and a two-valued disclosure would not be valid for an object key. That's a feature, not a bug, in my book. We have clearly separated explanations and code paths for _sd and ...; I found that easy to implement and we have not received any implementer feedback to the contrary.

Last but not least, I'd like to highlight that we have *many* implementations for SD-JWT out there, so many in fact that I can't list them all. We have 17 libraries named in our repository, and there are countless Issuers, Wallets and Verifiers that already use SD-JWT (for example, in the EU Digitial Identity Large-Scale Pilots). Unless there are very good reasons, they would certainly not appreciate us breaking the format at this stage.

-Daniel


I know it's the eleventh hour, so if these questions aren't productive now, please feel free to just point me in the general direction of the past discussions on this subject. Thanks.

_______________________________________________
OAuth mailing list -- [email protected]
To unsubscribe send an email to [email protected]
_______________________________________________
OAuth mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to