oauth-wg / oauth-sd-jwt-vc

draft-terbu-sd-jwt-vc
Creative Commons Zero v1.0 Universal
17 stars 11 forks source link

defining how DID can be used as user's indetifier #205

Open Sakurann opened 5 months ago

Sakurann commented 5 months ago

There are use-cases that would like to use IETF SD-JWT VC draft over W3C VCDM draft, while using DID as user's/subject's identifier. Currently, SD-JWT VC mandates cnf claim to be present. It would be very helpful to define how a DID can be used with a cnf claim. (as keeping cnf claim as mandatory is probably better for the interoperability)

paulbastian commented 5 months ago

I know that some people propose to use kid inside cnf.

I think that it would be better to register a new sub claim did in the IANA confirmation registry to use DIDs.

awoie commented 5 months ago

Yes, we had that discussion recently. It will be something as follows:

"cnf":{
  "did":{ "url": "did:example:1234#some-key" }
}
Sakurann commented 5 months ago

Where should cnf.did be defined?

bc-pi commented 5 months ago

My intuition is that sd-jwt-vc is not an appropriate place to define and register a new DID based JWT Confirmation Method. I'm not sure where it would be done but that'd be stretching the scope of this draft.

Meanwhile cnf.kid seems sufficient for the case.

Sakurann commented 5 months ago

cnf.kid instead of cnf.did? why would we need to defined cnf.did if we think cnf.kid is sufficient?

bc-pi commented 5 months ago

I guess that was kinda what I was implying/suggesting. That cnf.kid is sufficient so cnf.did doesn't need to be defined.

The interpretation of the kid value is application specific (per RFC7800) and can convey the same info as Oliver's example:

      "cnf":{
         "kid": "did:example:1234"
       }
awoie commented 5 months ago

I fully agree that it is not in scope of SD-JWT VC to define the did cnf method. However, I think this would be the cleaner approach. I would expect clients using this cnf method to register a did cnf method. kid does not really help with interoperability.

Sakurann commented 5 months ago

kid does not really help with interoperability.

Why? either relative of absolute DID URL, it is being used as a kid value already.

awoie commented 5 months ago

kid does not really help with interoperability.

Why? either relative of absolute DID URL, it is being used as a kid value already.

There is nothing wrong with this but I would assume that most implementations won't test if kid is a DID URL. To make it explicit people could just use a dedicated DID cnf method. This is really a design decision implementer's should make. If kid using DID URL is an established pattern, nothing wrong with doing this. If not, I'd recommend using a dedicated cnf method but this depends on personal preference. My preference is using a dedicated cnf method since the approach is cleaner.

awoie commented 5 months ago

@Sakurann is there anything where you believe we should update the SD-JWT VC specification?

Sakurann commented 5 months ago

is there anything where you believe we should update the SD-JWT VC specification?

one sentence saying that "when key is passed by reference (assuming Briand would not want to explicitly mention DIDs in the spec), cnf.kid should be used" would be helpful, so that people reading the specification know that SD-JWT VC can be used with DIDs too.

bc-pi commented 4 months ago

I took a try at the following proposed new text to replace cnf here that attempts to be inclusive of opinions expressed in this issue and also addresses issue #196 :

cnf

  • OPTIONAL. Contains the confirmation method identifying the proof of possession key as defined in [RFC7800]. This claim MUST be present when cryptographic Key Binding is to be supported. It is RECOMMENDED that this contains a JWK as defined in Section 3.2 of [RFC7800]. When the key is to be conveyed by reference (e.g., via a key thumbprint or DID [W3C.DID]), other JWT confirmation methods MAY be used, such as a key identifier defined in Section 3.4 of [RFC7800]. For proof of cryptographic Key Binding, the Key Binding JWT in the presentation of the SD-JWT MUST be signed by the key identified in this claim.
Sakurann commented 4 months ago

+1 to the proposed text - thank you, Brian!

awoie commented 4 months ago

I'd be ok with this change although we need to adjust the language a bit.

Option 1:

Option 2:

I would prefer Option 1 and recommend that if having a DID as a being included in the cnf value is required, defining a dedicated cnf method for that would be needed which is a much cleaner approach. I don't think we need to put this recommendation into the spec.

Note that I think that using DID URL for the kid value in the signed KB-JWT/Issuer-signed JWT is totally fine.

There is a reason why there is a dedicated x5c cnf method instead of putting the base64url-DER-encoded certificate in the kid in the cnf claim.

paulbastian commented 4 months ago

I agree with Oliver.

Kid is described as application specific and having a dedicated cnf.did method gives it a more universal touch that may be beneficial for interoperability.

bc-pi commented 4 months ago

I think the most beneficial thing for interoperability would be always and only use cnf.jwk for key binding. But that's a digression...

This document is not going to define a dedicated cnf.did method.

The sentence, "When the key is to be conveyed by reference (e.g., via a key thumbprint or DID [W3C.DID]), other JWT confirmation methods MAY be used, such as a key identifier defined in Section 3.4 of [RFC7800]." in the proposed text above is a just MAY to say that a cnf.kid or to-be-defined cnf.did could be used to convey the key binding key by reference. I'd honestly rather not have it that sentence at all (note that using cnf.kid or to-be-defined cnf.did isn't prohibited now it's just not mentioned) but it was my attempt to accommodate the ask by @Sakurann. Saying DID URL rather than just DID in that sentence would be okay for me too. But I don't think much more in this area would be appropriate here.

cre8 commented 4 months ago

It depends how we define "proof of possession key" in context of a DID document, where multiple keys can be used to proof the identity. In case of natural persons when they prefer to use dids, it's more likely they use did:key or did:jwk. But since SD-JWT-VCs can also be issued to a legal person that can be using did:web, did:ethr it is able to register multiple keys.

Key rotation in this scenario are a good security feature because they allow me to update my crypto material without issuing me new credentials that are directly bound to it. On the other hand I am unable to insert security mechanism like hashlinks since I want to point not directly to one specific public key, but to one having specific rights.

awoie commented 4 months ago

It depends how we define "proof of possession key" in context of a DID document, where multiple keys can be used to proof the identity. In case of natural persons when they prefer to use dids, it's more likely they use did:key or did:jwk. But since SD-JWT-VCs can also be issued to a legal person that can be using did:web, did:ethr it is able to register multiple keys.

Key rotation in this scenario are a good security feature because they allow me to update my crypto material without issuing me new credentials that are directly bound to it. On the other hand I am unable to insert security mechanism like hashlinks since I want to point not directly to one specific public key, but to one having specific rights.

Yes, this makes sense. However, cnf.did might be more appropriate to encode this information.

cre8 commented 4 months ago

It depends how we define "proof of possession key" in context of a DID document, where multiple keys can be used to proof the identity. In case of natural persons when they prefer to use dids, it's more likely they use did:key or did:jwk. But since SD-JWT-VCs can also be issued to a legal person that can be using did:web, did:ethr it is able to register multiple keys. Key rotation in this scenario are a good security feature because they allow me to update my crypto material without issuing me new credentials that are directly bound to it. On the other hand I am unable to insert security mechanism like hashlinks since I want to point not directly to one specific public key, but to one having specific rights.

Yes, this makes sense. However, cnf.did might be more appropriate to encode this information.

Yeah, since we can not reuse this approach from the spec since it has a defined response.

"cnf":{
  "jku": "did:exmaple.com",
  "kid": "key123"
}

Wouldn't it be the best way to extend the RFC for CNF to include the did resolution as an option? Of course this is more work, but then we can reference to a standard

paulbastian commented 4 months ago

It depends how we define "proof of possession key" in context of a DID document, where multiple keys can be used to proof the identity. In case of natural persons when they prefer to use dids, it's more likely they use did:key or did:jwk. But since SD-JWT-VCs can also be issued to a legal person that can be using did:web, did:ethr it is able to register multiple keys. Key rotation in this scenario are a good security feature because they allow me to update my crypto material without issuing me new credentials that are directly bound to it. On the other hand I am unable to insert security mechanism like hashlinks since I want to point not directly to one specific public key, but to one having specific rights.

Yes, this makes sense. However, cnf.did might be more appropriate to encode this information.

Yeah, since we can not reuse this approach from the spec since it has a defined response.

"cnf":{
  "jku": "did:exmaple.com",
  "kid": "key123"
}

Wouldn't it be the best way to extend the RFC for CNF to include the did resolution as an option? Of course this is more work, but then we can reference to a standard

jku can not be used in my opinion.

RFC7800 says:

This is done using the "jku" member. Its value is a URI [RFC3986] that refers to a resource for a set of JSON-encoded public keys represented as a JWK Set [JWK], one of which is the proof-of-possession key.

I do not think that this matches to (most) DID documents.

cre8 commented 4 months ago

It depends how we define "proof of possession key" in context of a DID document, where multiple keys can be used to proof the identity. In case of natural persons when they prefer to use dids, it's more likely they use did:key or did:jwk. But since SD-JWT-VCs can also be issued to a legal person that can be using did:web, did:ethr it is able to register multiple keys. Key rotation in this scenario are a good security feature because they allow me to update my crypto material without issuing me new credentials that are directly bound to it. On the other hand I am unable to insert security mechanism like hashlinks since I want to point not directly to one specific public key, but to one having specific rights.

Yes, this makes sense. However, cnf.did might be more appropriate to encode this information.

Yeah, since we can not reuse this approach from the spec since it has a defined response.

"cnf":{
  "jku": "did:exmaple.com",
  "kid": "key123"
}

Wouldn't it be the best way to extend the RFC for CNF to include the did resolution as an option? Of course this is more work, but then we can reference to a standard

jku can not be used in my opinion.

RFC7800 says:

This is done using the "jku" member. Its value is a URI [RFC3986] that refers to a resource for a set of JSON-encoded public keys represented as a JWK Set [JWK], one of which is the proof-of-possession key.

I do not think that this matches to (most) DID documents.

That's why I mentioned we need to update or extend the spec so it is compliant with the response of a did doc. We either extend the jku usage or define a new field like did.

paulbastian commented 4 months ago

It depends how we define "proof of possession key" in context of a DID document, where multiple keys can be used to proof the identity. In case of natural persons when they prefer to use dids, it's more likely they use did:key or did:jwk. But since SD-JWT-VCs can also be issued to a legal person that can be using did:web, did:ethr it is able to register multiple keys. Key rotation in this scenario are a good security feature because they allow me to update my crypto material without issuing me new credentials that are directly bound to it. On the other hand I am unable to insert security mechanism like hashlinks since I want to point not directly to one specific public key, but to one having specific rights.

Yes, this makes sense. However, cnf.did might be more appropriate to encode this information.

Yeah, since we can not reuse this approach from the spec since it has a defined response.

"cnf":{
  "jku": "did:exmaple.com",
  "kid": "key123"
}

Wouldn't it be the best way to extend the RFC for CNF to include the did resolution as an option? Of course this is more work, but then we can reference to a standard

jku can not be used in my opinion. RFC7800 says:

This is done using the "jku" member. Its value is a URI [RFC3986] that refers to a resource for a set of JSON-encoded public keys represented as a JWK Set [JWK], one of which is the proof-of-possession key.

I do not think that this matches to (most) DID documents.

That's why I mentioned we need to update or extend the spec so it is compliant with the response of a did doc. We either extend the jku usage or define a new field like did.

A standalone kid is also valid according to RFC7800 3.4, but for interoperability the best solution would be a new method did. But @bc-pi said, he thinks that this spec is not the right home for such an IANA registration.

awoie commented 4 months ago

kid does not really help with interoperability.

Why? either relative of absolute DID URL, it is being used as a kid value already.

We should have further restrictions on the DID URL. a kid containing a DID URL that is a DID would resolve to multiple keys potentially, which would cause ambiguity.

I made a mistake previously when I said using a DID URL would solve the problem since a DID is also a DID URL:

did-url = did path-abempty [ "?" query ] [ "#" fragment ]

whereas path-abempty can be literally completely empty which allows a DID to be a DID URL which makes sense because it is the location of the DID Document.

We would need to say that kid must be a DID URL that when dereferenced results in a single key (ideally JWK).

Sakurann commented 4 months ago

I think the text Brian suggested originally is sufficient: https://github.com/oauth-wg/oauth-sd-jwt-vc/issues/205#issuecomment-1947438330

(at least initially) please keep the option to use cnf.kid, as limiting the use of DIDs only with cnf.did could be a significant blocker for some implementations to implement sd-jwt vc. especially if sd-jwt vc will not define cnf.did (and I won't even attempt to try convince Brian to do so).

I also think it is probably better to say DID URL as opposed to just DID.

awoie commented 3 months ago

I think the text Brian suggested originally is sufficient: #205 (comment)

(at least initially) please keep the option to use cnf.kid, as limiting the use of DIDs only with cnf.did could be a significant blocker for some implementations to implement sd-jwt vc. especially if sd-jwt vc will not define cnf.did (and I won't even attempt to try convince Brian to do so).

I also think it is probably better to say DID URL as opposed to just DID.

Why is it a blocker if they use cnf.did instead of cnf.kid?

awoie commented 2 months ago

After some discussions, we believe the best approach is to define a dedicated cnf method for DIDs through a very small spec.

TimoGlastra commented 1 month ago

As having implemented DID holder binding for SD-JWT VCs while this discussion has been ongoing, we've decided to add the didUrl (pointing to the specific key that has been verified before issuance) in the kid value of the cnf claim.

So it will look something like:

{
   "cnf": {
       "kid": "did:example:123#key-id"
   }
}

Not sure if relevant for this discussion, but to show some implementers feedback on something that we have working today.

Happy to change our implementation on what comes out of this discussion.

awoie commented 1 month ago

As having implemented DID holder binding for SD-JWT VCs while this discussion has been ongoing, we've decided to add the didUrl (pointing to the specific key that has been verified before issuance) in the kid value of the cnf claim.

So it will look something like:

{
   "cnf": {
       "kid": "did:example:123#key-id"
   }
}

Not sure if relevant for this discussion, but to show some implementers feedback on something that we have working today.

Happy to change our implementation on what comes out of this discussion.

While I cannot prevent anybody from using this, I would find it much cleaner to use a dedicated DID claim for this for interoperability reasons. It should be fairly easy to write a DID cnf IETF draft:

{
   "cnf": {
       "did": { "did_url": "did:example:123#key-id" }
   }
}
TimoGlastra commented 1 month ago

As i mentioned in my post, we're happy to change our implementation on what comes out of this discussion.

But until then re-using existing fields is a lot easier to integrate. kid been used for did key identifiers for multiple years already