interledger / rfcs

Specifications for Interledger and related protocols
https://interledger.org
Other
430 stars 106 forks source link

http-ilp design discussion #329

Closed michielbdejong closed 6 years ago

michielbdejong commented 6 years ago

in http-ilp, the client generates a Pay-Token, which needs to be sent as data on each payment, and which is unrelated to the shared secret.

It looks like the token is added as data in the ILP packet unencrypted? Isn't that insecure? Also, can't we do something smarter, like deriving the Pay-Token from the shared secret?

michielbdejong commented 6 years ago

cc @sharafian @adrianhopebailie

michielbdejong commented 6 years ago

also cc @justmoon

sharafian commented 6 years ago

The Pay-Token is carried in the encrypted PSK data (1). We could theoretically have a client implementation that derives the Pay-Token from the shared secret, but I don't think we need to make it part of the standard. Leaving the token generation strategy up to the client lets you have persistent tokens, or tokens shared across several client instances.

(1) https://github.com/justmoon/koa-ilp/blob/master/index.js#L32

michielbdejong commented 6 years ago

Right. I see two downsides to what you propose: 1) it's more complicated 2) leaving the token choice to the client means the shop will probably get a lot of requests from attackers trying out if tokens like '123456', 'asdf', 'changeme', and 'seeecret' have any balance, and then have to deal with compliants from customers who used a buggy client and then blame the shop saying "my credit was stolen!".

OTOH, I see your point that if you use multiple devices, and you previously synced some client-side secret (e.g. an ssh keypair) between them, it's pretty cool that you can put credit "on your ssh key", and then use that credit from another device, even if the device from where you paid and the device from where you're consuming are currently not connected to the internet. I mean, they would both have to be connected to the internet in order to do the paying and the consuming, but they don't need to know about each other's existence, as long as you configured them in tandem. Admitted, it feels like an obscure use case that will probably not impact usability very much, but I agree it does feel like a cool feature for geeks. :)

It does make me think though, if the client already generates this Pay-Token and sends it to the shop, then that's already a shared secret, right? Is it ok if the shop uses that exact token as the shared secret for PSK, or is there a downside to that?

michielbdejong commented 6 years ago

I guess if you use the Pay-Token as the PSK shared secret, you should not encrypt the Pay-Token in a PSK header, but that also makes me think it would be easier if the shop just adds a clientId to the end of the destinationAddress? This clientId can then still be derived deterministically from the Pay-Token, but then at least the client doesn't have to do complicated crypto things to generate the right payment packet.

michielbdejong commented 6 years ago

Merged 4 tickets into one. :) Basically, I think http-ilp as it's currently implemented in koa-ilp and superagent-ilp is still too complex in a few ways:

emschwartz commented 6 years ago

double round trip should not be a requirement (it's easier if the http request stays open, and the body is streamed as soon as the payment has happened)

@michielbdejong is this your idea about sending the Pay header back before the rest of the HTTP response? If so, would there be a performance gain of that versus using HTTP Keep-Alive or HTTP2?

shops want to offer a prepaid balance feature then they can just run five-bells-ledger or some form of plugin-virtual for that.

That doesn't sound like it solves the problem though. I hear you that it's kind of strange to have the webserver storing a balance for you, but how would you then indicate to the server that you're paying from your account on their ledger? You don't really want to send payments to them, you just want them to draw down against that balance.

necessity of having Pay-Token / Pay-Balance is not clear; the fulfillment of an exact payment could act as the token for retrieving the resource, and if shops want to offer a prepaid balance feature then they can just run five-bells-ledger or some form of plugin-virtual for that.

Seems like the main questions here are:

  1. What are the main use cases we are designing this for? Is it for one-off interactions where you know the exact price up front or is it for streaming / repeated interactions? Are you paying for each HTTP request/response or are you paying for a couple at a time?
  2. How fast are the payments expected to be?

Regarding "the fulfillment of an exact payment could act as the token for retrieving the resource", that kind of sounds like the Bitcoin UTXO model. The server would need to remember all of the fulfillments they've given out and which ones have already been used, as opposed to remembering which account has what balance now. I think the account-based model would require the server to remember less.

I think we should just always let the shop pick the shared secret at will when it presents its Pay header

Definitely agree with this.

instead of requiring the client to encrypt its client identity into a psk header, a much simpler solution to identifying which payment is for which client

Is that really so complicated?

if the shop just presents a destinationAddress that is unique per client (for streaming)

How do you correlate different requests from the same client? Would that be based on source IP? If the sender presents their token for each request, there's no ambiguity about which balance the server should be drawing down against.

the Pay header should adhere to https://tools.ietf.org/html/draft-hope-bailie-http-payments-00#section-4.1 (i.e., start with 'Pay: interledger-psk ')

👍

michielbdejong commented 6 years ago

The server would need to remember all of the fulfillments they've given out and which ones have already been used, as opposed to remembering which account has what balance now. I think the account-based model would require the server to remember less.

Remembering fulfillments only requires more memory if one users first pays for hundreds of resources and then consumes them all later. If a single user makes a single payment, the amount of state caused by that is the same, whether you retrieve using a token or a fulfillment.

Is that really so complicated?

Yes. It's a complex cryptographical operation that (as far as I can tell) is useless. We have to apply the French Revolution here :)

How do you correlate different requests from the same client? Would that be based on source IP?

Even if you make two http requests from the same computer, they would not be correlated. In the one-off case, you would get two different 402 responses. In the streaming case you would get two different Pay headers. You pay one, that one produces content. Pay the other, and the other one does.

If the sender presents their token for each request, there's no ambiguity about which balance the server should be drawing down against.

In the streaming case this is not needed; when you pay, the content stream immediately starts flowing without you having to do anything else.

In the one-off case, instead of presenting your token, you present the fulfillment which is your proof of payment to retrieve the content.

sharafian commented 6 years ago

Yes. It's a complex cryptographical operation that (as far as I can tell) is useless. We have to apply the French Revolution here :)

I think the current version is actually very simple because it builds on existing application protocols that need to be implemented anyways. It's more implementation to build a second application protocol with fewer features than it is to just use the one we have

adrianhopebailie commented 6 years ago

I think we can compromise on a lot of these points of contention.

There are a lot of different use cases and I don't think we are at risk of overcomplicating things by having a few options available for performing these payments.

As an example, we can define the purpose of the Pay-Token and Pay-Balance headers but that doesn't mean everyone has to use them. Some people may wish to just use HTTP sessions

michielbdejong commented 6 years ago

I think the current version is actually very simple

Simple for a developer who includes the code from the ilp module, or simple for someone who tries to understand how the protocol works?

Can we change the data in the ilp packet to implement this without relying on the prepackaged implementation of PSK? If it's indeed simple then I'm ok with it. We should also explain in the tutorial why we are doing this, and why it's better than just leaving the packet.data as ''.

sharafian commented 6 years ago

Simple for a developer who includes the code from the ilp module, or simple for someone who tries to understand how the protocol works?

Yeah, if you're starting from scratch learning Interledger then it's complicated to dive right into HTTP-ILP+PSK. But if you're familiar with what PSK is, it's a very small step to understand HTTP-ILP; it's just a flow for transmitting PSK parameters in an HTTP response.

Personally, I think it's most important that we make things work really well in the first case: the developer using our tools. Once we've written protocols and tools that work really well we can worry about explaining them.

What we want to avoid is shuffling around our protocols and causing breaking changes and version bumps that a developer on our stack has to worry about. I really want to be able to tell people at our workshops that our tools are ready and they can start building on them today. If we're still talking about breaking HTTP-ILP, which all our developer tools use, people won't use them. So that's why I don't want to make breaking changes to HTTP-ILP at this point.

adrianhopebailie commented 6 years ago

Yeah, if you're starting from scratch learning Interledger then it's complicated to dive right into HTTP-ILP+PSK

I think we need a really easy to understand PSK explainer or maybe a better explanation of Transport Protocols (I hate that name!)

michielbdejong commented 6 years ago

Once we've written protocols and tools that work really well we can worry about explaining them.

That contradicts Stefan's "simplicity (the simplest protocol will win)" slide, and Evan's "it's done when there's nothing left to take away" motto.

Also, I don't remember if we discussed this before, but what is the benefit of your more complex proposal over what is implemented now in https://interledger.org/tutorials/http-ilp/?

I don't want to make breaking changes to HTTP-ILP at this point.

From my perspective, HTTP-ILP doesn't exist yet - we can't really call something a breaking change if there's no consensus yet about the first version? All we have is four contradicting proposals: tutorial, code, RFC, and Internet draft.

dappelt commented 6 years ago

If we're still talking about breaking HTTP-ILP, which all our developer tools use, people won't use them.

@sharafian Out of curiosity, what are the developer tools you are referring to?

michielbdejong commented 6 years ago

I think mainly https://github.com/justmoon/koa-ilp, https://github.com/justmoon/superagent-ilp, and https://github.com/interledgerjs/ilp-curl. They have not been used by many people yet, but they were used for the demos that were presented at the SF workshop.

sharafian commented 6 years ago

That contradicts Stefan's "simplicity (the simplest protocol will win)" slide, and Evan's "it's done when there's nothing left to take away" motto.

PSK is a protocol on top of ILP. Because it's application layer (or transport layer) it can be upgraded without splitting the network. New tools can be created to use a different protocol, I just think we should keep the ones we've already had intact.

PSK also has many different features that we decided we wanted. If we wipe that clean and start from scratch, we may find ourselves having to reintroduce many of the features we took away.

Also, I don't remember if we discussed this before, but what is the benefit of your more complex proposal over what is implemented now in https://interledger.org/tutorials/http-ilp/?

That link is pointing to the HTTP-ILP flow I am advocating for, but I assume you mean the mid-request payment flow.

One advantage to current HTTP-ILP is use of PSK, so it doesn't have to redefine the transport layer. Another is that by separating the flow of the payment from the flow of the request, you can fund many requests at once, or pay in a streaming fashion while making requests simultaneously.

I think there are valid use cases for your mid-request payment flow too, but I also think that any changes should be introduced non-breakingly at this point. And in general it requires lower-level integration with interledger and lower-level integration with HTTP, making it harder to practically use.

They have not been used by many people yet, but they were used for the demos that were presented at the SF workshop.

One goal of our workshops is to inspire people to use Interledger in their projects. If people think we're going to be breaking them they won't want to build anything with them until those changes are all complete.

adrianhopebailie commented 6 years ago

Personally I'm not crazy about PSK's current design but mostly that's with regard to the envelope format. I had always assumed it was a POC but we've started to include it into a lot of stuff that makes it hard to change now.

That said, I think if we changed it by just changing the libraries that would mean we don't break much.

I'd love to make PSK a little less opinionated on the serialization and envelope format for example.

sappenin commented 6 years ago

@adrianhopebailie Interesting comments about the current design of PSK - can you elaborate more? My opinion is that now is the time to update PSK if we think there should be changes (though possibly discuss in another issue?)

adrianhopebailie commented 6 years ago

can you elaborate more?

I don't understand why we are inventing a new envelope format. It's just another piece of custom code that is a dependency of an ILP application.

This data is application layer data, we should just define an envelope data schema in JSON. Then we can use existing tools.

Even better would be to use a standard like JWE for the data.

michielbdejong commented 6 years ago

oops

michielbdejong commented 6 years ago

@adrianhopebailie were you involved in writing https://www.w3.org/TR/webpayments-http-api/? Is it compatible with https://tools.ietf.org/html/draft-hope-bailie-http-payments-00#section-4.1?

adrianhopebailie commented 6 years ago

@adrianhopebailie were you involved in writing https://www.w3.org/TR/webpayments-http-api/?

Not directly

Is it compatible with https://tools.ietf.org/html/draft-hope-bailie-http-payments-00#section-4.1?

No. https://www.w3.org/TR/webpayments-http-api/ is being dropped by the WG. We voted on this in yesterday's meeting.

The plan is to adapt https://www.w3.org/TR/webpayments-http-messages/ to be a generic logical data model description of the data passed into the PaymentRequest API. This would then form the basis of new bindings like an HTTP binding as described in https://tools.ietf.org/html/draft-hope-bailie-http-payments-00

stale[bot] commented 6 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. \n\n If this issue is important, please feel free to bring it up on the next Interledger Community Group Call or in the Gitter chat.