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

Signed transaction data object #342

Open
senexi opened this issue Nov 22, 2024 · 48 comments
Open

Signed transaction data object #342

senexi opened this issue Nov 22, 2024 · 48 comments

Comments

@senexi
Copy link

senexi commented Nov 22, 2024

Currently the transaction_data object is defined as a "base64url encoded JSON object". For some use-cases it might be useful to actually sign this data, so it can later be linked to its originator. So the idea would be to also allow an encoded JWT here.

@jogu
Copy link
Collaborator

jogu commented Nov 22, 2024

Hi @senexi , can you confirm if you've signed an OpenID contribution agreement please, and if not sign one please? https://openid.net/intellectual-property/openid-foundation-contribution-agreements/

Thanks!

@c2bo
Copy link
Member

c2bo commented Nov 24, 2024

Currently the transaction_data object is defined as a "base64url encoded JSON object". For some use-cases it might be useful to actually sign this data, so it can later be linked to its originator. So the idea would be to also allow an encoded JWT here.

Can you describe your requirement / use-case in a bit more detail? We already have the option to sign the Authorization Request containing the transaction_data (which will very likely be required in most use-cases that use transaction_data) - wouldn't that be enough or do you want a second signature by another party?

@senexi
Copy link
Author

senexi commented Nov 25, 2024

@jogu we are checking the paperwork today and sign it.

@senexi
Copy link
Author

senexi commented Nov 25, 2024

@c2bo we are currently working on using this feature for payments where the presentation of a credential is requested by a merchant but will be forwarded to an issuing bank for verification. If the transaction_data object would be signed, the issuing bank could verify who presented the data to the holder, given the presentation and the original (signed) transaction_data_object. The Authorization Request itself does not help in this case.

We will also publish a paper describing it in more details soon. Will link to it once it is published.

@senexi
Copy link
Author

senexi commented Nov 26, 2024

Hi @senexi , can you confirm if you've signed an OpenID contribution agreement please, and if not sign one please? https://openid.net/intellectual-property/openid-foundation-contribution-agreements/

Thanks!

@jogu I signed the agreement.

@jogu
Copy link
Collaborator

jogu commented Nov 26, 2024

Thanks @senexi !

Can you expand on this bit please:

the issuing bank could verify who presented the data to the holder

A flow diagram might help as I'm not sure how the issuing bank and the merchant relate to the issuer/wallet/verifier roles in OID4VP.

@senexi
Copy link
Author

senexi commented Nov 27, 2024

Thanks @senexi !

Can you expand on this bit please:
A flow diagram might help as I'm not sure how the issuing bank and the merchant relate to the issuer/wallet/verifier roles in OID4VP.

Hi @jogu

Here it is explained in more detail.

However the important part might be this. An sd-jwt presentation (named P2Pay here) is forwarded from the verifier to the issuer of the credential. And the issuer could verify who the originator of the transaction_data object actually is, if it would be signed.

image

@tlodderstedt
Copy link
Collaborator

The current flow design is intended to be used by the ASPSP to authorize a transaction with its customer (through the wallet). That's why a payment credential (issued by the ASPSP) is used to do the authorization.

Your flow is the typical Open Banking Payment Initiation flow, where the TPP gets an access token to initiate a payment with the ASPSP. I don't understand what the value/purpose of the TPP to wallet interaction is in this case. Can you please explain?

Tp me it seems you want to utilize the credential presentation (with the transaction data) as kind of an access token towards the ASPSP.

@senexi
Copy link
Author

senexi commented Nov 28, 2024

In the standard OpenBanking SCA Flow the customer is initiating the payment through a different channel first. But the actual initiation of the payment (including SCA) could also be done using the wallet, by requesting an attestation that links to a payment account an a certain payment method of rail. This also provides the option for the TPP / merchant to request additional attestations like age verification or a loyalty card and thereby leverage the wallet ecosystem. In this case, the presentation would be forwarded to the issuer for verification (and payment execution). For that case, it would be useful if the ASPSP could not only verify that the presentation is linked to a certain payment request (transaction_data object), but also that this payment request is linked to the TPP.

@stefan-kauhaus
Copy link

Wouldn't the TPP be known to the ASPSP based on the interaction between them? Berlin Group etc. typically are not anonymous APIs; the TPP would have an API client id + secret / certificate of some sort in any case?

@senexi
Copy link
Author

senexi commented Dec 3, 2024

@stefan-kauhaus yes, looking at open banking, the TPP is identified by the according certificates. However we are not only looking at open banking. If we look at it from a more generic point of view, we are talking about forwarding the presentation - may be even relaying it through multiple parties. So it might not always be the case, that the party submitting the presentation to the issuing ASPSP is the one who created the authorization request for the wallet. In such a case, a signed transaction_data object would be a way to maintain this link.

@cyberphone
Copy link

cyberphone commented Dec 4, 2024

It is a bit hard to understand what the TPP adds to the pudding in the depicted scenario. If there is a Merchant involved, it needs to be included in the sequence diagram as well.

In case a TPP forwards an authorization (like illustrated), I would assume that it would embed the received authorization data, in a specific TPP-signed TPP->ASPSP message.
EDIT: After reading step 8, it seems that this is what the current spec actually do. Isn't that sufficient?

@cyberphone
Copy link

@stefan-kauhaus
Copy link

In such a case, a signed transaction_data object would be a way to maintain this link.

Hi @senexi, this signature would only add value if the 'ultimate verifier' (in this example, the payer's PSP) has an understanding who the 'immediate RP' (the merchant/PISP/etc.) is and if he has a robust way to obtain that party's public key, right? How do you see this part?

@c2bo
Copy link
Member

c2bo commented Dec 9, 2024

I am also slightly worried about privacy implications for this flow. Wouldn't we in the case that is depicted here want the TPP to not be able to see all details like account information?
I am not that knowledgeable about payment flows but my understanding would be that ASPSP requires details like account information whereas TPP might not need and probably should not be able to see that kind of information?

@tlodderstedt
Copy link
Collaborator

tlodderstedt commented Dec 13, 2024

Hi all,

I think the current proposal has some drawbacks.

  • the TPP does need to know claims must be disclosed in the VP
  • the VP is not protected against replay between TPP and ASPSP
  • the TPP get's to know the content of the VC/VC even though

I suggest to adopt a more Open Banking style approach and use the wallet to issue a sender constrained access token (which contains the payment VP). Note: the proposed OAuth flow uses the messages as designed for OpenID4VP, so it will require OAuth extensions (let's call it decentralized OAuth ;-)).

Here is the sequence diagram:
image

  1. (steps 1-4) The TPP (acting as an OAuth client) sends an authorization request using RAR requesting authorization to request a payment initiation. Technically, this means a redirect from TPP to wallet and the wallet fetching the request object from the request URI. This also allows to do a proof of possession for a DPoP key.
  2. (step 8) The wallet asks for consents and pushes the access token (containing the EAA presentation) to the TPP using the TPP's response endpoint.
  3. (steps 9-10) Redirect from wallet back to TPP
  4. (step 11) The TPP sends a payment initiation request to the ASPSP (including a DPoP PoP).
  5. ... the rest is payment initiation processing

The request (step 4) would contain an authorization_details parameter with the following content:

{
   "type": "payment_initiation",
   "instructedAmount": {
      "currency": "EUR",
      "amount": "123.50"
   },
   "creditorName": "Merchant A",
   "creditorAccount": {
      "bic":"ABCIDEFFXXX",
      "iban": "DE02100100109307118603"
   },
   "remittanceInformationUnstructured": "Ref Number Merchant"
}

It would also need to contain a proof of possession of a DPoP key, like this:

{
  "typ":"dpop+jwt",
  "alg":"ES256",
  "jwk": {
    "kty":"EC",
    "x":"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs",
    "y":"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA",
    "crv":"P-256"
  }
}
.
{
  "iat":1562262616,
  "nonce": "eyJ7S_zG.eyJH0-Z.HX4w-7v"
}

The wallet would need to know that such a request needs to be answered with an access token containing the presentation of an EAA of a certain type, lets assume a vct of "https://credentials.example.com/a2pay". The respective presentation would be added to the access token (along with the DPoP key in the cnf claim). Here is an example:

{
    "iss": "https://issuer.eudiw.com",
    "aud": "https://bank.example.com/api",
    "exp": 1883000000,
    "nbf": 1718198433,
    "iat": 1718198433,
    "a2pay_presentation": "eyJhbGciOiAiRVMy..V0~Wy..ZnBAan5g",
    "cnf": {
      "jwk": {
        "kty":"EC",
        "x":"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs",
        "y":"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA",
        "crv":"P-256"
      }
    }
}

The TPP would need to send this access token along with the DPoP proof in step 11.

WDYT?

@cyberphone
Copy link

cyberphone commented Dec 15, 2024

Thanx @tlodderstedt, this is AFAIK the first (ever) attempt by somebody representing OpenID, taking a stab at a wallet associated with Open Banking!

Rather than going into the specification details, I believe we should first spend time figuring out what our expectations may be with respect to functionality, security, and privacy. None of the published pilots have bothered much with these rather fundamental issues. eIDAS or ARF compliance means little to the payment community. It is also worth keeping in mind that the competition is fierce and that the market is [rightfully] quite reluctant adopting unproven solutions. Making a slightly better mousetrap is of course an option, but that doesn't sound very cool.

There is plenty of room for innovation since Apple Pay does currently not support the following:
✅ Digital receipts. "Digitization" anybody?
✅ Unified POS/Online Payer authorization concept and protocol.
✅ Unified Payer authorization and UX. An account is an account, be it VISA, SEPA, or "XYZ". Let the backend deal with that (aka "payment orchestration"), as is already the case for card payments.
✅ Real-time account balances.
✅ Person-to-Person payments using SEPA Inst.

Regarding the specifications themselves, I have a hard time figuring out where the Merchants are. Merchants are neither relying parties, nor in need of credential presentations; they depend on assurances that they will be (or are already being) paid. Such data can only be provided by payment backends. In the rare occasion a Merchant is also a TPP, it shouldn't change anything protocol-wise; it just means taking on multiple roles.

@jogu @Sakurann

@senexi
Copy link
Author

senexi commented Dec 15, 2024

@tlodderstedt, thanks for picking this up. A few remarks regarding the proposal. As you already mentioned, wrapping the P2Pay in an Access token introduces a new / custom flow for the wallet. Although we also included a proposal for a possible endpoint (A2Pay Direct) where a bank could directly receive a P2Pay, we always envisioned it as something optional as there might be many different / proprietary ways to transport the P2Pay in the end. For example, the signed body feature in the current Berlin Group specs might also be a viable option. Taking this into account, it would mean introducing a specific frontend flow (for all wallets) only to support one possible backend flow, wouldn’t it?

But wouldn’t it be possible to keep the default OpenID4VP flow and tackle the drawbacks you mentioned in a different way.

Couldn’t the ASPSP easily detect a replay by tracking the hash of the P2Pay? Once a P2Pay is processed, the ASPSP would refuse the processing if it would be submitted again. To limit the timespan the ASPSP needs to keep track of the P2Pay hash, the lifetime of the according KB-JWT could be limited by including the exp claim into the KB-JWT, making it a rather short-lived token.

Also sharing the claims of the A2Pay with the TPP might not really be an issue, as the A2Pay should contain only information that actually need to be shared with the TPP. Like some kind of an account identifier and / or meta data required for processing by the payment rail that the A2Pay is connected with. Also wouldn't the TPP always be able to see those claims.

What we are currently not able to do is, to keep the link between the original TPP (who presented the payment request to the user) and the P2Pay. Although it might not even be required (depending on the payment rail), it would be useful to have the option to keep this link cryptographically - which is why I submitted this feature request here ;-) If the TPP is actually signing the transaction_data object, it would establish this hard link between the wallet signed P2Pay and the TPP, no matter how the P2Pay is relayed to the issuer in the end.

@senexi
Copy link
Author

senexi commented Dec 15, 2024

@cyberphone

None of the published pilots have bothered much with these rather fundamental issues. eIDAS or ARF compliance means little to the payment community.

Would you maybe care to share some details and explain in which way the LSPs never looked at privacy and security? It is actually a bold statement, considering the fact that the flow proposed by the LSP completely builds on the default OpenID4VP flow for SCA. But maybe there is an issue there…

Regarding the merchant. In this model, the role of the merchant and TPP are the same - as you noticed already. And yes, it should not change anything protocol wise.

@cyberphone
Copy link

@senexi Pardon me for using somewhat sweeping comments.

Would you maybe care to share some details and explain in which way the LSPs never looked at privacy and security? It is actually a bold statement, considering the fact that the flow proposed by the LSP completely builds on the default OpenID4VP flow for SCA. But maybe there is an issue there…

Yes, because these specifications do assumptions that doesn't seem to translate well to consumer-to-business payment transactions.

Regarding the merchant. In this model, the role of the merchant and TPP are the same - as you noticed already. And yes, it should not change anything protocol wise.

Well, this was not my intention. Merchants and TPPs represent entities having distinct roles as well as unique security, privacy and trust characteristics. That a single entity can take on multiple roles is another thing.

@cyberphone
Copy link

@senexi wrote:

Couldn’t the ASPSP easily detect a replay by tracking the hash of the P2Pay? Once a P2Pay is processed, the ASPSP would refuse the processing if it would be submitted again. To limit the timespan the ASPSP needs to keep track of the P2Pay hash, the lifetime of the according KB-JWT could be limited by including the exp claim into the KB-JWT, making it a rather short-lived token.

Yes! This is idempotent operation and may even contribute to reliability since it makes retransmission a "thing":
https://fido-web-pay.github.io/specification/#seq-10.5

@stefan-kauhaus
Copy link

@c2bo

I am also slightly worried about privacy implications for this flow. Wouldn't we in the case that is depicted here want the TPP to not be able to see all details like account information?

When we use transaction_data to address the dynamic linking requirement, then the data in this object has the purpose of being shared knowledge between the user (payer), the user's bank (payer's PSP), and the recipient (payee, e.g. merchant, potentially represented by their acquirer or PISP). The data typically contains the amount, currency, and payee details (including their name and/or account number). The data typically does not contain any payer's details (like payer's name or account number), as this is established separately between payer and payer's PSP. Hence, the only data being at risk of getting disseminated when additional intermediaries are added to the picture (to help "forwarding" the authentication/dynamic linking evidence to the payer's PSP, as @senexi explained) are the merchant's details. Given it is the merchant who would hand this off to the intermediary, I do not see specific privacy implications.

@cyberphone
Copy link

@stefan-kauhaus Since there is no fifth entity (Merchant/Payee) in the depicted schemes, I'm unable to draw any conclusions regarding privacy with respect to the User/Payer.

@stefan-kauhaus
Copy link

@cyberphone

My comments addressed @c2bo's question on privacy against the backdrop of the scenario how @senexi had sketched it:

If we look at it from a more generic point of view, we are talking about forwarding the presentation - may be even relaying it through multiple parties. So it might not always be the case, that the party submitting the presentation to the issuing ASPSP is the one who created the authorization request for the wallet. In such a case, a signed transaction_data object would be a way to maintain this link.

@cyberphone
Copy link

@stefan-kauhaus I see. Personally, I have some difficulties translating the above into a concrete specification.

@cyberphone
Copy link

cyberphone commented Dec 16, 2024

A Sequence Diagram with Merchant/Payee
Sequence Diagram

https://cyberphone.github.io/doc/defensive-publications/partial-encryption-full-signature.pdf

A simplified next step for the scheme described in the PDF adapted for SEPA:

# Object ID: https://datatracker.ietf.org/doc/draft-rundgren-cotx/
1010(["https://example.com/psp-request-sepa", {
# Payee (receiver) account
  "accountId": "DE02100100109307118603",
# The ID as defined by the PSP
  "merchantId": "10577",
# The authorization object created by the wallet as shown in the PDF
  "payerAuthorization": {
    0: {
      "timeStamp": "2024-12-10T13:28:02-01:00",
      "providerInfo": {
        "networkId": "https://banknet2.org",
        "serviceLocator": "mybank.com"
      },
      "paymentRequest": {
        "amount": "600.00",
        "currency": "EUR",
        "commonName": "Space Shop",
        "referenceId": "20241210.00079"
      }
    },
    1: 3,
    2: {
      1: -29,
      4: {
        1: 2,
        -1: 1,
        -2: h'e812b1a6dcbc708f9ec43cc2921fa0a14e9d5eadcc6dc63471dd4b680c6236b5',
        -3: h'9826dcbd4ce6e388f72edd9be413f2425a10f75b5fd83d95fa0cde53159a51d8'
      },
      7: {
        1: 2,
        -1: 1,
        -2: h'ce264b040ad50970935438f7588202b633e99587ebf43b8b6f6433cddfd0af79',
        -3: h'8a156afabaccb3143525f83511ca108601c5e12c21d0cec5737e900a7b56f7c1'
      },
      10: h'c25237ed702f9479f247ee95b5cb8465faaa6c096ccb026fb0068d87597661....'
    },
    8: h'33b239edee76332761d9cd041ce82d6f',
    9: h'ab1d2e84b6f48f03cba0ba67',
    10: h'f48bb11ca94bc94e47bfc0d0f31a36de2a1ef2162c3765c576a4d7b6a042d7dc....'
  },
# The Merchant/Payee must authenticate to the PSP
  "authorizationSignature": {
    1: -9,
    4: {
      1: 2,
      -1: 1,
      -2: h'e812b1a6dcbc708f9ec43cc2921fa0a14e9d5eadcc6dc63471dd4b680c6236b5',
      -3: h'9826dcbd4ce6e388f72edd9be413f2425a10f75b5fd83d95fa0cde53159a51d8'
    },
    6: h'8aa613db7ba90a9335509c6ede69cc4830650faef2ff267f9d816a5a3480f2ff996....'
  }
}])

@tlodderstedt
Copy link
Collaborator

But wouldn’t it be possible to keep the default OpenID4VP flow and tackle the drawbacks you mentioned in a different way.

Couldn’t the ASPSP easily detect a replay by tracking the hash of the P2Pay? Once a P2Pay is processed, the ASPSP would refuse the processing if it would be submitted again.

@senexi one time use for replay detection is a rather limited approach as injections and any sort of abuse where the attacker prevents the legitimate party to use the token cannot be prevented. So if we want to make this additional flow a secure option of the normal OpenID4VP flow, we need additional measures in place.

The difference between normal OpenID4VP and this flow is the fact the RP does not consume the credential presentation itself but rather uses it to authorize an API call with a 3rd party. I suggest to signal this to the wallet in the presentation request through an additional parameter present_to_thirdparty, which causes the wallet to respond with an access token wrapping the credential presentation in the vp_token.

image

  1. (steps 1-4) The TPP (acting as OpenID4VP RP) sends a presentation request with transaction data for payment initiation. In addition to the normal flow, it also indicates that the resulting VC presentation shall be used with a third party (the API of the ASPSP/the bank). It also passes a DPoP key, to be used to proof possession when using the VC presentation (as access token) with the payment initation API of the ASPSP.
  2. (step 8) The wallet asks for consents and pushes the access token (containing the EAA presentation) to the TPP using the TPP's response endpoint.
  3. (steps 9-10) Redirect from wallet back to TPP
  4. (step 11) The TPP sends a payment initiation request to the ASPSP (including a DPoP PoP).
  5. ... the rest is payment initiation processing

This is an example request for step 4:

{
  "client_id": "x509_san_dns:client.psp.org",
  "response_type": "vp_token",
  "redirect_uri": "https://client.psp.org/callback",
  "nonce": "n-0S6_WzA2Mj",
  "dcql_query": {
    "credentials": [
      {
        "id": "A2Pay",
        "format": "dc+sd-jwt",
        "meta": {
          "vct_values": [
            "https://credentials.example.com/a2pay"
          ]
        },
        "claims": [
          {"path": ["id"]},
          {"path": ["payment-product"]},
          {"path": ["payment-uri"]},
          {"path": ["currency"]},
          {"path": ["name"]}
        ]
      }
    ]
  },
  "transaction_data": [
    eyAidHlwZSI6IC...cGluZyBhdCBNZXJjaGFudCBBIiB9
  ],
  "present_to_thirdparty": {
    "credential_ids": [
      "A2Pay"
    ],
    "dpop_key": {
      "jwk": {
        "crv": "P-256",
        "kty": "EC",
        "x": "NASJ2ADuagOvraLf7O4VxcBMbantzL9dd0jpvMLnBfs",
        "y": "OJY6pqCqRIzpEt78OXasWHGgqV5ZGre_3cHtpNH82gg"
      }
    }
  }
}

The parameter present_to_thirdparty contains the additional data and indicates to the wallet a modified flow.

  • credential_id identifies the requested credentials, the RP wants to present to a third party.
  • dpop_key is the public key the credential presentation (used as access token) shall be bound to.

Note: the present_to_thirdparty function MAY be combined with transaction data.

The wallet will ask the user for consent for the transaction and produce the response. The wallet will wrap the respective credential presentation into an JWT-based access token along with a cnf for the DPoP key and the client_id of the authenticated wallet client. Here is an example access token:

{
    "iss": "https://issuer.eudiw.com",
    "aud": "https://bank.example.com",
    "client_id": "x509_san_dns:client.psp.org",
    "exp": 1883000000,
    "nbf": 1718198433,
    "iat": 1718198433,
    "credential_presentation": "eyJhbGciOiAiRVMy..V0~Wy..ZnBAan5g",
    "cnf": {
      "jwk": {
        "kty":"EC",
        "x":"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs",
        "y":"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA",
        "crv":"P-256"
      }
    }
}

Note: Even though the access token uses the JWT-format, this design is intended to work with any credential format.

This access token is signed with the same key that is used to sign the credential presentation. The access token is encrypted with a public key of the bank. This key would need to be determined either from data in the A2Pay credential or through metadata the wallet requests from the bank.

The access token is returned in the vp_token instead of the credential presentation in a structure containing the following claims:

  • access_token: the access token
  • nonce: the nonce as send in the request.
  • metadata: Additional metadata the wallet shares with the RP. In the case of the A2Pay credential, this is the payment endpoint URI.

Here is an example:

{
    "vp_token": {
        "A2Pay": {
            "access_token": eyJhbGciOi...00ifQ.OKOaw...zg.48...3b.5eym8T...QD_A.XFBo...SkQ,
            "nonce": "n-0S6_WzA2Mj",
            "metadata": {
                "payment-uri": "https://bank.example.com/pay/7dfe5484g78"
            }
        }
    }
}

Note: depending on the use case, the RP might know the API to send the access token to in advance. In such cases, the RP would add them to the present_to_thirdpartystructure. If not, the wallet determines those and add it to the response.

The RP will send this access token along with the DPoP proof in step 11.

@senexi
Copy link
Author

senexi commented Dec 17, 2024

@tlodderstedt thanks for your proposal. I can see us going forward with that as it is also a more explicit way to handle things. One thing that comes to my mind though is how to determine the metadata of the presented credential. One thing would be to just include all disclosed claims also into the meta data property. Another thing would be to flag them somehow during issuing, but this would create a dependency on the wallet itself. Could also be in the issuer metadata (the TPP could also retrieve directly), however we might need something here that is specific to the credential issued. What are your thoughts on that?

@cyberphone
Copy link

cyberphone commented Dec 17, 2024

@tlodderstedt @senexi C2B (Consumer To Business) payment schemes are (usually) Merchant-centric but I don't see any Merchant. That I also can't find a description of payment credentials makes it hard to see if your specifications matches or surpasses the feature list that I (FWIW...) consider required.

Regarding stealing payer authorizations, there are essentially two basic ways:

  • Corrupt client software/platform. I certainly do not have anything to offer here.
  • Network/protocol attacks.

Regarding the latter, the "Saturn" wallet builds on the same (but inverted) security model as FIDO: WebPKI-secured host-names. That is, the Wallet records the request host name and provides as a part of the authorization data. Then the PSP based on registered host name information + strong Merchant authentication (via a signature/id), can verify if the forwarded request is authentic. Checking claimed name is another easy to perform test.

  "payerAuthorization": {
    0: {
             .
             .
      "payeeHost": "spaceshop.com",
             .
             .
      }

It is also worth considering that in order to be Merchant you (probably) have to sign a compliance agreement. This makes it somewhat less attractive committing crimes in full daylight.

The UX described in https://github.com/nobid-consortium/payment-reference-documentation/blob/main/payment-reference-doc.md#screenflow feels a bit "quirky". A single user Authz should be sufficient.

@tlodderstedt
Copy link
Collaborator

tlodderstedt commented Dec 18, 2024

@senexi happy you like the proposal ;-)

One thing would be to just include all disclosed claims also into the meta data property. Another thing would be to flag them somehow during issuing, but this would create a dependency on the wallet itself. Could also be in the issuer metadata (the TPP could also retrieve directly), however we might need something here that is specific to the credential issued. What are your thoughts on that?

I have considered to add this to the credential through claims and/or (disclosure) policies. If that is to static, one could also use issuer hosted metadata.

@tlodderstedt
Copy link
Collaborator

tlodderstedt commented Dec 18, 2024

@cyberphone don't you think the PSP could be a merchant?

@cyberphone
Copy link

@cyberphone don't you think the PSP could be a merchant?

Well, Merchants and PSPs represent different roles. In some cases an entity takes on both roles. I don't see a need for doing something special protocol-wise for edge cases. I guess that possible optimizations and simplifications can be carried out locally.

@cyberphone
Copy link

According to https://github.com/nobid-consortium/payment-reference-documentation/blob/main/payment-reference-doc.md#security-considerations Merchants are TPPs that verify. Verify what?

These guys have another idea on how to use OpenID4VP:
https://ewc-consortium.github.io/eudi-wallet-rfcs/payment-rfcs/implementation-guides/payment-authentication-sca-using-eudi-wallets.pdf#page=38

Facts:

  • Banks already have working PayByBank solutions. The much hyped https://www.w3.org/TR/secure-payment-confirmation/ tries to compete with already deployed SCA solutions.
  • The European Commission is about to launch an Ad-Hoc Task Force for payments using EUDI.
  • The majority of the SPRIN-D Funke conference participants thought it is futile competing with Apple and Google.

Any ideas on how to proceed?
@jogu @tlodderstedt @Sakurann

@mobinauten
Copy link

mobinauten commented Dec 19, 2024

@cyberphone We just synconized with EWC 48hs ago and they are very much aligned to this proposal. We both sync regularly.

@mobinauten
Copy link

@cyberphone Merchandts verify age e.g., shipping adresses @cyberphone Why don't you join one of the parties in NOBID or EWC to contribute directly and get a very deep insight into the current software developments?
e.G in NOBID one of the main actors in REWE, a large retailer in Germany, having implemented the first versions of these approaches, so an experienced merchant is on board and provides hands-on experiences and developers.

@mobinauten
Copy link

And the the LSPs are part of the ATAG.

@mobinauten
Copy link

And it was from my perspective the wrong question at the SPRIND conference. This approach is not to compete against Apple, Google, Mastercard or Visa.
It should enable payment in an EUDIW in an open, standardized and scheme-agnostic way in order to combine payment and credentials/data in one app/transaction and to provide superb CX.
It's not about inventing the next scheme.
And maybe Google or Apple will develop an EUDIW as well, who knows? Or Visa? Then this approach should work as well.
ieIDAS2 is part of a bigger EU infrastructure picture and thus we don't need to ask the competition question, I believe.

Ideas how to proceed. Very clear.

  1. Continue work on LSP1
  2. Start work on LSP2s
  3. Synchronize with national developments like FUNKE in DE
  4. Synchronize with the EU and national and EU banking authorities

@senexi
Copy link
Author

senexi commented Dec 19, 2024

@cyberphone

According to https://github.com/nobid-consortium/payment-reference-documentation/blob/main/payment-reference-doc.md#security-considerations Merchants are TPPs that verify. Verify what?

As stated in the document: "verification of the P2Pay". In case you are asking what a P2Pay is... it is explained in the document.

These guys have another idea on how to use OpenID4VP: https://ewc-consortium.github.io/eudi-wallet-rfcs/payment-rfcs/implementation-guides/payment-authentication-sca-using-eudi-wallets.pdf#page=38

Seriously? Do you actually read these documents? Maybe you would notice that they are quite similar....

https://github.com/EWC-consortium/eudi-wallet-rfcs/blob/main/payment-rfcs/ewc-rfc008-payment-data-confirmation.md

But I would like to focus on the actual issue and proposal from @tlodderstedt here...

Regarding the metadata, I think it absolutely makes sense to move some of the claims from the credential to the PSP / Issuers metadata, as they are the same for every issued credential. Making the approach more flexible and reducing the static data within the credential. @stefan-kauhaus also pointed out that option.

@cyberphone
Copy link

@mobinauten

And it was from my perspective the wrong question at the SPRIND conference. This approach is not to compete against Apple, Google, Mastercard or Visa.

Personally, I don't see much point in developing a system that doesn't have these characteristics. The system I'm working with (entirely on my own and without any funding 😪), is explicitly designed for competitiveness.

Merchandts verify age e.g., shipping adresses

Yes, but this is unrelated to payments.

Why don't you join one of the parties in NOBID or EWC to contribute directly and get a very deep insight into the current software developments?

I believe I did but I got no response. Anyway, without clearly separating Merchants and TPPs, I wouldn't consider joining the party.

@c2bo
Copy link
Member

c2bo commented Dec 19, 2024

I think being explicit that this flow (whatever it will look like) is intended to be shown to / used with a third party would be a very good idea here -> +1 on the present_to_thirdparty proposal or something similar.

@cyberphone
Copy link

cyberphone commented Dec 20, 2024

@c2bo This is implicit in other payment authorization systems. Maybe the idea is that a single wallet implementation, should be able to handle everything from age-assertions to payments? This would IMO be a pretty bad idea.

My guess is that Apple have a common code-base for certain functions like crypto, but that the wallet dispatches requests to application-specific "executors".

Anyway, a unified flow seems pretty distant since we (apparently) have quite different ideas about what a Merchant is. In the depicted schemes, Merchants would either need to have contracts with all issuer banks or be accredited by an NCA (National Competent Agency) as an PSD2 entity. This obviously doesn't apply to the coffee shop on the corner. There is a reason to why companies like Adyen, Stripe, Worldline exists. They handle millions of Merchants and thousands of Banks.

There ARE ways to change this but this require a major architectural update. I'm currently not actively pushing this but it might be interesting to see anyway...

saturnflows li

The idea is quite simple: The Merchant's Bank maintains a Trust Service (TS) holding core Merchant data like name, public key, account, etc. With this, the User Bank can verify the authenticity of Merchant requests through simple lookups.

The Merchant data is in turn signed a by key+certificate belonging to a bank PKI. The very same PKI is also used for returning authoritative responses to Merchants that requests have been processed.

My take on the Wallet depends on trust services also in a more conventional setup. That is, the ARF doesn't apply.

This is not a theory: https://test.webpki.org/saturn-payeebank/

@cyberphone
Copy link

@tlodderstedt @senexi @mobinauten The bigger question (IMO...) is if we believe we are creating a standard for an EUDI Wallet with payment functionality. I don't think we are even close because we haven't yet concluded what our expectations are. Such a standard would also have to (in order to be "authoritative") be developed by a standards committee. OpenID does currently not have a "Payment Wallet WG".

Is this a problem? Yes, the lack of a real standard will undoubtedly stall large-scale deployments unless one of the initiatives will considered a clear winner.

Personally (FWIW), I have limited faith in Berlin Group's take on how to support payment wallets which caused me to develop an entirely different solution. Currently it is just "slideware", but I actually did a similar solution with a real bank back in 2019, and it worked pretty well. The main points with this concept are:

  • Reducing the need for centralized standardization of gazillions of APIs.
  • Permit third-parties creating application-specific APIs that (at least in theory), with moderate efforts would work in any number of banks.
  • Enabling competition by wallet designs.

https://github.com/cyberphone/open-banking-2.0

OB2

@stefan-kauhaus
Copy link

@senexi: To offer another perspective on the original topic: The KB JWT contains aud as required element. OID4VP says on this:

Note: The Key Binding JWT nonce claim contains the value of the nonce from the authorization request, and the aud claim contains the Client Identifier of the Verifier.

(https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#appendix-B.4.5-10)

In our scenario, the 'Verifier' would be the immediate RP the presents to, and the KB JWT will reach the 'ultimate verifier' as well.

So, the wallet already records who it is talking to and signs over this. Would this not be good enough as a solution (for now)?

@tlodderstedt
Copy link
Collaborator

tlodderstedt commented Jan 7, 2025

@cyberphone

@tlodderstedt @senexi @mobinauten The bigger question (IMO...) is if we believe we are creating a standard for an EUDI Wallet with payment functionality. I don't think we are even close because we haven't yet concluded what our expectations are. Such a standard would also have to (in order to be "authoritative") be developed by a standards committee. OpenID does currently not have a "Payment Wallet WG".

I don't suggest to standardize the use of wallets (or oid4vp) for payments at OIDF. I rather suggest to build the rails into oid4vp to enable use cases like payment authorization (and qes authorization). present_to_thirdparty is part of such a rail, which could go into oid4vp. The schemas for representing payment authorization should be done in a SDO competent in that field.

Having said that, we need concrete use cases here to be able to have a meaningful discussion. That's why it makes sense to use payments as example to drive the discussion.

@mobinauten
Copy link

Indeed, we should differentiate between the enabling infrastructure and the payment mean and architecture as well. Different layers.
The approach in NOBID and EWC and thus in OIDF could be/is already to creating the necessary rails/layers that then can be used by the different payment architectures. And these payment means and architectures then very likely will use other standards as well like from W3C or ISO or...
The EUDIW and OIDF are not, should not be Payment means with all their rulebooks like cards or A2A schemes.
It could powers these but are not.

@cyberphone
Copy link

cyberphone commented Jan 7, 2025

Maybe we could take a step back and define a place for the Merchant?

In my take on payment authorizations (which predates OpenID4VP with 8 years or so), the wallet is entirely unaware of rails and specific payment networks, it is just a fairly simple Merchant payment request-response scheme. There are no credential presentations or verifications either; with respect to the Merchant, the wallet response only provides core data needed for payment network and bank selection.

It is not clear to me what more specifically an SDO would do. Define the content of transaction_data? I hope not.

Current specifications also need to be tested before any meaningful standardization can be performed. We are probably talking 2030 before such a standard would be ready (and probably already obsolete).

VIP: https://cyberphone.github.io/wallet-core/doc/

@mobinauten
Copy link

@cyberphone We're testing these approaches since more than 12 months in LSPs NOBID and EWC. You should really join one of those a the coming ones to get deeper insights.
Cheers Olli
P.S SDO is what?

@cyberphone
Copy link

cyberphone commented Jan 8, 2025

We're testing these approaches since more than 12 months in LSPs NOBID and EWC.

Dear @mobinauten No one doubts that your stuff works. My questions are related to scalability and architecture.

You should really join one of those a the coming ones to get deeper insights.

At this stage I prefer sticking to the publicly available documents. I'm sort of a spec. nerd. 😆. EWC seems to also target 3D Secure, something I would never consider since it is already available, albeit (typically) through mobile banking applications.

SDO is short for Standards Development Organization.

FWIW, I have limited faith in Berlin group's Signed Payment Request. Their single-level "monster" API concept, makes development and testing a nightmare!

It is not very clear to me what mission SD-JWT could have in a payment authorization scheme.

Cheers Anders

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants