openid / OpenID4VP

52 stars 18 forks source link

Credential format and supported algorithm negotiation #136

Open tplooker opened 6 months ago

tplooker commented 6 months ago

As raised on the DCP WG call on the 26th of March, currently the text in OpenID4VP is as follows.

The formats supported by a Verifier may be set up using the metadata parameter vp_formats (see Section 9.1). The Wallet MUST ignore any format property inside a presentation_definition object if that format was not included in the vp_formats property of the metadata.

In essence this establishes that the client metadata takes precedent over the formats element in the presentation definition. HAIP also further re-enforces this with the following text

The presentation of a SD-JWT VC is requested by adding an object named vc+sd-jwt to the format object of an input_descriptor. The object is empty.

I think there is a desire to now instead use the format feature in P.E instead of client metadata. I would prefer we strengthen the language in OpenID4VP to make it clear that the format property of the presentation definition should never be used and instead use only client metadata for this negotiation. Supporting doing the negotiation around this information in two places is likely to create significant confusion.

javereec commented 6 months ago

I interpreted that discussion that using client metadata doesn't allow you to differentiate which alg you want for which credential. To use an example to clarify.

You would convey the set of supported algs in client metadata

{
  "vp_formats": {
    "vc+sd-jwt": {
      "sd-jwt_alg_values": ["ES256", "ES512"],
      "kb-jwt_alg_values": ["ES256"]
    }
  }
}

But use PE to convey that you want 1 credential (I think PID was used as an example in the call) signed with a subset (ES512 in this example) of what was specified in client metadata (which doesn't support that distinction.

{
  "id": "example_sd_jwt_vc_request",
  "input_descriptors": [
    {
      "id": "pid_credential",
      "format": {
        "vc+sd-jwt": {
          "sd-jwt_alg_values": ["ES512"],
          "kb-jwt_alg_values": ["ES256"]
        }
      },
      "constraints": {
        "limit_disclosure": "required",
        "fields": [
          {
            "path": ["$.vct"],
            "filter": {
              "type": "string",
              "const": "https://credentials.example.com/identity_credential"
            }
          }
        ]
      },
      {
      "id": "other_credential",
      "format": {
        "vc+sd-jwt": {
          "sd-jwt_alg_values": ["ES256", "ES512"],
          "kb-jwt_alg_values": ["ES256"]
        }
      },
      "constraints": {
        "limit_disclosure": "required",
        "fields": [
          {
            "path": ["$.vct"],
            "filter": {
              "type": "string",
              "const": "https://credentials.example.com/other_credential"
            }
          }
        ]
      }
    }
  ]
}

The text that you referenced to me just seems to say that if you would use an alg that was not part of the set of algs in the client metadata (e.g. EdDSA) would need to be ignored.

javereec commented 6 months ago

Having said that, I support @tplooker 's sentiment that having two places in the spec to negotiate this will lead to confusion especially if there are dependencies between the two.

Also, I was thinking that when using scope to request a credential, there would also not be a possibility to negotiate this and as such client metadata is the most stable, logical reference point.

tplooker commented 6 months ago

I interpreted that discussion that using client metadata doesn't allow you to differentiate which alg you want for which credential. To use an example to clarify.

I think you're correct, that does appear to be the desire from some, specifically for a presentation definition to be able to select a subset from the set of algorithms they have declared support for in their client metadata. I'm however not convinced as to the value of allowing this. At the end of the day the relying party either possesses the ability to verify an say SD-JWT with an ES256 signature or not and the source of truth for this should be the client metadata alone, the presentation definition should not provide a way to do further negotiation on this as its just liable to create all sorts of implementation issues.

Sakurann commented 5 months ago

WG mtg.

peppelinux commented 5 months ago

I would start again from the security requirements, trying to answer the question: which methods ensure the non-repudiation of the request by the RP and the truthfulness of the parameters included in it?

Obtaining the parameters in the metadata opens the possibility of obtaining the metadata in different ways:

I believe we have never concretely addressed this. We are delving into the LoA of the request. Parameters has different LoAs based on how they are provided:

Obtaining everything in the metadata allows for a secure governance of entities and what they are supposed to do, for this reason, I believe that presentation_definition should be provided in the metadata and can also be anticipated in the request, provided that what is contained in the request is compatible with what is contained in the metadata (exactly like the scope parameter of rfc7591) and, if the metadata doesn't contain the presentation_definition it MUST be contained in the request.

Having put the metadata in an higher order of priority, I agree that the formats can be provided in the presentation definition, not duplicated in other places, and that the presentation_definition may be included in the metadata as well, without forcing the duplication in the request when not necessary.

tplooker commented 5 months ago

sounded like there is a rough consensus that algs specifying what verifier needs for a particular transaction belong in the input descriptor.

I'm not against this, provided we can articulate the use case where we need to dynamically request specific algorithms. I know it was discussed during the WG session but I'm still unsure that I understand it so bear with me!

What I picked up on in the session is that it appears there is a usecase where a verifier (client) wants to articulate in a request not "what I support" in terms of cryptographic securing algorithms for a credential, rather "what I want".

Generally I believe client or AS metadata is saying "what I support" where algorithms in the presentation definition is likely to more imply "what I want".

I've tried to articulate the use case I heard below during the session just so I understand it.

Say I am a verifier of PID's across the EU and country 1 supports algorithm X while country 2 supports algorithm Y and Z.

When I am requesting a PID which might be returned from country 2, I want to be able to request that the credential presentation use algorithm Z instead of Y, even though I support Y.

This appears to be what I understood the usecase to be ^. If it is correct, I have the following questions:

IMO even if we want to support algorithms in the presentation definition, for usecases that do not fit the above situation, we need to still have metadata describing what the verifier supports, because otherwise every RP that uses VP, that doesn't have the desire to dynamically request the cryptographic algorithm for a credential presentation, will be encumbered by having to put this information in every request.

David-Chadwick commented 5 months ago

I believe that presentation_definition should be provided in the metadata

This is similar to what we implemented. The variance was that the presentation definition was stored in an external policy server, and the metadata only held the URL of it. The trust infrastructure also held this URL for the RP's presentation definition, so that the RP could not change it dynamically (thereby requesting more PII than it had been trusted to request).

Sakurann commented 5 months ago

@peppelinux I think we need to differentiate verifier's metadata (that can, for example, be obtained vie OpenID Federation trust chain), and client_metadata parameter in the request.

putting presentation_definition in the verifier's metadata would limit use-cases because it does not allow tailoring it to a specific transaction. and right now, client_metadata enjoys the same level of integrity protection as a top-level presentation_definition parameter, so i do not see a clear benefit in doing so. At least in my mental model, presentation_definition is "what verifier needs in that particular transaction" and not "what verifier supports".

So if your your requirement is wallet being able to validate that verifier is authorized to request that presentation_definition, adding some kind of a reference in the trusted verifier's metadata (presentation_definition.id? presentation_definition_uri?) in addition to presentation_definition(_uri) in the request is probably the way to go.

David-Chadwick commented 5 months ago

@Sakurann

putting presentation_definition in the verifier's metadata would limit use-cases because it does not allow tailoring it to a specific transaction.

I think this is the nub of the problem. In my mental model the RP may support several different types of transaction, but each one will have a presentation_definition tailored to it. So the trust_infrastructure will record each of these transaction types and the presentation_definition that accompanies it.

I guess this issue then becomes, does each transaction instance of a given type require a different presentation_definition or not. I am assuming not. Perhaps you are assuming it does. Perhaps we need some use cases to highlight this. For example, "purchase any item on eBay". The presentation_definition may require the following credentials: customer's name, address, credit card details and email address, regardless of the item that is being bought. Do you have an example where a presentation instance will require a specific presentation_definition?

peppelinux commented 5 months ago

@Sakurann, I understand your point, but relying on uid or id references doesn't ensure the security that the input descriptors haven't been altered.

In my earlier assumptions, I considered part of the presentation definition to be static and another part to be dynamic, like the section related to data transactions (mentioned in another issue).

We might opt to keep the presentation_definition as it currently is in the request, not incorporating it into the RP metadata. Instead, we could introduce a policy parameter in the metadata, specifying how a presentation_definition should be filtered according to this policy.

This can be achieved by including the static part of the presentation_definition directly in the metadata and outlining how to filter the dynamic presentation_definition provided in the request, using the part specified in the metadata.

this could be easily achieved using the same method we have in the python dictionary .update method.