openid / OpenID4VP

47 stars 12 forks source link

Advanced flow for OpenID4VP #45

Closed OIDF-automation closed 4 months ago

OIDF-automation commented 2 years ago

Imported from AB/Connect bitbucket: https://bitbucket.org/openid/connect/issues/1401

Original Reporter: tlodderstedt

The current cross device flow works fine, however it forces the RP to make assumptions about the SIOP/wallet the user might choose to process the SIOP request.

I propose to investigate an advanced flow that involves an advertisement/discovery step and allows Rp and SIOP to better adjust the flow to each others capabilities.

The RP could render a QR code that give rise to its capabilities and endpoints. The user then scans that QR code with the wallet of her choice.

The wallet uses the QR code data and send a request to the RP containing its capabilities and endpoints/identifiers in a direct HTTPS POST request.

In the HTTPS POST response, the RP directly sends with the authentication request data (tailored for the particular SIOP).

As already noted, this flow would allow the RP and the SIOP to tailor the requests to each others capabilities. Also, the QR code could potentially be static and concise.

OIDF-automation commented 2 years ago

Imported from AB/Connect bitbucket - Original Commenter: dwc8

This sounds similar to the Condatis approach. It should also help to alleviate phishing attacks because the user will presumably know the DNS name of the web site displaying the QR code and this can be compared to the URL contained in the QR code, so that if the QR code is replaced by a phisher’s URL there will be a mismatch that will be visible. Its not foolproof, but could we add rules to the format of the QR code to make it more difficult for a phisher to replace?

OIDF-automation commented 2 years ago

Imported from AB/Connect bitbucket - Original Commenter: dwaite40

I think this approach, defined appropriately as a new protocol, would be much better than the current response_mode approach.

If I POST my OP metadata to get a request, I should just POST the response back to the same place once I’m done without the variability of front-vs-back-channel redirects, redefinition of redirect_uri as an API endpoint vs web endpoint, etc.

It also can be applied to non-SIOP use cases, e.g. the QR code could just take me to a page for a more stock ‘log in on your phone’ authentication flow.

OIDF-automation commented 2 years ago

Imported from AB/Connect bitbucket - Original Commenter: KristinaYasuda

This is the Condatis approach David C. is referring to: https://bitbucket.org/openid/connect/issues/1212/siop-chooser#comment-61693433

OIDF-automation commented 2 years ago

Imported from AB/Connect bitbucket - Original Commenter: KristinaYasuda

2022-01-27 call, agreed to create a PR, and continue discussion there

OIDF-automation commented 2 years ago

Imported from AB/Connect bitbucket - Original Commenter: KristinaYasuda

Is this about

  1. differentiating whether cross-device flow or same-device flow is being used?

    1. those have different protocol implications (HTTP POST vs redirect, etc.) and I don’t think SIOP currently has a clear way of differentiating the two - in the lack of such mechanism, our implementation, for example, supports only cross-device flow to accommodate more use-cases.
  2. or about differentiating between SIOPs

    1. preventing NASCAR screen - SIOP chooser, Condatis approaches

I think those are different topics and by re-reading the issue/comments it was not clear which one we are talking about..

OIDF-automation commented 2 years ago

Imported from AB/Connect bitbucket - Original Commenter: KristinaYasuda

bringing this issue up again as we agreed to come back to it after we extend SIOP to support not just Implicit flow.

OIDF-automation commented 2 years ago

Imported from AB/Connect bitbucket - Original Commenter: KristinaYasuda

@{557058:64689aae-f6d2-4db5-b56a-8b21020634d2} suggested using DID Documents to discover metadata as an option.

OIDF-automation commented 2 years ago

Imported from AB/Connect bitbucket - Original Commenter: dwc8

Using DID Documents opens up the flood gates to hundreds of different ways to discover metadata. I think the use of DIDs is not a particularly good idea as it leads to many different islands of (non)interop. Having a single defined method is the best approach in my opinion.

OIDF-automation commented 1 year ago

Imported from AB/Connect bitbucket - Original Commenter: KristinaYasuda

the proposed flow is exactly an ISO mDL flow.. where step 1 is mainly used to 1/select between protocols to use (BLE/NFC/Wifi Aware, etc) and exchange ephemeral keys to enable applicaiton level end-to-end encryption of the entire step 2, as opposed to communicating metadata for one specific protocol.

step 1

  • velifier → wallet: “here are my capabilities and endpoints“.

  • wallet → verifier: “here are my capabilities, endpoint (?), identifiers”

step 2

  • verifier → wallet: Authorization Request

  • wallet → verifier: VC/VP

in OID4VP, we already enabled a lot of flexibility for the verifiers to communicate metadata both within and before sending an Authorization Request. for the wallet, right now it is either pre-discovery or static metadata which i agree seems a little inflexible, but i always thought that the ultimate decision making was left to the wallet to choose formats/crypto within the range of what verifiers support (just like AS makes an ultimate decision).

I quesiton if we need this advanced flow.

OIDF-automation commented 1 year ago

Imported from AB/Connect bitbucket - Original Commenter: gffletch

Is it possible that the requirements of the verifier could change based on the request? If thinking about this in the context of a browser navigating to the verifier, the verifier could run a risk assessment on the browser connection and based on that risk assessment have a different set of requirements the wallet needs to meet. If so, then I’m not sure discoverable metadata is sufficient.

I also believe that for many RPs/verifiers as they roll out support for wallets will chose to first require the user to enter a login_id of some ilk and then transition to the QR code for the authorization request. This allows the verifier to apply some additional per user risk assessment before issuing the authorization_request to the wallet.

As long as the current specs allow for per transaction adjustment of the authorization_request based on the context of the request or the “user” involved, then we probably don’t need an advanced flow. However, I do believe this dynamic capability is required.

OIDF-automation commented 11 months ago

Imported from AB/Connect bitbucket - Original Commenter: tlodderstedt

I would like to bring this issue up again and extend it. I think a advertisement/discovery extension could be useful in same and cross device scenarios.

Here is how I would envision it to work:

1) There is a new type of message, let’s call it verifier advertisement for the moment. In case of same device, it is sent to a newly defined endpoint. In case of cross device, there is a dedicated custom scheme for it (openid-advertisement) in the QR Code.

2) The advertisement message contains contains a message identifier and the URL of a new endpoint at the verifier, let’s call it start presentation for the moment.

Note: I intentionally do not use any OAuth parameters in the advertisement message as I would like to give the verifier as much flexibility as possible to tailor the actual authorization (presentation) request to the wallet that will call the verifier (see George’s comment). I also would like to enable the advertisement to be used for different transactions. So this message could be printed out, put on a wall and scanned by several people to start a presentation transaction.

3) The wallet sends a POST request to verifier’s start presentation endpoint. This request contains the message identifier and the issuer URL of the actual wallet. This means the verifier learns what concrete wallet (product/service) it will talk to and can adjust its behavior accordingly. It can obtain all sorts of metadata including endpoints. For example, the verifier can determine the client id and client id scheme to be used with this particular wallet.

Further parameters could be:

4) The verifier creates a fresh authorization (presentation) request and sends it in the response of the POST request.

The rest of the process works like before.

Benefits if the proposed approach:

alenhorvat commented 10 months ago

@tlodderstedt see https://github.com/openid/OpenID4VP/issues/28#issuecomment-1706035807

Combining SIOP with another SIOP or OID4VP can solve the problem. Wallet acts like a (SI)OP, "verifier" acts like RP Since Verifier requires additional information (e.g., wallet metadata, wallet attestation, ...) Verifier starts a new intermediate SIOP/OID4VP flow, where the roles are reverted After the intermediate flow the original flow continues

Here's a high-level overview of how we combined the two: https://api-pilot.ebsi.eu/docs/ct/verifiable-presentation-exchange-guidelines-v3#context Good thing about the approach is that it re-uses the existing specifications as they are.

Sakurann commented 10 months ago

at OSW we discussed an alternative approach, which builds up on RFC9101 (passing request by reference): 1) verifier sends an authorization request with a request_uri to the wallet (custom url scheme, etc.) 2) when the wallet obtains the request object at a received request_uri, it sends a POST request with the parameters describing wallet capabilities, maybe wallet attestation etc. 3) flow continues

but I prefer @tlodderstedt 's proposal in this comment, mainly because:

Sakurann commented 10 months ago

@alenhorvat thank you - I am trying to better understand the flow you linked to: does the flow you point to work only when the wallet initiates the flow? is the assumption that the wallet knows verifier endpoint out of band? how does cross device flow look like? why is there token request from the wallet - what is access token scoped for? why does the description text talk about credential req-res if this is about presentation? Is the Self-issued ID Token of the wallet sent in the first authorize request to the verifier without verifier provided nonce?

alenhorvat commented 10 months ago

I believe there are 2 possible scenarios a) dynamic wallet discovery - in this case a simple POST to an ?authorisation? endpoint with wallet metadata could solve the problem (same behaviour as redirect_uri except that it can accept the wallet metadata and adjust the request object accordingly) b) verifier requires additional info - here the VP flow can be re-used as described above.

Essentially there can be two scenarios (for b) a) VP flow embedded into another VP flow b) 2 sequential VP flows (this is essentially what @tlodderstedt described)

asharif1990 commented 10 months ago

The proposal of @tlodderstedt sounds good to me as it helps to solve the problem of wallet invocation. I am in favor of using (app link/universal link). However, I would like to recommend considering the Wallet Instance Attestation to be shared with the Verifier in addition to the parameters mentioned in in this comment, as it provides a way for the verifier to obtain useful information regarding the security level of wallet besides what is already mentioned by @peppelinux in https://github.com/openid/OpenID4VP/issues/28#issuecomment-1706035807.

alenhorvat commented 10 months ago

Hi @Sakurann. We elaborated the flow EBSI designed and adjusted the terminology to the proposal of @tlodderstedt https://api-test.ebsi.eu/docs/ct/verification-offering

I hope this answers (some of) your questions.

peppelinux commented 10 months ago

Providing the WIA during the presentation phase, better if before obtaining the signed request object, we have the following benefits:

peppelinux commented 10 months ago

considering also that there are cases where the wallet instance acts like a verifier that requests a presentation, or obtains a presentation offer, to/from another wallet instance, the sole trust to be established between the actors is the WIA, since the wallet instance is not an organizative entity with a publick endpoint where to publish its metadata/keys (while the wallet provider, that's the WIA issuer, has it)

side note: We may assume that the verifier_attestation we have in OpenID4VP SHOULD allow multiple typ allowing that the attestation may be of different type (issue here: https://github.com/openid/OpenID4VP/issues/32)

Sakurann commented 10 months ago

btw Issue #47 mentions another mechanism to discover wallet metadata - using service nedpoint from the wallet's DID Doc

alenhorvat commented 10 months ago

@Sakurann, to use that mechanism the wallet needs to communicate it's DID, first. It boils down to the "dynamic wallet metadata discovery" we're discussing here.

David-Chadwick commented 10 months ago

@tlodderstedt It would be good if you could upload your swim lane for your proposed message flow for this issue that you showed to us in the meeting of 7 Sept 2023. WRT to that flow, my concern is that the assumption is that the wallet trusts the verifier and is prepared to send information to the verifier before knowing if the verifier is who they say they are, or can be trusted. Thus the first message from the verifier to the wallet should allow the wallet to determine if the verifier is trustworthy (or not). This can be achieved by the verifier saying "this is me", which can be a true or false statement, it does not matter since the wallet will verify this. (Therefore the verifier's message does not need to be signed). It the wallet determines that 'this is me' is trustworthy it should be able to collect sufficient meta information about the verifier in order to continue the dialogue, without any further direct interaction with the verifier e.g. by going to a well known place for 'this is me' to retrieve the meta-data. In the WG call of 7 Sept @tlodderstedt raised the issue that although my proposed solution works if both the verifier and wallet are in the same trust domain, it does not work if they are not in the same trust domain. However this is not true. It is possible for the verifier and wallet to be in different trust domains but if they share a common trust protocol they can still determine the other's trustworthiness. (This is how X.509 and TRAIN works for example.) Furthermore, the OIDF GAIN POC WG is developing a solution for cross domain trust where the entities are in different trust domains and use different trust protocols as well (by using OID Federation as the common bridging protocol). So we should leverage the GAIN work and incorporate the GAIN message(s) into the initial dialogue between the verifier and wallet, and then any wallet will be able to determine the trustworthiness of any verifier (and vice versa) providing they both either support GAIN or the same (possibly proprietary) protocol.

peppelinux commented 10 months ago

I read diligently the entire thread.

Is there any concrete reason for not extending the request_uri endpoint with a POST http method that would allow us to use rfc7521 to pass the wallet attestation?

Alternative to rfc7521 already implemented in Italy: we use dpop in the RP request_uri to provide the wallet attestation with a proof of possession.

We have decided dpop because It is very simple and doesn't require the http post method.

However this doesn't solve the problem for wallet 2 wallet interactions, probably It would be Better to define a new specialized endpoint/URL-scheme to enable the provisioning of the wallet attestation.

This increases complexity.

The concept of the presentation offer gives us a way to provide the wallet attestation. The wallet instance presents itself to an RP and this latter has to uniquely identify the wallet instance to know which request forge for It later on, within the request uri endpoint. This sounds like a kind of wallet registration to the RP, that could be made even without complete the presentation phase. Something that lives by its own.

Before going ahead we should care about the risks that this feature May be exploited to collect wallet attestations by RP without any scope related to the presentation. -> this would be possible Also with dpop/rfc7521/any-other.

By extending the request_uri endpoint we restrict the scope of the request for the provisioning of the signed request, for the same scope and withing the same request the wallet provides the attestation (dpop in http get or rfc7521 with http post) according to the italian approach.

I'm not excluding the advertisement endpoint, I'm Just wondering about the impacts of that and I look forward to work more on this with you.

mtaimela commented 10 months ago

There's two protocols: Issuance and Presentation. The problem below is solved in the issuance side (VCI).

..however it forces the RP to make assumptions about the SIOP/wallet the user might choose to process the SIOP request.

The key for the introduction is the XXX Offer and client driven discovery. I think it is important to keep these two specs symmetrical, so if the problem also requires "wallet to wallet issuance and presentation", then the Offer(s) should be amended with the metadata for the discovery and possibly a signature to protect the metadata.

Why Presentation should not adopt the Offer pattern? This pattern works and exists in Issuance side. If you would not like to introduce Presentation side Offer, please remove it from the Issuance too

peppelinux commented 10 months ago

@mtaimela your proposal makes sense, it would be better make VCI and VP similar

tlodderstedt commented 10 months ago

@mtaimela the proposal I made uses the same pattern as the credential offer. @peppelinux where do you see a difference?

Please find attached the sequence diagram I used yesterday to illustrate the idea.

image

fbaud commented 10 months ago

Hi @tlodderstedt,

We did implement a workflow that is close to your sequence diagram, but with some differences due to our particular architecture.

We have:

Now for the differences:

All in all, we have definitely adopted a sequence for presentation separate from the issuance, even if very similar for the steps 1 to 4. And we strongly support having a distinct specification from issuance

We do support what we call dynamic bootstrap like the one in your sequence diagram, or static bootstrap (user agent produces a qr code as a gif without ever contacting the verifier). We can support the 2 modes thanks to number 4 call, but definitely need to have a transactionId AND verifier_state to be passed all along to let the verifier mimic the rest of the workflow

peppelinux commented 10 months ago

@tlodderstedt

the difference is the semantic, offer != advertisement. I have worked on a similar approach, where:

  1. advertisement endpoint is called pre-request-uri-endpoint
  2. in this pre-request-uri-endpoint I detect if the device is mobile or desktop, then I decide if return a QRCode or a Redirect, then I create the session (with state, nonce, cookie bindings and so on) and return the Response, something like this
HTTP/1.1 /pre-authz-endpoint Found
Location: https://wallet-provider.eudi.wallet.gov.it?
client_id=https%3A%2F%2Frelying-party.example.org%2Fcb
&request_uri=https%3A%2F%2Frelying-party.example.org%2Frequest_uri%3Fid%3Drandom-value
  1. why transaction-id exists wouldn't state be enough?
  2. number 5 -> why the wallet creates a presentation request, wouldn't be the RP to create that? It's just a semantic issue that confuses minds, we may just mention "request_uri endpoint", since it is the RP that requests a presentation while in this step the wallet instance just fetches the signed request

For now the most relevant question would be HOW the wallet can provide the wallet attestation to the request_uri endpoint? DPoP or RFC7521 or any alternative?

Then when I read an ephemeral key - to be used to encrypt the authorization request I assume that the wallet attestation must contain at least a public key, is then this ephemeral key really required?

fbaud commented 10 months ago

@tlodderstedt @peppelinux ,

While on the semantic side, here are my own bias:

offer != advertisement. <<

we call it a credential-call to distinguish from a credential-offer. Beyond the semantic, I believe that the pull vs push has some implication on the design and authorisations. That is the reason I believe the 2 workflows should be separated

1 advertisement endpoint is called pre-request-uri-endpoint <<

we also distinguish between the pre-request part, which is an exchange between our widget and the verifier server and the request which is mainly between the wallet and the verifier server. But we should be able also to bootstrap without a pre-request in what we called the static bootstrap (e.g. gif sent by email)

2 in this pre-request-uri-endpoint I detect if the device is mobile or desktop <<

This is where we have a very different situation. The user agent is a widget, and it is its business logic that decides everything concerning the bootstrap, in particular what it is asking the wallet to provide and what the verifier server should know to complete the workflow

3 why transaction-id exists wouldn't state be enough? <<

It should be enough. But we also pass the 2 because we want to be able to recreate a state from the transaction-id in case the state disappeared on the server (failback procedures). Actually we call the transation-id a credentialCallId

4 number 5 -> why the wallet creates a presentation request <<

My understanding was that number 5 was a call for the verifier to create a presentation request, which is what we do in our implementation. But to be more specific, in our case, the verifier server is creating a request based on the instructions explicited by the widget (with potential additonal elements mainly related to the security policy of the verifier server).

fbaud commented 10 months ago

Hi @alenhorvat

It seems I'm not able to open the document at https://api-test.ebsi.eu/docs/ct/verification-offering

alenhorvat commented 10 months ago

https://code.europa.eu/ebsi/ecosystem/-/blob/ebip/oid4vp-presentation-offer/drafts/oid4vp-presentation-offer.md

mtaimela commented 10 months ago

Hi @tlodderstedt

Please find attached the sequence diagram I used yesterday to illustrate the idea.

Regarding the diagram, I think this will definitely work. It also looks like that the "Presentation Flow" is not yet discovered, just the means of transferring VCs is (transport envelope with DIFv2).

So how about if we treat OID4VP just as a component in the "undiscovered Presentation Flow", and this component could also be replaced with SIOPv2 (ID Token)? In the end, asking for "Claim based proofs" vs "just DID control proof" is a matter of Verifier's knowledge.

With the component thinking in mind, OID4VP and SIOPv2 components implements the OIDC "authentication" capability (which is normally implemented with username/password screen). So could it be possible to consider the option of starting with the Advertisement, then diving into /authorize code flow, prompting the "OID4VP component", and in the end resulting into Access Token?

This would make Presentation and Issuance quite similar, while Presentation becomes the new login or information submission protocol. It would also allow the Verifiers to be more oriented with "OAuth 2.0 protected endpoints" principle.

Sakurann commented 10 months ago

@peppelinux do you mean RFC9101 (RAR).

I think that's the proposal I made here, but I am not in its favor because i think Torsten's proposal is cleaner in terms of separating what verifier sends before//after it knows wallet capabilities/attestations..

also I do not think reusing DPoP is a good idea for various reasons because it reuses somehting meant for other purposes, so for example it would mean stuffing extra claims expressing wallet capabilities in DPoP JWT

tlodderstedt commented 10 months ago

Regarding the diagram, I think this will definitely work. It also looks like that the "Presentation Flow" is not yet discovered, just the means of transferring VCs is (transport envelope with DIFv2).

This sequence diagram describes how to request and present a presentation of one or more credentials (OID4VP). It will also be able to cover SIOP v2 (as it only adds another pre-step before the actual authorization request is passed from the verifier to the wallet), i.e. the request object in step 6 would also contain SIOP v2 parameters, like a scope "openid".

peppelinux commented 10 months ago

@peppelinux do you mean RFC9101 (RAR).

Not sure I meant RAR but I fully agree with you to have a specialized endpoint for handling the wallet instance authentication with a verifiable attestation (WIA) instead of pushing it to an endpoint that was intended for other scopes (request_uri)

the flow we have implemented aims to give a wallet verifiable metadata discovery to the RP, when this issues will reach an actionable conslusion then implementing the endpoint would be the way to go

peppelinux commented 10 months ago

@tlodderstedt before giving the conclusions and the agreements within this thread, could you please answer or give any hints to file the points raised here https://github.com/openid/OpenID4VP/issues/45#issuecomment-1712357096

peppelinux commented 10 months ago

another though

We have discussed about the value of having a specialized endpoint for doing the wallet discovery, since we need it in both presentation and issuance phase

having a special purpose endpoint, reusable, it could be used also for wallet2wallet presentations, using custom url schemas

other kind of relations may happen, like wallet2RS (authentic sources, and so on). A basic component, avulsed by the context and then usable in multiple contexts

mtaimela commented 10 months ago

@peppelinux

We have discussed about the value of having a specialized endpoint for doing the wallet discovery, since we need it in both presentation and issuance phase

The text leaves room for two specialised endpoints or for one unified. In general, I would prefer not to have multiple endpoints for a single application. The problem lies in mobile configurations as you may register the default endpoints to different apps, which will cause usability issues. Single scheme or Universal Links/App link is better as parameters or values can handle the behavioural split. I'm referring to VCI and VP invocation mechanisms.

peppelinux commented 10 months ago

In the following issues I would like to explore with you how we may get a proper generalization of oauth-attestation-based-client-auth to design the nonce endpoint as a protected endpoint and give a good harmonization in both OpenID4VCI and OpenID4VP (within this issue)

https://github.com/vcstuff/draft-ietf-oauth-attestation-based-client-auth/issues/46

@tlodderstedt WDYT?

tlodderstedt commented 10 months ago

I would like to get the design of the flow for OpenID4VP straight before we discuss harmonization.

tlodderstedt commented 10 months ago

Here is the PR for this issue: https://github.com/openid/OpenID4VP/pull/52

peppelinux commented 9 months ago

An alternative flow was provided here: https://github.com/openid/OpenID4VP/pull/52#issuecomment-1741179550

please provide your reactions/comments if any

tlodderstedt commented 8 months ago

Hi all, I filed a new PR with an alternative design for the advanced flow. It is less sophisticated but simpler and more privacy preserving. I hope it can be the basis of a consensus. Have a look at PR #59.

Sakurann commented 4 months ago

PR merged