berendsliedrecht / sd-jwt-ts

Selective Disclosure JWT (SD-JWT) Draft 06 & Selective Disclosure JWT VC (sd-jwt-vc) Draft 01 implementation
https://www.npmjs.com/package/@sd-jwt/core
Apache License 2.0
16 stars 2 forks source link

Support recursive disclosures #2

Open TimoGlastra opened 11 months ago

TimoGlastra commented 11 months ago

The SD-JWT spec describes the possibility of recursive disclosures. Where you can have a selectively discloseable value, that then contains selectively discloseable values within the selectively discloseable value: https://www.ietf.org/archive/id/draft-ietf-oauth-selective-disclosure-jwt-06.html#name-example-sd-jwt-with-recursi

Doesn't seem like a really important feature to support right away, but opening this issue to keep track of the status.

We would probably have to add another field that can be added to the disclosureFrame to indicate the property itself should be recursively dislcosed. Currently when you provide the following dislcosure frame:

{
            credentialSubject: true,
            __decoyCount: 2,
            credential: {
                __decoyCount: 3,
                dateOfBirth: true,
                name: true,
                lastName: true
            }
        }

You get the following output (kinda)

{
    iat: 1700555090380,
    iss: 'did:key:some-random-did-key',
    nbf: 1700555090480,
    credential: { _sd: ['credential-disclosure-digest-1', 'credential-disclosure-digest-2'] },
    _sd_alg: 'sha-256',
    _sd: [
      'txiegb4QZDKwnzkeYSzDCqdbR9uHUSU7RW2uPIFO2_k',
      'uNPp8xv9pJwWUkMDY17jEiUuPjIcZOJwS75GXJ8SIW8',
      'xZapa_MT9GR3NpyhrgEyM12sUNOknfRYTSahiQISUlM'
    ]
  }

Following the structure of __decoyCount, I think we can do something like this for the disclosure frame:

{
            credentialSubject: true,
            __decoyCount: 2,
            credential: {
               __recursiveDisclosure: true
                __decoyCount: 3,
                dateOfBirth: true,
                name: true,
                lastName: true
            }
        }

To receive this output:

{
    iat: 1700555090380,
    iss: 'did:key:some-random-did-key',
    nbf: 1700555090480,
    _sd_alg: 'sha-256',
    _sd: [
      'txiegb4QZDKwnzkeYSzDCqdbR9uHUSU7RW2uPIFO2_k',
      'uNPp8xv9pJwWUkMDY17jEiUuPjIcZOJwS75GXJ8SIW8',
      'xZapa_MT9GR3NpyhrgEyM12sUNOknfRYTSahiQISUlM',
      'this-is-the-digest-for-credential-the-disclosure-contains-the-nested-disclosures'
    ]
  }

Not fully happy with the __recursiveDisclosure name yet, but I hope you get the idea.

berendsliedrecht commented 11 months ago

Just to be clear, it means that you can selectively disclose each attribute within a nested object AND the nested fully by itself? If it is an OR it is already supported, but not both together within a single credential.

TimoGlastra commented 11 months ago

I think it's an AND. You can e.g. have the whole credential object selectively discloseable, and within that object you could then either have:

and this could be nested as many layers deep as you want.

So to parse an SD-JWT to the decoded payload you would have to parse a disclosure, see if it has an _sd field of itself, and then do the same trick, until you find an object that does not have the _sd property anymore

TimoGlastra commented 11 months ago

But by making the credential object itself selectively disloseable, you don't give away that there is an credential object to begin with. In the complex example currently it is the case that you can see the credential key, while you could hide that, as well as make all items of the credential object itself selectively discloseable

berendsliedrecht commented 11 months ago

Let me check the spec later, would be good to double check this. I might've missed this when reading through it.

TimoGlastra commented 11 months ago

It seems the Meeco implementation does support recursive disclosures: https://github.com/Meeco/sd-jwt

berendsliedrecht commented 11 months ago

I can't seem to find an example of what this library does not support, do you have a direct link?

TimoGlastra commented 11 months ago

See the link to the spec I posted in my initial message: https://www.ietf.org/archive/id/draft-ietf-oauth-selective-disclosure-jwt-06.html#name-example-sd-jwt-with-recursi

TimoGlastra commented 11 months ago

I think the following output is not possible:

{
  "_sd": ["credential-property-digest"]
}

With the following disclosures:

["salt", "credential", {
   "_sd": ["first-name-digest", "last-name-digest"]
}] // digest = "credential-property-digest"

["salt", "firstName", "Timo"] // digest = "first-name-digest"
["salt", "lastName", "Glastra"] // digest = "last-name-digest"
berendsliedrecht commented 11 months ago

I see, yes that is not possible currently. I think for now I will just apply the fix you provided with the __FIELD_NAME_TBD within the object. Not the cleanest but it should suffice for now. Thanks for pointing it out.