-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Opportunities to improve the credential query/request syntax #112
Comments
Notes from conversations from three open space sessions at OSW and IIW titled "What does Presentation Exchange do and what parts of it do we actually need?" can be found at https://self-issued.info/?p=2427 and https://self-issued.info/?p=2395. In all these conversations, many people expressed the viewpoint that Presentation Exchange is pretty complicated. |
I'll go on record here as being not a fan of PE. |
I think I understand the points outlined in this issue and agree we should discuss if/how we would address them. For the limitations of using JSON Path with CBOR-based mdoc format, this thread also might be useful: WICG/digital-credentials#80 (comment). Having said that, I also think it is important to discuss and understand what in PE has worked well. So I'll go on record here that PE does the job:
Again, not saying PE is perfect, or the current approach is the best, just believe these points should be taken into account in this discussion. |
You will see from comments that I made over a year ago that mandating the use of DIF PE was a bad design choice. Instead we should give flexibility to implementors to use whatever query language their community of users choose. |
I also believe we need a better way than PE for expressing queries. I have worked on and with several different credential formats, including fully JSON-based ones like IETF SD-JWT VC that do not have any special namespace considerations and have native support for selective disclosure, W3C VCDM 2.0 with a lot of optionality even in the proof format and the way claims use namespaces via
I believe having a credential-format agnostic query language like PE is quite challenging for those reasons. |
As cited at openid/OpenID4VCI#266 (comment), a few of us have been working on a format-specific query language proposal as a strawman to replace PE. This was motivated in part by @tlodderstedt's request during the IIW session to "show me a specific counter-proposal". See https://docs.google.com/document/d/10JT--pXWsfwC4QVu3XJpXGwcO08M6tnpkZ4PKdtCEWo . |
Chair hat on, would suggest to proceed as following:
Notes from Feb-22-2024 WG call, Some requirements
Options in the solution space (does not have to be only one of these - doing 1 and 4, for example, seems to be an option)
|
In all cases, we need to define profiles for credential formats. Even if we had one query syntax that appears similar for all credential formats, it would have significantly different meanings per credential format, which is equivalent to defining a syntax per credential format. This applies to all four options. Under this assumption: Regarding option 1, I'm not convinced that having a profile for PE for each credential format is the best option. There is a risk that implementers will make mistakes, implement additional features not recommended, or become overwhelmed by the feature set that PEv2 offers. Note that they will need to refer to the PE spec anyway and find sections that apply. Regarding option 2, it is similar to option 1. Regarding option 3, I would be fine with that, but again, we would need to profile it anyway. I am uncertain if being credential format agnostic is a goal that can be achieved or one that we actually want to achieve. Reusing some components across credential formats does make sense, for example, how to encode constraints such as certain fields being required in the response. Note that openid/OpenID4VCI#276 is actually more like option 4 since it uses the top-level namespace/credentialSubject object for mdocs/VCs, which is not common among the credential formats. Regarding option 4, it is essentially the same as option 3. Regarding options 3 and 4, I see them both as almost equivalent since you will need profiles anyway, and the interpretation of the query will differ depending on the format even it looks similar. I think the reuse of constraints (required, requiredIfPresent, intentToRetain, etc.) makes a lot of sense, but we should have the flexibility to cater to structural/encoding characteristics of formats, which has already been demonstrated in openid/OpenID4VCI#276. I don't think the goal is to have an n-number of query syntaxes for one credential format. Ideally, it should be just one, defined aligned with the patterns the respective community has already used. |
I don't understand why verifier metadata negotiation is part of this discussion. There is a mechanism in place that works well with OID4VP. We even added a feature, client identifier scheme, to facilitate this negotiation. The method by which PE populates some of the supported curves is redundant and unnecessary. We even have a paragraph that states, "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." Therefore, |
@Sakurann You appear to missed out the option of having the query language as an extension point, which brings a lot of advantages, a main one being future proofing, another one being innovation. Some in the WG like this approach whilst others do not. An argument made against it was that it kills interop. But this argument is fallacious for several reasons. |
@awoie verifier metadata negotiation is part of the discussion because there is no agreement on the statement @David-Chadwick thank you! updated my original comment to add "having the query language as an extension point" as an option :) |
My point was that there is implicit agreement codified by normative language in the OID4VP spec: "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." |
that language might be residual from before we negotiated with PE authors to add a top level format parameter in the PE. also that sentence only talks about the formats negotiation and not the rest of the metadata. so I think the large question is still in tact. |
I don't understand what this means, according to github, IMO, it is not a requirement of any query syntax to communicate any of these metadata. We have client metadata for this and changing this is would be a fundamental shift for OID4VP. We have an issue to do real capability negotiation and using PE for this was never brought up nor included in any proposal. I believe nobody argued for putting other client metadata into the query syntax. |
On the 22 Feb 24 call @Sakurann pointed out that this kind of "voting" alone on PE wasn't particularly helpful, which is fair. My concern with PE is somewhat more high-level. It promises to provide an awful lot of useful functionality but is extremely complex. This kind of standard often sounds/looks good on paper and even in narrowly constrained testing at first but the real cost of the complexity and sometimes inability to actually provide purported functionality doesn't show up until later and manifests in serious interoperability and security issues or lack of adoption/use. That's maybe not much more helpful that a "vote" but tried to convey some of my rationale. |
Our experience is that PE supports a lot of functionality that on paper sounds useful, but that in the end leads to a lot of complexity when trying to build systems that support many different flavors of credentials for reasons many mentioned above (encoding matters, storage method matters, structure matters, typing matters, features matter...)
We ignored Features for now When only using absolute paths with non-regex filters we came to a more or less understandable implementation - but one that still involved having Intermediate Representation of credentials, and translating PE to another query language, and one that was still very complicated.
Reducing the set of PE would make sense at least to me, but I am not sure how that would be enforced and communicated. The feature set would need to be very clearly defined, and referenced in the base spec and not in the interop-profile.
This could potentially give us an opportunity to define the base/core of the spec that we think is aligned with our requirements, so I think I prefer it more compared to suggestion #1.
Could make sense, but seems like a lot of work, and given that many have already implemented PE it might be easier to try to fix that one before designing yet another mini-language.
I think the spec should allow for multiple query syntax(or their versions), but that it should mandate one across all implementations. Example: VP 18 mandates PEv2, but it could allow you to use a specific one that might fit your system better. Mandated one(s) would ensure interoperability, while the optional ones would allow for experimentation, competition, and local optimizations. This could possibly also allow for easier switching from one version/flavor of query syntax to another. This would probably require some registry of known query syntaxes. |
I'd like to add support for @Sakurann's suggestions, namely
I'd take this a step further and suggest PE v3 is adopted as a work item of this group. To paraphrase @selfissued I do not believe we should allow for multiple query languages if one will do. Standards make choices. Optionality is the enemy of successful interoperability. Because I believe PE v3 will take a while, my immediate suggestion is to profile a subset of PE v2 and require it for all implementers of OID4VP. Separately, I'd like to make a comment on the complexity of PE. As one of the authors/editors of PE v1 and a contributor to v2, we tried to represent the complexity present in the credentials space, which is itself highly complex. I could succeed in making an argument that OAuth, OIDC, and OID4VC are all really complex specs. This is not me suggesting that we increase that complexity, rather, it's an acknowledgment that our subject area is inherently complex and the reasoning "too complex let's exclude it" is misleading at best. Many engineering teams have implemented PE successfully. I have personally done so multiple times. It's not an insurmountable task, albeit annoying at times. This represents an opportunity for us as editors to find opportunities for simplicity that works for our use cases. |
does anyone have an example of how to turn a PE request into a meaningful user consent form that can fine on a smart phone screen? |
@TomCJones My understanding of current models is that the user consents to what information can be released that satisfies the PE request, not what information was requested by PE, so there is never a need to turn PE into a user consent screen. So for example if the PE requests a proof of name from either a driving license or a passport, it does not seem important for the user to know that this was the request - only for the user to be asked (in the case where they only have a driving license on their phone and not a passport) whether they would like to release the name in their driving license credential to the verifier. Can you explain a situation where it would instead be important for the user to understand the request the verifier made? At least in my example, it would seem considerably less user friendly to try to explain the request to the user. |
I think you are telling me that the verifier gets to create a sql injection attack against the user, the user gets a list of all of the credentials and all of the data fields in those credentials as a consent request from what? one aggregator wallet, each wallet in turn (perhaps three of them) will they are standing in a line to get on an airplane or into a concert and makes an informed consent decision? All of the ideas about informed consent that i have been involved with the question in their mind is what the verifier is going to do with the data. I don't see where informed consent is addressed in any of this! It sounds to me like a direct violation of nearly every data protection law in existence. |
Hi Tom To complete my example, if the user has a driving license and a passport stored on their phone, and for the purposes of this example they are stored in different wallets, then my understanding of the flow might work (as is being defined in the WICG group):
This is fully informed consent. No one here has any interest in designing flows that fail to comply with data protection laws, that would be a fruitless endeavour. |
i guess i don't see an example of the screens the user sees. Who's job is it to display the name of verifier and what they want to do with the data? For what purpose do they want the data? Is the verifier trustworthy? the device or each wallet. I can see some simple use cases going to six screens depending on the design. |
Hi Tom. I think your original question about PE has been answered and we've now veered significantly away from the subject of this ticket. I think some of the WICG folks have demos of the flow, it might be worth asking there. |
+1 here I dont believe we should allow multiple query languages, that would be a failure of the standard to foster interoperability.
If you are referring to my last point, I don't believe that is the argument I'm making. I'm merely pointing out that there is a trade off, every feature a protocol or standard chooses to define has a cost associated to and that there needs to be a counter balance saying "do we really need this feature, is it worth the cost"? Having also participated somewhat in P.E I don't believe it got that right, the inclination was to say "yes" to every use case, rather then challenging which features were actually needed. I think its abundantly clear that especially in the context of OpenID4VP that P.E defines way more features then required for its application, evidence of which can been seen via the heavy profiling of P.E done in HAIP, ISO 18013-7 and OpenID4VP itself. That redundancy has a significant cost associated to it. |
Valid points are raised, but I also want to make a few points from our side:
I agree and am in favor of others pointing out:
|
is there any evidence that normal human users or verifiers will accept VPs? |
In an effort to make some of my concerns more concrete, I've compiled 3 examples of P.E requests, I think they highlight very clearly why profiling P.E would be entirely insufficient to fix the issues here Example 1 How should one process the following query?
The ambiguity around this query is that selective disclosure in an mDoc can only be done to the "$['org.iso.18013.5.1']['driving_privileges']" level. So what should a wallet respond with here, the whole driving_privileges structure OR nothing? A similar issue also exists when applied to an SD-JWT that encodes a nested object as a single disclosure rather as a series of nested disclosures all the way down to the leafs. This in my opinion quite clearly highlights the issue with using either JSON Path OR JSON Pointer as the basis for a query syntax, it can't express the nuanced constraints of a credential format like SD-JWT or mDoc reliably. Example 2 Similar question how should one process this query?
Without Example 3 As a verifier if I were trying to determine whether the holder has a US drivers license, e.g by determining whether it contains a real ID claim without them knowing, I could use the following query to disguise my request
The problem here is two fold
Based on the logical processing of P.E for the above if the real_id attribute was present on the matched credential it would be returned and the holder would likely have given consent based on the "name" thinking they were releasing their "Family name". Secondly in the case the wallet actually didn't have the real_id attribute on the drivers license, the fact that the family name is returned here, proves the real_id attribute doesn't exist, leaking this to the relying party. Both of these cases above are concerning from a data privacy perspective and can't simply be addressed by profiling P.E they are fundamentally designed into it. |
@tplooker can you explain how these situations can be resolved please - e.g. are you suggesting defining a query language that simply doesn't allow the queries in your examples to be made? |
In short yes I believe a proposal like what is given in https://docs.google.com/document/d/10JT--pXWsfwC4QVu3XJpXGwcO08M6tnpkZ4PKdtCEWo/edit#heading=h.7igj7m3na8ru avoids these issues by
|
I believe this clearly shows there's lack of semantic interoperability, and IMO this is not the issue of the query language. But fun begins when you want to combine claims from different VCs. Ecosystems with good data model governance won't have this problem :) |
Agreed, it is because the credential formats are different. It is not a query language issue. I just wanted to demonstrate that the query language would need to cater to that. It would be probably better to embrace those differences and have
:) |
Even if the format is different, one should be able to match the claims. Open or closed system, claim definitions are always defined. In code (at least on GO), CBOR and JSON are serialised into objects using exactly the same approach. No namespaces, no path extensions, ... If issue is not in the query language, which is IMO the case, the issue should be renamed into "querying claims or VCs in an open world-ecosystem" or "how to achieve semantic interoperability"? |
With ISO mdocs, there is no such single envelope structure you could serialize from CBOR to JSON (there are multiple). Also, perhaps you could serialize the ISO |
I'd argue the true cost here isn't actually any higher. For an implementation to support a new credential format they have to add a bunch of code anyway to handle the actual response, validating it, interogating it etc. Asking them to also add support for a query structure that likely closely mirrors the actual form of the credential they get in response is actually a reduction in complexity and implementation cost. The alternative is asking them to add a bunch of a format specific sanitisation checks to a generic query syntax to support a new credential format like what @awoie has pointed out, and even in doing that the resulting queries still appear brittle and prone to abuse IMO. |
The problem is most of these credentials are not simple JSON documents nor can they be modelled as such. They could be using other data representation technologies like CBOR and or aren't even one consistent data structure, the information in a credential can be split across entirely different places (e.g mdoc has an MSO and an IssuerSigned structure which are totally different structures), W3C VC DM has a single JSON document but all the subject claims are grouped in one place "credentialSubject", SD-JWT is different again with in effect two different places credential information can actually exist (the payload and header) not to mention features like selective disclosure can be applied to varying parts of the credential including different levels of nesting. All of these differences make it extremely problematic to try and provide a generic query interface as there fundamental design is entirely different. |
I'm not sure this is how information is processed today. If my understanding is correct, you claim that queries are actually made to credentials in a signed format and not in the unsigned format? JWS/JWT compact or JSON serialised (applies to both JSON or JSON LD representation): all claims are always in the payload. Even if selective disclosure is used, wallet will always expand the SD into a JSON/JSON-LD and store that (and queries should be done over this structure since verifier cannot know in advance how the information will be packaged, when signed) -> In other words, when it comes to JSON, you (always) validate the schema against JSON schema/shacl/... Same applies to CBOR. CBOR is just a format that is expressing a data model. How information is transported, must be irrelevant. With CBOR it should be even simpler, because CBOR is used in environments with well defined and fixed data models. |
IMO, you are right but this is not well defined. It is also not really clear if you would need to run JSON-LD expansion for LD-credentials first before querying the data. Strictly, those things need to be (better) defined by the format-specific profiles.
All claims are not always in the SD-JWT payload (Issuer-signed JWT plus Disclosures). Some of the claims are in the Disclosures, not in the Issuer-signed JWT. But I agree, it should be done like this but it is not defined. For that reason I asked to make this explicit in the PR on SD-JWT VC profile #115. Otherwise, you would break PEv2 because there is no such PEv2 "input" document that contains all the information.
Please look at the ISO 18013-5 specification. You don't want to use the ISO mdoc internal data structure in your query, you would want to use something more abstract instead, i.e., using namespaces/data element identifiers only. And I think this is also what you were saying because the data model is defined. However, PE uses JSONPath which requires some JSON document to refer to certain elements, i.e.,
ISO does not define an "input" document that can be used with JSONPath (PEv2). That is why we had to redefine the semantics of PEv2 for ISO in the ISO spec which was a bit awkward. If you simply transform ISO CBOR to JSON and call this JSON document the "input" document that PEv2 requires, the queries would be bloated and are not really usable. It might be also hard to do CBOR to JSON conversion since there are a few decoupled data structures. |
JSON-LD has several representations and the format in the query should clearly define the representation (compact JSON-LD (which is essentially JSON), expanded, ...) SD-JWT + disclosures is actually the signed form. When you decode the SD-JWT you will always result with JSON. Verifier cannot know in advance where/how the claims are "hidden". They will just say: give me a VC with "first_name", "last_name" according to vocabulary XYZ. ISO structure is very simple: it has a namespace and an identifier as per 7.2, table 5.
If multiple namespaces need to be supported, it's the 2nd option. And I agree, all this needs to be defined - and it's regardless of the query language you define. Even if the new query language is accepted, you will have exactly the same problem, and all we're discussing about, must be defined (prior to considering of introducing a new query language). |
Sorry, but this is the encoding for the JWT that is used in ISO 18013-5:2021 Server Retrieval (which nobody uses and which does not match the CBOR structure). That is not used by ISO 18013-7.
Yes, that all needs to be defined. And yes, it does not matter whether you have credential format-specific query syntax or not. But by being credential format-specific you are not limited in expressiveness, effectiveness, robustness of the how to use the syntax because it is tailored to the needs of the credential format. |
As mentioned above, this is not the applicable section. You have to look at 8.3.2.1.2.2 Device retrieval mdoc response |
It occurs to me I should clarify, with my bigger DIF hat on*: DIF will happily interoperate with whatever comes out of this discussion. We're also open to bigger changes in the next major PE release if that's helpful. There are some great ideas being discussed here. Not an easy decision but it seems to be in good hands. Daniel and I are always available if there are further questions we can help with. *we'll call it the DIF sombrero, vs the PE baseball cap |
I think I never said anything else than this and I fully agree that a query syntax should follow this approach. That is what for instance the query syntax proposal we shared does. My point was that with the current version of PEv2, you won't be able to do that since it requires a "JSONPath" and an "input" document (that defines the $ for the JSONPath). Structure 7.2 in Table 5 does not exist and is not a real structure btw. (not persisted this way). It is just a list of data element identifiers and their values. You can certainly say, use Table 5 and put it in a specific JSON document and then use this as the value for the input document in PEv2. Updated: |
@alenhorvat PEv2 requires a transformation algorithm from the credential to an intermediate format. PEv2 defines a technical algorithm for matching/filtering based on JSONPath applied to an input document. The intermediate format is the PEv2 input document. This transformation algorithm needs to be defined per credential format. Some credential formats such as W3C VCDM don't require that since it is JSON(-LD) already. Other require this algorithm such as ISO mdocs (which we kind of implicitly did in ISO 18013-7 Annex B; we didn't call it such). Because you need such an algorithm, you are additionally limited in how you persist credentials because you have to persist the credentials in this intermediate format in your database to run the filters/matchers efficiently. Like you said, it would be better to use Table 5 on namespaces and data element identifiers directly in case of ISO. The query syntax should use those directly and should not require a transformation to an intermediate first. |
To make it crystal clear, the goal of the credential-format specific query language we proposed is NOT to replicate the structure of the credential (in JSON). The goal is to create a syntax with a reasonable semantic abstraction per credential format. The reason why I talked about the CBOR structures was to counter argument the point that a simple transformation from CBOR to JSON can be done and using the output for the input doc in PEv2. Doing this would make no sense since it is way too convoluted. |
I'd much rather have a simpler per-format directive for placing all target data in a single set of curly braces and running a unified query language over that than descend into a per-format query language expedition where eventually a lot of features will have to be copied across differing query languages in slightly different forms and have User Agents/OSes continually involved as they evolve toward equivalent levels of expressiveness - thar be far more dragons of far greater ferocity, imo. |
@csuwildcat you mean something like this? mdoc
SD-JWT VC
This would be my preference. |
Not quite - I was referring to placing the target data portions of a credential in a JSON container, running JSON Pointer queries over it, and testing the results with JSON Schema declarations, instead of creating bespoke, per-format syntaxes that will eventually end up recreating one-off doppelganger versions of these well-established, industry standard utilities that are already known by millions of devs. |
IMO, this requires ISO mdocs to be transformed to JSON documents first which is already a bit awkward. This has to be defined somewhere. It would make it also hard to run queries without support for JSON Pointer. It means, developers cannot use their own database scheme, they would need a database that supports JSON pointer queries and they would need to store the credentials in the transformed JSON document. Am I missing something? Wouldn't this be a strong limitation or assumption we make for a lot of developers? Note that in the case of format-specific queries, you don't need to define that transformation. You just define a couple of indexes but how those are implemented is up to the developer. |
That's a bit of a canard, because any bespoke syntax isn't going to be natively supported by a db query syntax either. The reality is that users aren't going to have millions of credentials, so pulling hundreds to a few thousand from local storage and running a query function over them is trivial. Also, popular DBs actually do support JSON Path/Pointer, Postgres for example. |
That is true but it is more trivial to define indexes/keys for a very limited set of defined terms in your query syntax. It would be easier to choose your own database schema.
There are people that don't want to run those queries locally.
Yes, that is true but this means, you would need to store the credentials (e.g. mdoc) in the transformed JSON form. |
To support a new credential format developers already have to invest significant implementation effort to support the credential format anyway, because they need to know how to parse, validate and generally understand it, so even with a generic query syntax, a lot (majority IMO) of this cost will exist. The question then becomes how much cost does a generic query syntax save vs the complexity it creates through its abstract nature? What I've argued is based on the developer feedback we've seen over multiple years is that any savings in implementation re-use that P.E might bring across credential formats is far outstripped by the general confusion around how to use P.E in the first place because of how abstract it is. |
WG mtg
Could we close this issue and open a new one focusing on the concrete syntax (starting point being what we have here: https://docs.google.com/presentation/d/1OxqQy4-WC5BmplCyuo-oKriXZVj2fBrGPCg7n9ryCcg/edit) in a new issue @tplooker ? that might influence the requirements, so issue #144 will remain open until updated syntax is merged. |
based on the discussion in this issue, specific proposal for an alternative query language has been made in #178 and the WG has agreed to use it as a starting point. closing this issue in a week, if no objections. |
Over a period of time through implementation feedback on OpenID4VP, several items around the current credential query syntax (based on P.E v2) have been raised. To the best of my ability I have attempted to summarise some of those that I have heard below
Usage of JSON Path/Pointer
Presentation exchange v2 which is the current target of OpenID4VP makes use of JSON Path, which is a highly expressive DSL for reading JSON documents. The problems identified with it are that because of its broad expressivity and feature set, it creates certain security and use-ability challenges.
JSON pointer is a narrower expression syntax then JSON path which alleviates most of the security challenges and has been considered before as an alternative. But to some it still represents significant use-ability challenges and is still arguably too flexible/complex for most of the applications we have within OpenID4VP credential queries/request syntax where the path expressions we desire to be able to define are usually just simple traversals through nest maps and or arrays.
Furthermore some of the credential formats defined by OpenID4VP are not JSON based instead use technologies like CBOR which gives rise to other possible challenges.
The feature set of P.E is massive
Presentation Exchange itself beyond its usages of JSON Path/Pointer is highly expressive enabling all sorts of incredibly complex queries to be represented. However this complexity burdens both developers who need to write robust implementations of P.E and know how to create valid credential request/queries using P.E. Certainly the feedback overtime that I have heard is many of the features of P.E aren't needed for most usecases or the implementation complexity they create outweighs their value.
P.E protocol agnostic design goal complexity
Presentation exchange from the outset aimed to define a query/request syntax that was protocol agnostic. While this design goal does lead to the potential for re-use of P.E across different protocols. It has created duplication of features that are already inherently present in OpenID4VP (and OAuth2 and OpenID Connect for that matter) such as capability negotiation between the protocol participants. For example OpenID and OAuth2 of which OpenID4VP is built atop has always largely handled capability negotiation through metadata exchanged/registered between the protocol participants rather then doing this negotiation during execution of the protocol itself. Whereas presentation exchange due to its protocol agnostic design goal defines how to negotiate things such as cryptographic suites in a credential request/query.
There are several options we have to solve these challenges and the purpose of this issue is to first better collectively understand these concerns and then discuss what solutions we could apply.
The text was updated successfully, but these errors were encountered: