Skip to content
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

Do the /exchanges/* endpoints need authz? #279

Open
msporny opened this issue Mar 30, 2022 · 72 comments
Open

Do the /exchanges/* endpoints need authz? #279

msporny opened this issue Mar 30, 2022 · 72 comments
Assignees
Labels
ready for PR Issue ready to be resolved via a Pull Request

Comments

@msporny
Copy link
Contributor

msporny commented Mar 30, 2022

At present, the /exchanges/* endpoints are being implemented to have optional authz. That is, implementers can add authz to those endpoints if their use cases require it.

At least one implementer does not require authz for performing presentation exchanges, but rather does authn/authz in the /exchanges/* protocol itself. One use case has the Issuer implementing the /exchanges/* endpoint, a Holder engaging with the endpoint, and the Issuer responding with a DIDAuth request to authn the Holder. This does not utilize OAuth2 to establish software client authz.

This approach has been challenged to be insecure, so this issue is to discuss the attack models and security characteristics of this approach.

@msporny
Copy link
Contributor Author

msporny commented Mar 30, 2022

This issue was spawned from a discussion in #48.

@msporny
Copy link
Contributor Author

msporny commented Mar 30, 2022

In #48, @tplooker said:

I still don't seem to see how an e2e flow would work in the case of say issuing a personal identity credential (e.g DL or PRC). To me this flow involves three entities, the wallet, issuer and End-User. Typically unless you are assuming the wallet is handed some token of authorization that identifies who the End-User is and proves the wallet has the authority to request the credential from the issuer, then this has to be done within the protocol flow. I understand that designing of authorization protocols is out of scope for this spec and that its relationship is optional, but how do they relate when they need to?

Say you are using plain OAuth2 or OIDC to do user auth and issue an access_token, does the wallet include this somehow in a request to the interact API? Does that make the VC API a resource server of the IDP? What scopes need to be granted to get this access_token or does it not matter?

Maybe im missing the point, I'm just struggling to see how the protocol flow works e2e for that case?

@msporny
Copy link
Contributor Author

msporny commented Mar 30, 2022

I still don't seem to see how an e2e flow would work in the case of say issuing a personal identity credential (e.g DL or PRC).

Finally, a real opportunity to use Github's new mermaid-js feature!!! :P

I'm going to use a "Student ID" as the example to avoid any politically charged reactions from others that might engage in this thread. Here's a rough sketch on how you'd issue a Student ID to a Wallet:

sequenceDiagram
    participant W as Wallet
    participant I as Issuer
    autonumber
    W->>I: Request Student ID via POST .../exchanges/new-student-id/z123456 (VC-API)
    I->>W: DID Auth Request (VC-API + VPR)
    W->>I: DID Auth Response (VC-API + VP)
    I->>W: Present new Student ID (VC-API + VP)
Loading

Now, a careful reader would notice that anyone could intercept .../exchanges/new-student-id/z123456 (this is effectively an Swiss Number capability, that is authz via knowledge), and use it to retrieve a specific Student ID and bind it to a DID that you have control over. So, a naive view would assert that at least two things matter for the security model here:

  1. The Issuer is able to get that capability-based URL to the Wallet over a secure channel OR they're able to pre-register a software client.
  2. It is imperative that some process bind the student to the ID at some point. In order to bind the student to the ID, a physical biometric is probably required (photo).

Attacks against item 1 are software proxies running on the student's wallet. If the student can run software that intercepts and proxies requests (and there is a healthy market for fraudulent IDs in most countries), all forms of software pre-registration and secure communication are defeated.

That leaves item 2 as the only real mitigation, and even that needs to be done on a regular basis (or at least, before a critical use of the ID). Even if a proxy is not being used, the device can be sold and/or re-purposed (new biometric authn registered/changed).

Does the above resonate? Is there a different security model under consideration?

@tplooker
Copy link
Contributor

tplooker commented Mar 30, 2022

Does the above resonate? Is there a different security model under consideration?

Yes it certainly helps to get to the next level of detail.

The Issuer is able to get that capability-based URL to the Wallet over a secure channel OR they're able to pre-register a software client.

Im not sure this is quite the right framing of the options, the questions I have and apologies for just dropping a list of them I'll attempt to explain my perspective below:

  • what does the end to end flow look like, including how this URL (capability) was generated?
  • Who generated the URL is their a security domain boundary between them and the "Issuer" or is it the same entity?
  • Did the generation of this URL involve user auth, if not how does the interaction id in the URL become related to a specific user?
  • How long is the URL valid for, can you run the flow multiple times OR is there some replay attack prevention mechanism?
  • Whats the relationship between the system that generated the URL and the system hosting this instance of the VC API that the wallet is now interacting with?
  • Is the user aware at the point that this URL is generated that the wallet can get this credential, put another way when was consent obtained for the end user or does that happen later?
  • When does capability negotiation between the wallet and the issuer occur to ensure the result is actually going to be useable by the wallet? Ideally the earlier the better here.

In my opinion, what happens before this flow is that the wallet has to obtain this url (capability) some how. To me that is an authorisation flow. One where the wallet makes a request to get a particular credential, for a particular user (e.g this URL). Obtaining this authorisation usually involves authentication and consent from the user (often the subject of the credential in personal identity usecases). Who this entity the wallet goes to, to obtain this url (capability) also affects these things, im assuming logically the entity that you obtain this URL from is the same entity the wallet is interacting with in the above sequence diagram? Because the fact that the capability is in the form of a URL like this implies that there is some state being managed behind the scenes here in relating the id featured in the URL to some ongoing transaction or session?

@tplooker
Copy link
Contributor

tplooker commented Mar 30, 2022

IMO the last paragraph above touches on some of the limitations involved in using URL based capabilities rather than say cryptographically secured tokens, the former imposes more session based state management by the issuer and likely a coupling of the entity responsible for generating the capability to the entity where the capability is exercised (e.g the "issuer" in the above diagram).

@msporny
Copy link
Contributor Author

msporny commented Mar 31, 2022

The questions I have:

I'll try short/quick answers to these and then follow them up with a more detailed diagram that attempts to summarize the answers.

  • what does the end to end flow look like, including how this URL (capability) was generated?

Summarized in the diagram below.

  • Who generated the URL is their a security domain boundary between them and the "Issuer" or is it the same entity?

The simplest case is that the Issuer generated the URL. A more complex case is that an entity that the Issuer can communicate with, in a SECURE and out of band fashion, generated the URL. Yet another more complex use cases is that a completely different entity generated the URL and placed encrypted data in the URL (e.g., CWT) that only a particular recipient can decrypt. For the purposes of simplicity, let's just focus on the first two, because we haven't found any use cases that need that last one.

  • Did the generation of this URL involve user auth, if not how does the interaction id in the URL become related to a specific user?

If by "user" you mean "the subject of the VC", then yes, it did. When the the subject of the VC is through the auth process, they're given the URL over a secure transport (e.g., same device CHAPI). Yes, insecure transports (cross-device QR Code) /could/ be an issue -- and we'll get to that later.

  • How long is the URL valid for, can you run the flow multiple times OR is there some replay attack prevention mechanism?

The presumption is the URL is valid until they pickup their VC OR a certain amount of time has elapsed (15 minutes). So, yes, replay attack prevention is expected to be implemented at the Issuer for "high value" credentials.

  • Whats the relationship between the system that generated the URL and the system hosting this instance of the VC API that the wallet is now interacting with?

The presumption is that they're in the same trust boundary in the simplest case. There are cases where one can "hop" trust boundaries via the "interact" field in VPR. So you can start at one trust boundary, do part of the flow, and then hop to another trust boundary (using VPR + any other protocol). When you do this you MUST ensure that there is some sort of transferrable trust from one boundary to the other -- like a JWT in a URL or VC in POST data -- both of which can be expressed via VPR "interact".

  • Is the user aware at the point that this URL is generated that the wallet can get this credential, put another way when was consent obtained for the end user or does that happen later?

This is an open question. I think your assertion is that consent MUST be acquired before they initiate the VC exchange. In that case, there are multiple ways it can happen, but the most straightforward is: The Issuer can ask the subject "Do you want to store this Student ID in your digital wallet?" -- and then a mediator is invoked or QR Code is displayed.

  • When does capability negotiation between the wallet and the issuer occur to ensure the result is actually going to be useable by the wallet? Ideally the earlier the better here.

Yes, this would be the first exchange, where the Issuer would state the features it needs from the wallet (query 1 in the VPR), and the DID Auth request (query 2 in the VPR), and the wallet would receive those and, if it can't fulfill either query, tell the user why. While failing isn't the ideal outcome, if the wallet can't fulfill the request, it can't fulfill the request.

There is an option here where the wallet can register features it has in the mediator (CHAPI)... but remember, different profiles in the wallet might have different capabilities. So, even if a wallet supports CryptoSuiteX, that doesn't mean that any of the active profiles (DIDs) in the wallet does. This is why we do not believe that having a static wallet configuration can solve this, fundamentally dynamic, problem of configuration. It has to be done dynamically, in the protocol.

I'm out of time for tonight, but hope to draw up the full flow diagram, as you requested, detailing the above, 12-ish hours from now.

@tplooker
Copy link
Contributor

The simplest case is that the Issuer generated the URL. A more complex case is that an entity that the Issuer can communicate with, in a SECURE and out of band fashion, generated the URL. Yet another more complex use cases is that a completely different entity generated the URL and placed encrypted data in the URL (e.g., CWT) that only a particular recipient can decrypt. For the purposes of simplicity, let's just focus on the first two, because we haven't found any use cases that need that last one.

Ok understood so the most basic cases are when the identifier encoded into the URL is just a random identifier that is associated to some session state on the issuer?

If by "user" you mean "the subject of the VC", then yes, it did. When the the subject of the VC is through the auth process, they're given the URL over a secure transport (e.g., same device CHAPI). Yes, insecure transports (cross-device QR Code) /could/ be an issue -- and we'll get to that later.

Yes i do, that clarifies it.

The presumption is the URL is valid until they pickup their VC OR a certain amount of time has elapsed (15 minutes). So, yes, replay attack prevention is expected to be implemented at the Issuer for "high value" credentials.

Ok.

The presumption is that they're in the same trust boundary in the simplest case. There are cases where one can "hop" trust boundaries via the "interact" field in VPR. So you can start at one trust boundary, do part of the flow, and then hop to another trust boundary (using VPR + any other protocol). When you do this you MUST ensure that there is some sort of transferrable trust from one boundary to the other -- like a JWT in a URL or VC in POST data -- both of which can be expressed via VPR "interact".

Ok details are still fuzzy to me, but I think I understand the intent.

This is an open question. I think your assertion is that consent MUST be acquired before they initiate the VC exchange. In that case, there are multiple ways it can happen, but the most straightforward is: The Issuer can ask the subject "Do you want to store this Student ID in your digital wallet?" -- and then a mediator is invoked or QR Code is displayed.

Doesn't have to be in all cases but I think a protocol that doesn't allow this as a possibility will run into issues with certain credential types.

Yes, this would be the first exchange, where the Issuer would state the features it needs from the wallet (query 1 in the VPR), and the DID Auth request (query 2 in the VPR), and the wallet would receive those and, if it can't fulfill either query, tell the user why. While failing isn't the ideal outcome, if the wallet can't fulfill the request, it can't fulfill the request.

To me this is too late, by then the end user has likely been through an auth journey, probably clicked yes to a bunch of T's & C's, maybe filled in some data and then to find out after all that their wallet cannot support the credential is liable to just annoy users immensely. I think the negotiation of capabilities has to happen much earlier.

This is why we do not believe that having a static wallet configuration can solve this, fundamentally dynamic, problem of configuration. It has to be done dynamically, in the protocol.

I agree the information is liable to change overtime so the model needs to account for that, but assuming that it is so dynamic that the most practical method is to send all information on every issuance flow is extreme.

@dlongley
Copy link
Contributor

@tplooker,

To me this is too late, by then the end user has likely been through an auth journey, probably clicked yes to a bunch of T's & C's, maybe filled in some data and then to find out after all that their wallet cannot support the credential is liable to just annoy users immensely. I think the negotiation of capabilities has to happen much earlier.

There are a few things to consider here.

  1. If the user doesn't want the VC more than they want to have to use another wallet, they will abandon the exchange. In this case, we have a situation where the issuer will need to upgrade their services to support well-liked wallets to increase user acceptance. If the user is on the fence -- then they will be more likely to store the VC in a new, issuer-recommended wallet at the end of the exchange vs. if they have made no commitments during a flow. Which of these is actually better for the user depends on the actual value of the VC (vs. its perceived initial value) and what the changes to the wallets and issuers would be if the user rejected it outright. So there are interesting market dynamics questions here. It's important to remember that the best outcomes for users on the whole are not necessarily the result of the most convenient UX in failure modes.

  2. Wallet selection can still be done first with these technologies, where the URL has an offer that isn't bound to any particular user. This results in an exchange request that, e.g., asks for zcaps to write the credential to the wallet and includes over a user-mediated URL for the wallet to direct the user to. The user then follows the issuer flow (user auth/whatever) on the issuer website. At the end of that flow, the issuer uses the zcaps to send the resulting credential to the user's wallet.

  3. If the user does not have a wallet that can work with the issuer but the user really wants the credential anyway, the user can select a new wallet from the recommended list provided by the issuer. The user can be informed that their existing wallet cannot interoperate with the issuer at this time. This situation should only occur when there is an interop failure, where the user's wallet doesn't support some choices made by an issuer of a VC that they really care about. This failing should be surfaced in some way that results in the user using their influence to create a better wallet marketplace (with increased interop) through their choices. As noted above, it's not clear which flow (wallet selection at the beginning or at the end) would result in maximizing user influence.

@tplooker
Copy link
Contributor

It's important to remember that the best outcomes for users on the whole are not necessarily the result of the most convenient UX in failure modes

I follow this point, but im struggling to see the conclusion you are drawing here, when is it ever advantageous to delay failure in a system intentionally, knowing full well that the engaging party (the End-User) is having to invest in the process. To me I dont see how this doesn't always end in End-User frustration or them making a decision from a position of compromise (e.g fine i'll store it in the Issuers recommended wallet because I've been through all of this work to get this far).

Wallet selection can still be done first with these technologies, where the URL has an offer that isn't bound to any particular user. This results in an exchange request that, e.g., asks for zcaps to write the credential to the wallet and includes over a user-mediated URL for the wallet to direct the user to. The user then follows the issuer flow (user auth/whatever) on the issuer website. At the end of that flow, the issuer uses the zcaps to send the resulting credential to the user's wallet.

Understand the theory here, but again without seeing how it shakes out end 2 end its hard to fully evaluate

This failing should be surfaced in some way that results in the user using their influence to create a better wallet marketplace (with increased interop) through their choices. As noted above, it's not clear which flow (wallet selection at the beginning or at the end) would result in maximizing user influence.

Again I think I understand your perspective, but unsure how you are reaching your conclusion.

@msporny
Copy link
Contributor Author

msporny commented Mar 31, 2022

I'm providing ONE example of an end-to-end flow that is end-to-end secure -- there are other end-to-end flows that we can get into later. This does not focus on client feature detection, that's issue #280.This is a same-device flow using a web-based wallet:

sequenceDiagram
    participant H as Holder
    participant WS as Wallet Service
    participant WA as Wallet App (Website)
    participant CH as CHAPI
    participant IW as Issuer App (Website)
    participant IS as Issuer Service
    autonumber
    H->>IW: Authenticate to pick up Student ID (authn via MFA - (OIDC | email + password) + pin)
    IW->>IS: Generate VPR (bind to MFA outcome)
    IS->>IW: VPR (containing .../exchanges/new-student-id/z123456)
    IW->>CH: Invoke CHAPI with VPR
    CH->>WA: Invoke registered Credential Handler 
    WA->>WS: Instruct Wallet Service to perform VPR flow
    note right of IW: Calls below this note are proxied through the Issuer Website to the Issuer Service
    WS->>IS: Request Student ID via POST .../exchanges/new-student-id/z123456 (VC-API)
    IS->>WS: DID Auth Request (VC-API + VPR)
    WS->>IS: DID Auth Response (VC-API + VP)
    IS->>WS: Present new Student ID (VC-API + VP)
Loading

Here is the same flow that is just as secure using Native CHAPI (Web Share):

sequenceDiagram
    participant H as Holder
    participant WS as Wallet Service (in Native App)
    participant WA as Wallet App (Native)
    participant CH as CHAPI
    participant IW as Issuer App (Website)
    participant IS as Issuer Service
    autonumber
    H->>IW: Authenticate to pick up Student ID (authn via MFA - (OIDC | email + password) + pin)
    IW->>IS: Generate VPR (bind to MFA outcome)
    IS->>IW: VPR (containing .../exchanges/new-student-id/z123456)
    IW->>CH: Invoke CHAPI with VPR
    CH->>WA: Invoke registered Credential Handler 
    WA->>WS: Instruct Wallet Service to perform VPR flow
    note right of IW: Calls below this note are proxied through the Issuer Website to the Issuer Service
    WS->>IS: Request Student ID via POST .../exchanges/new-student-id/z123456 (VC-API)
    IS->>WS: DID Auth Request (VC-API + VPR)
    WS->>IS: DID Auth Response (VC-API + VP)
    IS->>WS: Present new Student ID (VC-API + VP)
Loading

Do you see anything here that is not end-to-end secure, @tplooker?

@dlongley
Copy link
Contributor

@tplooker,

Again I think I understand your perspective, but unsure how you are reaching your conclusion.

What I'm trying to highlight as important is not the difference between non-optimal failure mode UX and a perfect solution (no drawbacks) that addresses it. Obviously the latter is preferable. Rather, the trouble is with the difference between non-optimal failure mode UX and a solution to it that harms user choice more in ways that may be indirect and, therefore, can be overlooked when viewing the failure mode UX in a vacuum.

This is, to me, a significant concern with a solution that requires user wallet or wallet vendor registration with the RP. If it's more indirectly harmful to users, I am suggesting that accepting non-optimal failure mode UX is the better choice (absent any other options).

In other words, we should optimize for user choice across the ecosystem generally, not just in failure mode UX.

@mavarley
Copy link
Contributor

mavarley commented Apr 1, 2022

I have always felt authorization was out of scope for this API, given that it is meant to be completely generic.

Consider the following scenarios:

  1. I am an issuer that provides a verifiable credential containing a timestamp from my server when I was called. That's it. "what time do you have?"
  2. I am an issuer who will issue a credential over VC API, but I will authorize them with an adopted pattern I already support for other customer centric APIs - through OAuth (or iteration thereof)
  3. I am an issuer who will only permit certain holder software to communicate with me, that allows for an integrated "wallet" experience where the holder can authenticate themselves to me through the VPR by either providing an existing credential I trust and can match (and I know the holder has one because that's the rules of the wallet/ecosystem), or perhaps I will send them an out-of-band one time code to an email/phone/etc... that I have on record that they can enter, in the holder software, in session, which acts as the binding.
  4. I am an issuer as part of an automated process, and client system authorization is required for my API as a qualification check, and so I can charge the client for using my service. There is no "personal account" link in this use case.

(1) does not require "authorization". It's a digital Big Ben.
(2) Requires an authorization token bound to a holder activity at the issuer site, and bound to that account holder session.
(3) Requires holder software authorization (but only cause I am presuming this is how the issuer will help guarantee success of the process) - like an Api Key or OAuth CC grant - but the inline VPR messages will allow a VPR message to provide a trust factor/account verification link that the issuer can leverage and then the exchange is at an elevated trust level.
(4) Is my acknowledging that there are use cases that are about business processes and less about direct 'personal' interaction (I butchered a supply chain use case... sorry)

Since the API is generic, and we don't know what we are protecting, authorization should be out of scope.

Removing the requirement for a specific authorization protocol opens up the scenarios in how this API can be used - BUT it also may lead to interop challenges (how does a client know how and when to call an API endpoint?) and also may be a "foot gun" if we cannot provide proper guidance/best practices on how to use this new tech in a secure manner.

By comparison, the FAPI API was able to carefully define and specify the authorization requirements because it also defined the contents of the API (various levels of financial data, from ABM locator to account transaction history).

Without a concrete API context here, we will continue to spin on authorization requirements, I feel.

@tplooker
Copy link
Contributor

tplooker commented Apr 1, 2022

I'm providing ONE example of an end-to-end flow (without focusing on wallet configuration) that is end-to-end secure -- there are other end-to-end flows that we can get into later. This is a same-device flow using a web-based wallet:

Thanks this helps

Do you see anything here that is not end-to-end secure, @tplooker?

I think being absolute in feedback for this is quite difficult because it depends on your assumptions. Do I think there are certain use-cases that work with this model? Yes. However I do think there are some significant limitations which would make this approach difficult to address other usecases.

  1. The issuer of the capability (URL) has no idea about anything to do with the software client it is intended for, in fact its completely blind to whether that software is on the same device or its going to be piped through an out of band channel to somewhere entirely different. Meaning MITM/hijack style attacks are essentially impossible to mitigate at all. (Note - other protocol options may not be perfect in this regard, but I believe them to be significantly more secure against this style of attack)
  2. The possibility of phishing attacks - Say the End User selects the wrong wallet on the CHAPI screen, or for instance they installed a bad app on their phone, the consequence is that app ends up with the credential without any further action from the User.
  3. There is no way to enable issuer based consent where the issuer asks the use "do you want to issue a credential to wallet x?", now there are likely plenty of cases where this isn't required but eliminating it as a possible option is very limiting.
  4. The negotiation on the wallets compatibility with the issuer happens too late, in these flows the user has been auth'd, accepted T's & C's and clicked issue credential only to potentially find the wallet they want to use is incompatible.

I agree with much of Mikes comments above, however I think the problem I'm seeing is that this API appears to be re-inventing certain aspects of delegated authorization protocols, namely the expression of the authorization capability (URL) and how it is transmitted to the authorized party (CHAPI), rather than looking to use a standard protocol to do this instead (OAuth2). In doing this, the work required for this API's definition gets exponentially more complex.

The benefit of using standard authorization protocols is that you get a consistent approach that has a wealth of possible mechanisms you can layer in to satisfy different security models. For instance if bearer based access tokens aren't secure enough, layer in DPOP. Want to mitigate CSRF, add in PKCE. I dont see the same depth in the possible choices here because of how the flow is modelled and that is likely where the limitations will arise.

@tplooker
Copy link
Contributor

tplooker commented Apr 1, 2022

What I'm trying to highlight as important is not the difference between non-optimal failure mode UX and a perfect solution (no drawbacks) that addresses it. Obviously the latter is preferable. Rather, the trouble is with the difference between non-optimal failure mode UX and a solution to it that harms user choice more in ways that may be indirect and, therefore, can be overlooked when viewing the failure mode UX in a vacuum.

Right, understand and agree with the position, I just think we may disagree on whether or not there are alternative protocol designs that resolve this UX issue but still preserve user choice.

This is, to me, a significant concern with a solution that requires user wallet or wallet vendor registration with the RP. If it's more indirectly harmful to users, I am suggesting that accepting non-optimal failure mode UX is the better choice (absent any other options).

Again, I think the disconnect here is that I see no difference in a protocol that does "wallet registration" and one where the "wallet is negotiating its capabilities with the issuer via a DID Auth response", they are one in the same in their purpose, mechanically they may do it slightly differently but any risk that manifests around user choice is the same.

@msporny
Copy link
Contributor Author

msporny commented Apr 1, 2022

@mavarley you didn't answer the question :) -- Do you see anything here, in that ONE specific flow, that is not end-to-end secure? I get all the other points you're raising, and we'll get to them, but we need to start somewhere. Let me try going at it from the other direction:

The same-device end-to-end flow described above is secure for both web-based and native wallets. It does not need OIDC, DPOP, or PKCE to be secure. Full stop.

I believe @tplooker has confirmed that it is end-to-end secure in his response, and would like to discuss other use cases. We can talk about cross-device flows and security models for those after we get confirmation from everyone that the end-to-end flow described above is secure. :)

@dlongley
Copy link
Contributor

dlongley commented Apr 1, 2022

@tplooker,

I'd like to see if we can work through some of the concerns you raised to whittle down the list:

The issuer of the capability (URL) has no idea about anything to do with the software client it is intended for, in fact its completely blind to whether that software is on the same device or its going to be piped through an out of band channel to somewhere entirely different. Meaning MITM/hijack style attacks are essentially impossible to mitigate at all. (Note - other protocol options may not be perfect in this regard, but I believe them to be significantly more secure against this style of attack)

If CHAPI is trusted to prevent MiTM attacks (in the same way TLS is with OIDC), then this attack should not be possible. That's the limit of the security model and it functions the same way with OIDC. Can we agree to this or is there some other concern?

There is no way to enable issuer based consent where the issuer asks the use "do you want to issue a credential to wallet x?", now there are likely plenty of cases where this isn't required but eliminating it as a possible option is very limiting.

I think the issuer asking "Do you want to view this website using browser X?" before showing their web page would be very limiting in a negative way. I consider the question above to be of the same sort with similarly negative consequences. I consider this to be an information minimization use case -- where the issuer doesn't need to know which wallet I prefer to use and that knowing that information could be used against me, harming my free choices.

I think the roles are being confused here. The issuer is not my agent. The browser is and my wallet of choice is. The browser (or a polyfill for it like CHAPI) should help me make sure I choose the right wallet to use. And my wallet of choice, as my agent, should help me make decisions related to credentials (like whether or not I store them from certain issuers and whether or not I share them with certain verifiers). This is the right model, IMO.

@mavarley
Copy link
Contributor

mavarley commented Apr 1, 2022

@mavarley you didn't answer the question :) -- Do you see anything here, in that ONE specific flow, that is not end-to-end secure? I get all the other points you're raising, and we'll get to them, but we need to start somewhere. Let me try going at it from the other direction...

Actually, I answered the original question - the title of this issue and the original one in the first message:

This approach has been challenged to be insecure, so this issue is to discuss the attack models and security characteristics of this approach.

Without understanding what is being protected, or the risks, no evaluation can be made as to the "Security".

But I did dodge the latter, more specific question on the proposed flow:

The #279 (comment) is secure for both web-based and native wallets. It does not need OIDC, DPOP, or PKCE to be secure. Full stop.

So here goes. If we apply the following assumptions:

  1. CHAPI is sufficiently secure (against session hijacking/mitm/etc... which I think it is but have not studied closely) and
  2. The one-time transaction ID is sufficiently 'random' to protect against guessing or otherwise deriving (which I think is what we have spec'd)
  3. TLS is sufficiently secure (from TLS inspection/termination endpoint/cert hijacking etc... which I think it is, and the gaps are well documented regardless)
  4. The URL/ exhange-id endpoint is protected from replay (ie after the initial DIDAuth, the endpoint is bound to that DID only and for the rest of the endpoint's lifetime) The exchange-id is acting as an auth token, effectively, and there are Good Reasons to not have auth tokens in URLs (they end up in logs, browser history, etc...) so there needs to be a trust step-up and expiration time...

I believe the above is secure enough to transfer a credential relating to an account holder to a wallet of the account holder's choosing - the exchange ID is acting as an auth token, effectively, until DIDAuth can be completed.

The risk on the binding of the credential to the same subject in the web session is, as @tplooker pointed out; the 'wrong wallet' may get selected on a shared machine, the wallet or DID method may not match the required criteria, there is no confirmation on the web channel as to which holder software the credential was actually delivered to, etc... but depending on the credential's usefulness/value and associated protections, maybe these are not concerns.

And as I noted above, if there is an additional binding that can be performed (like the first message has a PKCE like value that was bound to the original session - or there is an SMS one-time-code that can be entered from the holder software...) then these may bolster the security posture, but these types of nuances depend on the resource being protected.

No one can answer "how much is secure enough" without the full picture - but again, this spec/API is being designed generically - and should leave room for a wide range of use cases and security contexts.

I will note I would have serious reservations about requiring CHAPI being tightly coupled to this API, for the exact same reason.

@tplooker
Copy link
Contributor

tplooker commented Apr 1, 2022

To be clearer, no I dont think this model is sufficiently end to end secure for several important usecases. I also dont see how you can layer on additional mechanisms to secure it further, because of how the flow is structured. I think the assumption that you generate the capability before knowing anything about the party you are giving it to, is wrong.

The same-device end-to-end flow described above is secure for both web-based and native wallets. It does not need OIDC, DPOP, or PKCE to be secure. Full stop.

As said above I dont believe this is the case for several important usecases.

If CHAPI is trusted to prevent MiTM attacks (in the same way TLS is with OIDC), then this attack should not be possible. That's the limit of the security model and it functions the same way with OIDC. Can we agree to this or is there some other concern?

Its not just CHAPI that needs to be secure against this here to a comparable level with TLS, its everything from the server that generated this URL through to where it ends up. Its also not the only layer of security OIDC or OAuth2 has when interacting with the token endpoint either, you could use client authentication with public private keys or PKCE to further mitigate several attack vectors. You cant do this with the above flow, because there is no interaction with the wallet prior to just handing them the capability (URL). I also dont think you can equate the security provided by a transport layer to a javascript polyfil providing mediation that requires end user interaction, they have completely different characteristics.

I think the issuer asking "Do you want to view this website using browser X?" before showing their web page would be very limiting in a negative way. I consider the question above to be of the same sort with similarly negative consequences. I consider this to be an information minimization use case -- where the issuer doesn't need to know which wallet I prefer to use and that knowing that information could be used against me, harming my free choices.

Sure but thats because your mental model is that a wallet is akin to a web browser, when mine is not.

I think the roles are being confused here. The issuer is not my agent. The browser is and my wallet of choice is. The browser (or a polyfill for it like CHAPI) should help me make sure I choose the right wallet to use. And my wallet of choice, as my agent, should help me make decisions related to credentials (like whether or not I store them from certain issuers and whether or not I share them with certain verifiers). This is the right model, IMO.

I get the issuer is not my agent, but do I not interact with the issuer via an agent, the Browser? And then why is it not a good idea to support a flow that allows via this agent for the issuer to convey to me the implications of issuing a credential to my wallet and obtain my consent? Piping this through the wallet is just vastly more complex and has significant implications around the trust model.

@tplooker
Copy link
Contributor

tplooker commented Apr 7, 2022

Does this mean that we're in agreement that a CSRF attack is not an issue here? I want to make sure we're making progress on a common understanding. I think it's best if clearly talk about specific threats -- and say whether they apply and what the mitigations could be.

Sure, I get the existing definition of CSRF perhaps does not fully apply here, but I dont think this means the attack vector doesn't exist even if it does not fit neatly into an existing definition.

At present, a credential handler receives the origin of the credential requestor (e.g., the "requestor that sent the VPR") via the credentialRequestOrigin property on both the CredentialStoreEvent and the CredentialRequestEvent. This information is trusted to be accurate based on the security model (which requires that CHAPI be secure).

Sure but none of this is afforded when talking to native apps from CHAPI right (via web share)? So this only works for web wallets?

The group of people that were like "let's just use what's there" are the ones that made it so PKCE had to be invented to fill security holes

As a counter though, the fact that a protocol which has been widely used for over a decade was able to easily extend to mitigate this threat vector IMO is a testament to the protocol. We should be careful not to wield the sword of hindsight against protocols like OAuth2, for example saying it didn't predict the need for this particular mechanism as a form of critism I think is miss placed, the reality is the protocol easily adapted with the addition of a simple extension.

Also it is this very flexibility within OAuth2 OIDC that I dont see with the CHAPI + VC API that has me concerned.

I worry that the same arguments are being made here: There's a tech that kinda looks like we could use it and it has wide deployment, so let's do that so we don't have to reinvent anything.

Yes to be totally clear I am making this argument although I dont think it "kinda looks like we could use it" im convinced, as are many others that we can, it doesn't mean we dont have to reinvent anything, but invent less, yes definitely.

If we want to go there, it seems to me that the push for the various "bindings" you and @mavarley have mentioned are not necessarily about threats in the CHAPI + VC-API model, but may be really about UX concerns. We should clearly separate these if so. A binding is only necessary for security when there's something you need to link together because there's no end to end security in a flow (there are gaps). As I've mentioned, with CHAPI, there's no confused deputy situation where the OS / whatever may hand something off to an attacker / MiTM like there is with OAuth/OIDC. Rather, the user deliberately chooses their wallet. Note: It's also the case that if the user accidentally chooses the wrong wallet -- this is a problem no matter what protocol is in use, and no amount of "preregistering" (or whatever else) will help if Alice picks Bob's wallet to link to her information.

Yes to be clear here it is between the wallets request for the credential (onbehalf of the end user) and the end-users authentication (and potentially consent) with the issuer to issue the credential.

So, it seems you are thinking about cases where a user may have indicated they want to use wallet X ... and then there's a need to ensure that if the user chooses a wallet again later that it's the same wallet, otherwise they will have a suboptimal experience (e.g., incompatibilities with issuer capabilities). In the flow we've been discussing, the user only makes a wallet selection once. Therefore, if there's only ever one time a user selects a wallet, you don't need to worry about binding that selection to "the same selection made earlier", because there is no such thing in the flow.

Yes this is because your mental model starts with the End User visiting a website, authenticating, invoking CHAPI and then issuing the credential, what I'm saying is I dont think that is right ordering of events in many usecases. In many cases it should be visiting a website, invoking CHAPI, authenticating the user (or just checking they already are on the device you are accessing the wallet from) then issuing a credential.

However, the OAuth/OIDC stuff is fundamentally based on a different trust model -- where you "trust the IdP" and
you add "clients" that you must authenticate via client secrets to access your stuff. The VC model was specifically
designed to be different from this. It was designed to distribute trust via cryptography, not infrastructure.
A party consuming a VC only needs to trust the math and the issuer -- and, often, that the presenter is in some
way appropriately connected to the VC (e.g., as its subject) via math and/or biometrics. There's no "trust the IdP /
authenticate the client" that delivered the VC. It's pretty much a major point of the new model to avoid that.
So when we say we're just going to reuse tech that used a different model -- I'm apprehensive. Again, that's
how things got broken to begin with -- such that we needed PKCE to patch OAuth. It didn't happen the other way around.

Personally I think the assurances that fancy maths (cryptography) can supply alone in the application of digital identity technologies is overplayed, people appear to approximate the usage of cryptography in cryptocurrencies and conclude that it alone can serve a similar basis for identity technologies. The latter in many ways is far more complex and involves way more social constructs that makes it incredibly difficult to just say "trust the math". We need to be clearer on what the purpose of the cryptographic binding established when a credential is issued actually even represents, to me in many circumstances its an authentication factor at best but alone proves next to nothing about whether the End-User (true credential subject) is involved in a credentials presentation.

If a person has two sets of cryptographic keys one tied to their holdings in bitcoin and another tied to their drivers license,
the situations that might cause that individual to share those keys are very different. An individual is probably less likely to share full access to their bitcoin balance (1st key), but for the right individual they may choose to share their drivers license so that person can say buy some beer with their drivers license, needless to say the outcome and consequences are very different.

For example, consider that an issuer is able to issue one or more VCs to a user based on the user's attributes, other VCs they present, or something that they do during a custom flow. Which VCs they are issued may change as well, based on their choices in the flow. Now, walking through this using the OIDC flow diagram you provided:

There is a lot of really good feedback in here that I want to be able to respond to however Im not sure a GH issue is the best way to do it, I could try capture it in a google doc? Otherwise happy to just respond inline to the GH issue.

@tplooker
Copy link
Contributor

tplooker commented Apr 7, 2022

Same as OIDC? That's what the redirect does?

This is a really important point that I think is being overlooked, what happens when you execute a redirect into an OIDC flow is completely up to the issuer and you have the full power of the web to build whatever user journey you want including authenticating the user, so I also dont really follow the argument that OIDC is overly limiting in this respect nor do I see a blurring of responsibilities. To be clear OIDC discovery is optional in the flow I shared above, the wallet doesn't have to do this nor do the credentials offered by a provider need to even be published in the metadata, the important thing is that the user gets authenticated and the wallet gets authorized to obtain the credentials its after.

@tplooker
Copy link
Contributor

tplooker commented Apr 7, 2022

To offer more context, if you want to accomplish a flow where you want to trust the channel in which you are passing something to the wallet and skip user auth on the device you are provisioning the credential on, then we are working on this variation in OIDC CP /OIDC4VCI known as pre authorized code flow, however there are a few features I think that make it quite different to the one shared above.

  1. You cannot bind the provisioning token / code / capability to the client / wallet if you want / need to
  2. It doesn't appear you could do a confirmation style flow on the device where the provisioning token was generated to ensure it ended up being past to the right device (e.g when you are using a QR code instead of a CHAPI)
  3. The outcome of your flow yields the VC rather than an authorization token that can be used to get the VC or refresh or renew it (side note, but I think presenting a VC to obtain another VC is an anti-pattern, hence why I think authorization tokens should be used).

@mavarley
Copy link
Contributor

mavarley commented Apr 7, 2022

I was thinking about a flow where a CHAPI initiated flow could help ensure a "tighter subject binding" through a flow, and support an early fail/bailout in case the person does not have a compatible wallet...

image
(source: https://bit.ly/3xc1nmC)

In red there are internal calls between the Issuer and VC API service that are out of scope (I think).
If the Holder calls the exchange endpoint "too early", the Issuer (Daily Planet) can deny providing the credential data.

Not sure how to structure the VPR messaging to support the callback/webhook (and maybe another CHAPI flow is required) but the point is (that I am trying to get at) is by breaking up the CHAPI flow above, there is a way to achieve a 'workflow' like experience that also helps bump up the level of assurance.

I am not suggesting all CHAPI flows need to change to the above; merely exploring possibilities.

PS: I will note that in step 2 in the diagram in #279 (comment) this call is likely authenticated/authorized and results in the exchange-id as a bearer token, which is also acting as the authorization to execute the exchange API -- seems like we danced around a lot, but the VC API still requires authorization ?

@dlongley
Copy link
Contributor

dlongley commented Apr 7, 2022

@mavarley,

I don't agree the CHAPI + VC-API is any less complex than OIDC. There are OIDC flows which can be quite trivial to implement, and more complex implementations that increase the level of assurance on an interaction - same with VPR (CHAPI or VC-API) - the current discussion on VPR I think is exploring these additional complexities. (ie, with the current VPR extension points, I can make an exchange as complicated as I like :) ).

That's not the complexity I was referring to. What flows you implement inside of a particular protocol and how complex those are / can be, is a question for a layer above the protocol itself. Ideally, a protocol keeps responsibilities separated by role, offers good composition via simple primitives, and gives people as much freedom as possible for their flows at that layer.

What I was talking about above was what every user of the protocol itself needs to do regardless of their particular flow, e.g., how many components must they implement (or use libraries for), which extra options do they need to consider (PKCE? DPOP?), etc. to ensure the security model works and so forth. To this point, one complexity I mentioned that isn't needed in the CHAPI + VC-API security model is software client registration and authentication.

@tplooker
Copy link
Contributor

tplooker commented Apr 7, 2022

To this point, one complexity I mentioned that isn't needed in the CHAPI + VC-API security model is software client registration and authentication.

If we take the purpose of registration in OIDC to be the ability for the wallet to express what it supports so that it obtains a VC it can actually use, then I dont believe this isn't needed in the CHAPI + VC-API, it may mechanically be achieved in some other manner but its a stretch to say that the way it chooses to achieve this is an overall reduction in implementation complexity.

Similarly Im not sure what is being defined here as client authentication so its difficult to know what you are talking about and hence whether it represents implementation complexity that CHAPI + VC API some how escapes.

@dlongley
Copy link
Contributor

dlongley commented Apr 7, 2022

If we take the purpose of registration in OIDC to be the ability for the wallet to express what it supports so that it obtains a VC it can actually use...

I've been trying to make it really clear that it's important to separate that out. It's not needed for the security model in CHAPI + VC-API but it is in OIDC.

If we want to talk about UX, etc. -- that's fine, but it's a separate subject. How we solve particular problems there may have a number of different possible solutions, each with advantages and disadvantages. If we come up with a more elegant solution to a UX issue than "client registration", OIDC still needs registration for its security model; that's important to note.

It is true that if we find that some element that is needed for some protocol's security model has good trade offs when reused to solve a UX problem as well -- that's great, but we need to be more rigorous in saying what things are for, why they are necessary, what the trade offs are, etc.

...then I dont believe this isn't needed in the CHAPI + VC-API, it may mechanically be achieved in some other manner but its a stretch to say that the way it chooses to achieve this is an overall reduction in implementation complexity.

It absolutely is a reduction in complexity (and attack surface). The effects of security bugs are not the same as compatibility bugs, just as another simple example.

@dlongley
Copy link
Contributor

dlongley commented Apr 7, 2022

@mavarley,

PS: I will note that in step 2 in the diagram in #279 (comment) this call is likely authenticated/authorized and results in the exchange-id as a bearer token, which is also acting as the authorization to execute the exchange API -- seems like we danced around a lot, but the VC API still requires authorization ?

It doesn't require "client authorization" (read: wallet authorization). There's an expectation that any backend service that the issuer uses would either have authorization of some sort or be behind a firewall, etc. -- but none of this is relevant regarding whether a user's wallet of choice now needs to be authenticated and/or strongly identified to the issuer. That's a total different requirement.

@dlongley
Copy link
Contributor

dlongley commented Apr 7, 2022

@mavarley,

I am not suggesting all CHAPI flows need to change to the above; merely exploring possibilities.

Yup, +1 to your example of a "tighter subject binding" that shows one way that the primitives provided via CHAPI + VC-API can be composed to achieve a particular use case.

@dlongley
Copy link
Contributor

dlongley commented Apr 7, 2022

@mavarley,

This is where I am weary - "there is no way that could happen" is a great opportunity for "bad actors" to find a way to break those assumptions. So then these attacks become a question of scale, not possibility. Break CHAPI and steal everyone's credentials? Bad and highly scalable. Break CHAPI, and subvert an out-of-band session binding (like PKCE or SMS code or ...) Bad, but less scalable. Break CHAPI, subvert an out-of-band security token, and impersonate a trusted holder software implementation ... well, diminishing returns maybe but you see how this goes.

This is a different kind of attack that assumes the security model is broken. The CHAPI + VC-API security model assumes CHAPI is secure. It's similar to assuming that wallet, RP, and issuer software are secure in any other case (like OIDC). If you don't have client authentication in the OIDC case, even if those other things are secure, there's an attack. If you don't have client authentication in the CHAPI + VC-API case, there's no attack. That's what my statement meant.

If we want to talk about "how to improve the security of the CHAPI mediator itself", I think that's an interesting topic of discussion, but it's a different discussion. Again, I think we need to be more robust with the layers at which we're making comparisons here.

That being said -- on the topic of "improving the security of the CHAPI mediator itself" -- the above attack you mentioned could be mitigated in an interesting way:

  1. RP publishes a did:web DID with a keyAgreementKey.
  2. RP calls CHAPI with a request for VCs.
  3. User picks a wallet.
  4. Wallet checks RP for a did:web DID; if found, encrypts the VP response via its keyAgreementKey.
  5. CHAPI forwards the encrypted response (it cannot be read) to the RP.
  6. RP decrypts the response.

Note that this still can all be done without any "client authentication / identification / registration".

@dlongley
Copy link
Contributor

dlongley commented Apr 7, 2022

@mavarley,

Something I think CHAPI + VC-API does moderately well is keeping role responsibility clean. For example, with CHAPI + VC-API, a wallet is a user's trusted agent and it handles consent and helping the user make decisions, and it's up to an issuer to provide an interface for taking a user through a process for obtaining a VC (which may include any number of interesting issuer / VC specific steps).

Same as OIDC? That's what the redirect does?

No, the OIDC flows we've seen require the issuance process to start via an unbounded public VC selection list published by the issuer that is downloaded by the wallet and rendered in a "wallet marketplace". The issuer must use this primitive to issue their VCs. I detailed a number of problems with this approach in my post. The biggest one is that the issuer loses their ability to manage the user relationship, experience, and eligibility checks at the start of their issuance process. We could end up with issuers giving their users instructions like this:

"Ok, once you choose your wallet, make sure that you scroll down to pick 'Greenwood Commons VC' in your wallet marketplace, not 'Common Greenwood VC', otherwise you'll have to do this again. Also, make sure that you have VC X, Y, and Z if you're going to pick 'Greenwood Commons VC', otherwise you'll have to go back and pick 'Albatross Greenwood Commons VC'."

This is why I suggested that having the user choose "flows" at the wallet marketplace may be better. But even then -- maybe issuers will just show one choice -- because they want full control over the process -- and it becomes a wasted part of the UX. Hopefully this makes better sense now.

@dlongley
Copy link
Contributor

dlongley commented Apr 7, 2022

@mavarley,

Maybe that was directed at @tplooker who has expressed these concerns, but I believe the comparison is:

  1. In a CHAPI based flow, the Issuer and subject interact / authenticate / qualify, and then the wallet gets involved. "All set, pick your wallet". Then the individual is left searching for a qualified wallet (maybe they didn't have one and need to get one before their web session expires? Maybe they had one but it doesn't use the same did/crypto profile and need to find a new one? But they've gotten this far!! "Figure it our fast or your session is cooked and you start again!" is pretty stressful)
  2. In an OIDC flow, the Issuer and holder-software can establish compatibility before the subject does any hoop jumping. In other words, step 1 is the client/wallet contacts the issuer and checks its qualifications. step 2 is authenticate/qualify/etc... and the conclusion of the process is a credential is fetched by the holder software.

Like I said in my other comments, there are not just wallet eligibility concerns, but also user eligibility concerns. I tend to think that user eligibility should be prioritized over wallet eligibility. Reasons:

  1. Another wallet can always be offered (unfortunate, but a possible solution) if a user gets to a point in a flow where they can't use their existing wallet. A user can't "become someone else" to solve the user eligibility problem after they've picked their wallet and started down a flow that they can't complete.
  2. The user can understand that their wallet is incompatible and it's not their problem -- and they may be able to use this information to persuade their preferred wallet provider to become more compatible (maybe this is achievable even if the wallet is chosen first).
  3. There are N-many ways a wallet could be incompatible. Most wallets will try to be compatible with whatever is popular -- and there are only so many popular DID methods and cryptographic suites. In a more mature ecosystem, this problem should be very rare. The number of ways that a user could be ineligible for a particular flow / VC is, by comparison to N, essentially unbounded -- with each issuer having any number of unique constraints -- and maturity of the ecosystem doesn't necessarily reduce this at all.

@tplooker
Copy link
Contributor

tplooker commented Apr 8, 2022

No, the OIDC flows we've seen require the issuance process to start via an unbounded public VC selection list published by the issuer that is downloaded by the wallet and rendered in a "wallet marketplace". The issuer must use this primitive to issue their VCs. I detailed a number of problems with this approach in my post. The biggest one is that the issuer loses their ability to manage the user relationship, experience, and eligibility checks at the start of their issuance process. We could end up with issuers giving their users instructions like this:

To be clear OIDC Discovery is never required its just a method to support this style of issuance when desired the credential offer sent to the wallet could equally be (note this is just an example)

openid://discovery?issuer=https://example.com&credential_type=university_degree

The wallet can then if it desires just skip ahead straight into an OIDC request with the openid_credential:university_degree present in the list of scopes, the publishing of the metadata just supports pre-discovery of what will be in the credential if it is desired.

@dlongley
Copy link
Contributor

dlongley commented Apr 8, 2022

@mavarley,

I might argue that your initial assumption is incorrect. I would not build a workflow the subject cannot complete without an OIDC exchange later. Instead, the workflow starts with OIDC. Or, the workflow completes successfully (with maybe a printable VC?) and the subject is presented with an option to load it into a digital wallet (which may require another login, but the workflow is clear). So, counter example:

  1. The user arrives at an Issuer site that issues Verifiable Credentials. The page describes the process and the wallet requirements (if any).
  2. The user takes an action (click a button, scan a qr) which tells their wallet to contact the issuer to begin the flow.

But which flow? In the diagrams we've been given, there's no way to whittle the choice down, but, as mentioned, an unbounded list of VCs is shown in a "wallet marketplace UI". I do tend to agree that issuers will end up abusing this primitive such that there's only one choice -- or very few choices -- because they will want to be in charge of this selection and where the flow heads on their own site.

  1. OIDC discovery, and possibly dynamic registration occur. At this stage, incompatible wallets indicate to the user, "sorry, cannot proceed" -- the user is disappointed but has invested very little.

Yes, the user will have invested very little. But if they make a choice and move forward -- and that choice isn't "the right one", they will be very annoyed.

Again, this implies that issuers, in order to avoid this, will abuse the "public VC selection list" primitive not to show actual possible VCs the user could get, but instead would make each item in the "VC list" be a representation of "all flows that require wallet features X" instead. This may be awkward for users -- have we considered what it would be like? It seems the flow in the diagram may be optimized for demo sites or small / one-off issuers.

What I'm saying is that the primitives feel off here and it's a result of taking away responsibilities from the issuer. Is that making sense?

  1. If registration is successful, the wallet redirects the subject to the issuer's authentication and qualification process web workflow (same as what exists in pre-CHAPI flow). This includes specific consent related to an active workflow, not a future possible workflow.

To further analyze whether the primitives and their semantics are right here ... what use was the "public VC selection list" in this flow? What does having it accomplish?

  1. At the completion of the application, the user is directed back to the wallet (where further action/consent can be collected and managed). The wallet pulls the credential from the issuer using a security token bound to an authenticated workflow.

The above is not perfect, and may have gaps that are currently being worked on wrt. required presentations etc; I will note that the above can also enable a direct wallet-to-issuer VPR communication exchange, but interact is not necessarily required, as presumably all the interaction has already occurred.

How does the wallet know when the exchange has ended? Does it assume it's over based on receipt of a VC? Is that what is meant by "presumably all the interaction has already occurred"? What if there are more VCs for pickup and more to do in the exchange -- how does the wallet know how to direct the user next? There seems to be a missing primitive that clearly marks the end of the exchange; instead, it seems to be presumed. I'm worried about composability here.

@dlongley
Copy link
Contributor

dlongley commented Apr 8, 2022

@tplooker,

To be clear OIDC Discovery is never required its just a method to support this style of issuance when desired the credential offer sent to the wallet could equally be (note this is just an example)

openid://discovery?issuer=https://example.com&credential_type=university_degree

The wallet can then if it desires just skip ahead straight into an OIDC request with the openid_credential:university_degree present in the list of scopes, the publishing of the metadata just supports pre-discovery of what will be in the credential if it is desired.

Then I would recommend eliminating the "wallet marketplace" option entirely, instead requiring an approach that mitigates the concerns I've raised.

Side note: I think I've also lost the thread here on how the user makes a compatible wallet selection or where / how the required wallet features are expressed. I'll see if I can find it in the issue here if it's already been said -- otherwise, could you elaborate on that part?

@tplooker
Copy link
Contributor

tplooker commented Apr 8, 2022

Then I would recommend eliminating the "wallet marketplace" option entirely, instead requiring an approach that mitigates the concerns I've raised.

Im not sure why eliminating it is required, if its optional and services other usecases why would we remove it? what does it prevent you from doing that you want to be able to do? I also dont really it as a "wallet marketplace" its just a way for a provider to advertise what credentials it supports issuing

@msporny
Copy link
Contributor Author

msporny commented Apr 8, 2022

Im not sure why eliminating it is required, if its optional and services other usecases why would we remove it?

We should eliminate it as a part of a core protocol because of ecosystem complexity. We should be trying to optimize for the minimum number of primitives that achieve the maximum number of use cases. Then we should pick primitives that can be layered/composed to maximize the next band of use cases.

I've noticed a pattern in the discussion (that we're all guilty of), of just referring to technology X to solve problem Y... and we're picking and choosing each technology and saying they are "optional". Ok, fine... but what's the baseline that everyone is expected to implement and how many use cases can we achieve at that baseline?

IOW, it's always possible to tack on optional technologies... OIDC4VCI + OIDC Discovery + SIOPv2 + DPOP + PCKE ... or VPR + VC-API + did:web keyAgreementEncryption + ... and when we do that, we tend to just go around and around in circles because... if you can solve a problem using one technology, it's probably true that you can solve the same problem using a different technology plus adding a bunch of add ons.

Person A: CHAPI enables user-driven mediation.
Person B: Oh, but OIDC could use CHAPI to achieve the same thing! ... but what about cross-device QR Codes, VPR can't do that.
Person A: VPR could use did:web keyAgreement to achieve that! ... but what about ...

and around in circles we go. How can we structure this conversation so that we start converging? Would it be helpful if we state things that need to be a part of the core interoperability profile?

Can we start with "Mediation is a mandatory part of the core protocol?" -- I only offer that because it seemed like @tplooker agreed to that on the CCG mailing list... and I don't know where @mavarley is on that right now.

I'm asking because I'm at a loss right now.

@mavarley
Copy link
Contributor

mavarley commented Apr 8, 2022

Person A: CHAPI enables user-driven mediation.
Person B: Oh, but OIDC could use CHAPI to achieve the same thing! ... but what about cross-device QR Codes, VPR can't do that.
Person A: VPR could use did:web keyAgreement to achieve that! ... but what about ...

Just a +1 to this comment.

Can we start with "Mediation is a mandatory part of the core protocol?"

(big apology in advance and asking quietly...) what do you mean by Mediation? I only ask because SK uses the term internally in several different ways...

As per #181 there may be scenarios where Mediation is not required?
Do you mean an intermediary protocol for connecting wallets to service /exchange/ endpoints when dealing with session specific data?

@tplooker
Copy link
Contributor

tplooker commented Apr 8, 2022

Can we start with "Mediation is a mandatory part of the core protocol?" -- I only offer that because it seemed like @tplooker agreed to that on the CCG mailing list... and I don't know where @mavarley is on that right now.

I think the disconnect here is that OpenID CP / OIDC4VCI doesn't always assume that you start from a channel, like a browser that requires mediation. Instead you could be scanning a static QR code from a piece of paper that contains openid://discovery?issuer=[https://example.com&credential_type=university_degree], hence having information at the providers metadata endpoint to tell you more about what auniversity_degree credential is, is useful in those cases. Designing a protocol that mandates that IMO is a layering violation and just means we would have to have another protocol when mediation isn't required.

@msporny
Copy link
Contributor Author

msporny commented Apr 9, 2022

(big apology in advance and asking quietly...) what do you mean by Mediation?

Yes, that was covered here: https://lists.w3.org/Archives/Public/public-credentials/2022Apr/0010.html

Excerpt below:

On 4/3/22 2:06 PM, Brian Richter wrote:

Manu, can you define "mediators" in this discussion?

Yes, we need to find a better term... even "wallet mediator" isn't descriptive enough.

A "mediator", as used in CHAPI, is a piece of software that enables a Holder to choose which "digital wallet" they want to use for a particular transaction. This is in stark contrast to how social login works today, where you are typically only given 3-4 fixed/centralized choices: Login with Google/Apple/Microsoft/Facebook

A mediator typically supports registration, selection, and deregistration. It also has other properties, like preventing an Issuer or a Verifier from discovering what Wallet the Holder is using (one strategy for preserving a competitive ecosystem).

A mediator is what enables digital wallet choice in the SSI ecosystem when you want to invoke a digital wallet, regardless of whether it is a web app or a native app, on the same device (such as your laptop). A mediator is agnostic to the messages flowing over the communication channel.

At present, CHAPI is used in the Verifiable Credentials ecosystem to select a wallet provider. It could also be used to select from among your OIDC providers.

In Aries / DIDComm land this term is used for agents that route messages to agents that are often offline however I suspect you are using it in a different way.

The meaning in CHAPI is slightly different. CHAPI is used to route messages to agents without a consideration to whether or not they're offline (e.g., CHAPI can work in both offline and online scenarios since it's purely client-side technology that lives in the browser).

@msporny
Copy link
Contributor Author

msporny commented Apr 9, 2022

@tplooker wrote:

I think the disconnect here is that OpenID CP / OIDC4VCI doesn't always assume that you start from a channel, like a browser that requires mediation.

Yes, true (though that point was never lost on me)... and this is one of the problems w/ the current conversation. In fact, I call out exactly the statement above in this comment. You are "whatabout"ing cross-device QR Codes (which DO need some sort of protection) when we haven't established whether you believe "wallet mediation" is required in same-device digital wallet invocations. That is, you're talking about a cross-device use case without us all getting on the same page about the same-device use case. I feel like we're close to getting on the same page about same-device use cases... can we run that to ground first?

We might try to start focusing on one class of use cases (e.g., same device wallet invocation) and come to some conclusion on the simplest/minimum primitives needed for that use case, and then moving on to another one. I do admit that we need to think about all of this holistically... however, that is leading to us talking in circles (sort of, I also admit that we're making progress with every circle -- this process was bound to be messy).

Can we run the "Is mediation required for same device wallet invocation use cases?" to ground? If we answer that question, we might be able to answer the question raised in this issue. To be clear saying "Yes, wallet mediation is required for same device wallet invocation use cases." does not require one to pick "CHAPI/OIDC/VC-API/VPR/etc." -- it's just an acknowledgement that we value addressing that use case. Digital Bazaar values that use case because we have customers that require the ability to invoke both native wallets and web wallets in same-device flows.

@tplooker
Copy link
Contributor

I dont think whether we are using a mediation component like CHAPI as a way to establish a communication channel between the wallet and issuer should be core to the protocol design here, instead it is an important layer above the protocol. If we make it one, we risk designing a protocol that only works over CHAPI and I disagree with that intent. Where components like CHAPI become important in this particular conversation is the trust and assurances it provides as a channel to allow an issuer to communicate with a wallet.

I believe it is better to start this protocol design from the perspective of an untrusted channel between the issuer and wallet, rather than trusted (e.g CHAPI). Because designing a protocol based on the former will mostly likely mean the flow will also work over a trusted channel like CHAPI, its just perhaps not as optimised. Whereas if you start from a world view that the channel must be trusted, chances are the assumptions in the underlying protocol will be invalid for the cases where it is not, hence causing a revisit of the core protocols design.

To answer your question directly Manu, I do see huge value in same device based flows through a mediation layer, however I think starting with these as the core requirements, risks designing a protocol that only works in that case.

@mavarley
Copy link
Contributor

Bringing in a conversation from another thread where we had talked about protocol intents and layering:

We have:

  1. Locators (Mediators as per Do the /exchanges/* endpoints need authz? #279 (comment))
  2. Discovery protocols (now that we've found each other, can we communicate?)
  3. Subject-to-wallet-to-session-binding (is there an an assurance the wallet operator is the same entity as the issuer/verifier session operator?)
  4. Credential delivery: (now that we can communicate and have a trust framework to operate in, how do I send you requests/presentations/etc?)

Examples:
Wallet locator: CHAPI, protocol handler, registered selector, QR
Discovery protocol: VPR, OIDC dynamic reg., WACI introduction
Subject-to-wallet-to-session binding: OAuth/OIDC (url) (and,or) credential presentation, N/A
Credential delivery API: VPR, OIDC-CP, WACI

Not all of the above are necessarily required for all interactions.

@jandrieu
Copy link
Contributor

Can we update the title?

I'm not sure we are still talking about /exchanges/* endpoints.

If we are, can we can an enumeration of those endpoints, including the components on which those endpoints are expected?

@msporny
Copy link
Contributor Author

msporny commented Jan 17, 2023

The group discussed this item on 2023-01-17. It was noted that many months have passed since this topic was discussed and in the meantime flows have been added to the OIDC4 flows that do not require registration or allow dynamic client registration. @dlongley noted that we should have authz for the creation of exchanges endpoints but should not require authz for the usage of the endpoint you create. @dmitrizagidulin agreed with a +1, authorization for using the exchanges endpoint should be optional because there are several valid use cases where authorization is done inband as a part of the exchange... DCC learner credential wallet uses such a flow... this is different from having authz on the API endpoint itself. Alan Karp noted that for administration, you will probably have authz. For public endpoints you almost never want to have authz, unless you want protection against DoS, in which case you went to other endpoint first, get an authz credential, and then provide that to "public endpoint". You absolutely don't want authz REQUIRED for a public endpoint.

@jandrieu noted that he was still confused about what exchanges is doing, so difficult to comment on technical ramifications, but noted that those implementing it find it useful. Why isn't it just a token passing when you have an endpoint that you hit and you get a "you need to get something else" -- who is telling whom that a flow is going to happen... and then "you need these things for this flow". @TallTed noted that he was confused as well -- designing things to not require authz has a high potential for security issues down the line -- in most deployments, this might not be necessary (especially in test), perhaps some kind of tokenization needs to be involved. When you come to newly created endpoint, you have to have token from person that requested endpoint. @dmitrizagidulin explained what /exchanges/ endpoint was... there is a need for iterative credential issuance/reissuance -- so endpoint belongs in issuer endpoint, but closer to issuer rather than verifier -- idea is it's a multistep way to provide credentials, where issuer can, in stages... "before I can issue to you, I need X, Y, and Z -- and might include authz" -- reason to do authz on application level is to allow discovery, to allow exchanges endpoint to specify which VCs/authz it needs to issue/reissue a VC. @dlongley noted that this isn't necessarily on issuer coordinator component... end user is using issuer coordinator website, via that interface, they make a decision to request a VC, upon that request, issuer coordinator creates exchanges URL that follows process that wallet needs to go through, hands that exchanges endpoint to wallet, which then (gets into authz discussion), URL could be seen as an authz capability (unguessable URL and only someone who's been handed the URL can go to the endpoint and proceed). When they hadn that off to a digital wallet and visit the URL, that URL might ask them for additional VCs... endpoint could be implemented on issuer coordinator to allow custom code, or could be implemented through external exchanges service that operates on basic primitives -- some flows can be easily constructed form a set of VPRs and VC templates, other flows cannot. It depends on the type of flow the user is going to end up going through. That's how exchanges set of APIs should be understood. @PatStLouis noted that exchanges service makes more sense now, in case of Aries, typical flow is credential offer, then credential request, then issuance. Issuer offers VCs, Holder requests it, Issuer issues it. How that language is used here "issue" -- signs the VC, adds the proof, previous to that "issuing" had the whole flow "to sign a VC and send it to wallet". Exchange service in VC API is whole communication between holder and issuer so they can understand how to exchange information, hopefully at end of implementation, Holder has VC in the wallet. Regarding authz, there is the concept of discovery, wouldn't discovery be treated separately? Unauthenticated endpoint that says "Here are the 'languages' that I can speak, which of these interactions would you like to begin? There are the functions I support, is that the type of discovery endpoint that the issuer can provide?".

@jandrieu Why not just as a response when you try to get a credential issued and you hit the issuer, why not use a redirect pattern, which is a more common pattern on the web? @dlongley noted that redirects don't work, you might not want to lose state, you might need to go to different device, different app, that pattern doesn't cover everything that needs to happen. @jandrieu didn't mean literal HTTP redirect, he meant the use of the interact field in the VPR. @dlongley noted that's exactly how it's implemented today (in CHAPI and some VC API exchanges). @dmitrizagidulin noted that the reason it's not done through /issue endpoint, if it was named literally, it would be an /add-proof endpoint... @jandrieu noted we're not talking about issuer service... @dmitrizagidulin said you could look at the exchanges endpoint as living on the issuer coordinator. The exchanges endpoint is meant to interact w/ wallets, very much a public endpoint, hence the optional authz, when credentials expire and wallets want to expire, they would talk to exchanges endpoint, when wallet wants to request particular VC, they'd use exchanges endpoint. @PatStLouis said that @dmitrizagidulin the /issue endpoint is an "add proof" endpoint, issuing credential has a different meaning in Aries as it does in VC API -- ACAPy admin interface has a specific endpoint, different endpoint for issuing credential, in issue credential endpoint, different endpoint for every step of flow, same thing for verifier endpoint. At one point, in one of the steps, you choose if you want to issue AnonCred or JSON-LD VC, but endpoint is strictly signing a credential. @dlongley noted that the /issue endpoint is more than just signing, for examples, it adds status list information -- creates a true instance of credential and updates backend state management. An endpoint example, we have WebKMS, just for making calls to sign/verify via cryptographic operations, those endpoints are stateless and don't care about what is being signed (just sign a hash), whereas /issue endpoint is responsible for that in VC API. @msporny noted that this can show up on issuer coordinator, verifier coordinator, and holder coordinator. @jandrieu noted that when refreshing, you'd use credentialRefresh property on VC not something "discoverable". Why do we have to go to exchanges endpoint, why can't we do everything w/ interact vs. saying coordinator they have to have this mechanism? @dlongley noted that you don't have to have this endpoint, they can model their URLs however they want to, refresh could go to exchanges endpoint, but could go elsewhere -- depends on refresh type -- those are all open options. The /exchanges/ API provides a common interface that people can write software against - a common architecture for software reuse. What we do w/ the other endpoints, there is a common pattern, because of common pattern, gives architecture for developers to develop against. @PatStLouis wanted to note about /exchanges/ endpoint could be on Holder... we talk about Holder, Verifier, Issuer -- which are roles, specific agent has in a specific interaction, mobile wallet, issued a VC, in that interaction I'd be holder, but isn't it forseeable that agent could be in a different interaction become an Issuer using same technology behind it. @msporny noted that we definitely have this on issuer coordinator and verifier coordinator, holder coordinator is a still more up in the air. @PatStLouis noted that roles bind when you are doing an interaction and only then, the VC API, every implementation should have all the routes available. @jandrieu one of the things we documented in the component diagram, the arrows show initiation of flows, which are from the holder... callbacks, async, holder provides callback from verifier, would be hesitatant to have endpoints on holder, could be attack vector. @dlongley didn't quite understand what the use case is for exchanges on verifier coordinator, would expect to be on issuer coordinator, perhaps something not a VC is being presented back to you for verifier coordinator? Not aware of a use case. @PatStLouis directly to what Dave said, couldn't verifier send a holder a proof request that would be a tangible thing sent through /exchanges/ API? @dlongley There is confusion around what it means to have issuer coordinator/verifier coordinator to be the same thing? You end up in a situation where a verifier is an issuer and becomes a verifier again -- a bit confusing trying to understand when we say exchanges endpoint could be on a verifier coordinator, also means verifier coordinator could also be issuer coordinator, if you get a proof request, you have to use it, perhaps we're saying you might use it on another service/system? Not quite sure. John Henderson noted, on user exchanges for verifier, found myself where Holder wants to get access to a service, so they ask / discover exchange endpoint and present credentials and are authorized having credentials used to those service, not receiving a VC in return, see it as holder exchaneges w/ verifier.

@PatStLouis noted that something doesn't sound secure about this. @msporny noted that this works just like a regular website, which doesn't have authz on the first hit. @dmitrizagidulin noted that these are exchanges under opaque strings, this is a specific opaque exchange that usually the wallet arrives at out of band. @TallTed if this is equivalent to homepage optional activation seems ok, but making it optional endpoint, they might not implement this authz piece they might change implementation because they discover they need that -- make the /exchanges/ endpoint mandatory to implement -- feels like a thing that should be there. @dlongley noted that what we should say is: "A given exchanges endpoint should be a URL capability or establish authz through exchange flow itself." @msporny asked if there was ever a use case where the previous sentence didn't fit? @dlongley noted that there is always authz -- like "number of bearer tokens that can be given out". Alan Karp noted that you do that if there is a DoS, if it's a public endpoint, if you want people to use this as their first interaction w/ the system, how do they get the initial authz -- if it's a piece that you only make sense to contact after you've been using other pieces of the system, makes sense to always have authz. @dlongley noted that we're really talking about the latter, URL capability or authz established within flow itself covers this -- what we were worried about was saying that "if you were given URL capability, do you also need to use OAuth2 to use the exchange endpoint" and the answer to that is clearly "no"... we're crossing trust boundaries. Totally different party thats accessing /exchanges/ endpoint using digital wallet.

@msporny asked if anyone had concerns about "A given exchanges endpoint should be a URL capability or establish authz through exchange flow itself." Alan Karp noted not an objection since we're talking about "private endpoints". @msporny noted it's not necessarily private, you have to interact elsewhere. @dlongley noted that there are multiple options here where you could get the capability URL. Alan Karp noted that you don't need authz to hit it the first time. When it's part of a flow, you get capability to invoke.

@msporny
Copy link
Contributor Author

msporny commented Jan 24, 2023

We discussed this on the 2023-01-24 telecon. @jandrieu noted that there are at least two things of concern 1) difference between endpoints, between issuer coordinator and verifier coordinator and verifier service (secured thorugh some mechanism) vs. verifier coordinator needs auth or not. 2) Establishing authz through exchange flow is still having authz on that exchange flow. @dlongley thinks what Alan was saying fits into quote above... "A given exchanges endpoint should be a URL capability or establish authz through exchange flow itself." -- either there is a case where you are using a URL capability (it's not advertised and sufficiently randomized to not guess URL), or case that there is a "public" URL, anyone can hit that, when you hit that URL, you get a VPR that you must respond to and in so doing, some sort of authz is going to be established through the exchange flow. @dlongley feels like quote covers both cases. Either it's a URL capability (authz by holding the capability) or authz is established upon interaction. @msporny asked about "first come - first served" use cases? @dlongley noted that even in those cases, authz of some kind will be done to prevent DoS, or limited number of credentials to be given out, one over limit - rejected, implies some sort of control over using endpoint. @jandrieu noted "proof that service is running" doesn't fit into that use case. @dlongley noted that even in that use case, it'll probably be rate limited.

@msporny noted that if we enumerate all the possiblities, if we answer the question? @dlongley and @jandrieu noted that if we go endpoint-by-endpoint, we answer this question.

The next step for this issue is to close the issue once we assign what types of security are on an endpoint.

@msporny
Copy link
Contributor Author

msporny commented Apr 11, 2023

The group discussed this on the 2023-04-11 telecon:

The group has set available security schemes for all endpoints in PR #334, which addresses part of this issue.

The next step is to raise a PR to refactor exchanges as a first-class component and explain how exchangers are created/configured and then how exchanges are built off of exchangers.

@msporny msporny added the ready for PR Issue ready to be resolved via a Pull Request label Apr 11, 2023
@msporny
Copy link
Contributor Author

msporny commented Jan 7, 2024

Waiting for #353 to land and then will build off of whatever text is added to the spec as a result.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready for PR Issue ready to be resolved via a Pull Request
Projects
None yet
Development

No branches or pull requests

7 participants
@msporny @dlongley @jandrieu @peacekeeper @mavarley @tplooker and others