Selective Disclosure JSON Web Tokens (SD-JWTs) provide a key mechanism for selectively disclosing individual elements of a JSON object. Thanks to recent work by Indicio, this credential format has been added to Aries Cloud Agent Python (ACA-Py). Here’s what it means for you.

By Char Howland

Indicio has added support for the SD-JWT credential format to Aries Cloud Agent Python (ACA-Py). This recent contribution includes API endpoints that sign and verify SD-JWT payloads. This investment in updating protocols demonstrates the Aries community’s commitment to and progress towards providing compatibility with the standards selected by the EU. Further work will enable the exchange of SD-JWT credentials both within the existing DIDComm based Verifiable Credential (VC) protocols as well as the OpenID4VC protocols, for which Aries support is already in progress. Adding the EU standards to the AnonCreds and DIDComm VC Protocols provides the best of both worlds: regulatory compliance when needed, demonstrable privacy, power, and additional capability when required by the application. 

Aries is committed to being a premium codebase for the support of all standards that facilitate Self Sovereign Identity (SSI) and decentralized identity. The Aries community prides itself on flexibility: this was not the first external standard chosen by the Aries community for interoperability, and it won’t be the last.

Selective Disclosure Json Web Tokens (SD-JWTs) provide a mechanism for selectively disclosing individual elements of a JSON object used as the payload of a JWS structure. SD-JWTs add an important privacy-preserving feature for the use of JWTs as verifiable credentials. SD-JWTs do not have all the features of AnonCreds, but their development is a step forward for technologies that require the use of JWTs.

SD-JWTs provide a variety of selective disclosure options. 

The recipient of a JWT can view all claims within the JWT. As described in the SD-JWT specification, if the holder wants to reveal only a subset of the claims in their SD-JWT during a presentation, the claims in the payload of the SD-JWT are hashed and therefore not viewable to the verifier. For the claims that the holder would like to reveal, the holder includes disclosures, which are the plaintext claims corresponding to the hashed claims in the payload. When the verifier receives the SD-JWT with the disclosures, it hashes each disclosure to ensure that the result matches one of the hashed claims in the payload. If it matches, then the verifier has proof that that claim is in the original signed SD-JWT, but they can’t view any claims in the SD-JWT that do not have a corresponding disclosure provided by the holder.

To provide an analogy for this mechanism, consider receiving an SD-JWT as if you were receiving a large locked box. You have the key for it, and when you open it, you discover that inside the large box there are several small locked boxes inside, as well as keys to a subset of those lockboxes. You unlock these boxes for which you have been given keys and discover their contents; however,you can’t open the boxes for which you didn’t receive corresponding keys. By contrast, a JWT would be the same as receiving a large box, unlocking it, and being able to view all of its contents. If I don’t need to view every item within the box but the items cannot be taken out of the box, the SD-JWT is the more privacy-preserving option.

A feature of SD-JWTs is that the issuer decides which claims can be selectively disclosable. The holder can only selectively disclose the claims that the issuer has designated as selectively disclosable. For the claims that the issuer has not designated as selectively disclosable, the holder has no choice but to reveal those claims when they present the SD-JWT. In this implementation, by default, all claims at all levels of the payload can be selectively disclosable, unless indicated otherwise by the issuer (with the exception of essential verification data such as iss, iat, cnf, etc., which are always visible). If the issuer does not want a claim to be able to be selectively disclosable, they must provide a JSON path, which specifies the claim’s location within the JSON structure.

This implementation supports various options for the selective disclosability of nested structures within the payload. Consider the nested structure of the “address” claim, which has subclaims of “street address,” “city,” and “zip code.” The issuer can determine the ways in which the holder can selectively disclose this claim and its subclaims.

One option is that the issuer can decide to treat the address claim as a block that can either be disclosed completely or not at all. In this case, neither “address” nor its subclaims are visible in the payload, giving the holder the option to choose whether or not to reveal this information in a presentation. The plaintext disclosure corresponding to the “address” claim will contain each subclaim, which means that if the holder includes this disclosure, they will reveal every subclaim. In this implementation, the issuer provides JSON paths to the subclaims to indicate that they are not selectively disclosable.

If the issuer wants to handle the object in a more structured manner, it may instead decide to make the “address” claim contents selectively disclosable individually. In this case, “address” is visible in the payload and is not able to be selectively disclosable, but its subclaims are hashed. The holder will receive disclosures for each subclaim, so that they can decide which specific subclaims to reveal by including their corresponding disclosures in the presentation. In this implementation, the issuer provides JSON paths only to the “address” claim, leaving the subclaims at their default selective disclosability.

A final option is that the issuer may decide to make the “address” claim selectively disclosable as a block and its individual subclaims recursively selectively disclosable. In this case, the “address” claim is hashed in the payload as in the first option, but its corresponding disclosure contains hashes of the individual subclaims. The hashes of these individual subclaims each have corresponding disclosures. In this implementation, the issuer provides no JSON paths related to “address” or its subclaims, leaving each at their default selective disclosability.

In addition, this implementation supports the selective disclosure of array items, which can be indicated by the issuer using list indexing or splicing, as well as an optional mechanism for key binding, which is the concept of binding an SD-JWT to a holder’s public key and requiring that the holder prove possession of the corresponding private key when presenting the SD-JWT.

This addition provides the foundation for further support, both for use with the OpenID4VC protocols as well as the DIDComm Verifiable Credential protocols. This work allows Indicio to better support those that have requirements to adopt the standards being endorsed by the European Union. These technologies work alongside our existing technologies within Aries and those available as part of our Proven product, allowing Indicio to better support those who need to adopt the standards endorsed by the European Union.

Learn more:

SD-JWT Pull Request to Aries Cloud Agent Python
Documentation of SD-JWT Implementation in ACA-Py
SD-JWT Specification


Please feel free to reach out to Indicio, or contact

Char Howland
GitHub: cjhowland

Daniel Bluhm
GitHub: dbluhm