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

Allow asset issuers to require authorization per transaction #135

Closed
tomerweller opened this issue Jul 3, 2018 · 22 comments · Fixed by #154
Closed

Allow asset issuers to require authorization per transaction #135

tomerweller opened this issue Jul 3, 2018 · 22 comments · Fixed by #154
Labels
CAP Represents an issue that requires a CAP.

Comments

@tomerweller
Copy link
Contributor

tomerweller commented Jul 3, 2018

Motivation

There is a growing number of requirements, set by asset issuers and regulators, regarding assets and trust-lines. From velocity limits to minimal balances and weird fee structures. (Related issues: #101, #85, #71)

Introduction

Instead of supporting all of these different requirements, we could delegate this logic to an off-chain service.

Note: this is not a complete proposal. just a starting point for discussion.

I propose adding the ability to declare that an asset is TX_AUTHORIZATION_REQUIRED. Meaning that this asset requires the issuer's signature for every transaction involving the asset. The issuer will commit to providing a signing service, that signs compliant transactions and provides meaningful errors for non-compliant ones.

I propose two approaches for achieving this:

  • Approach 1 (preferred): combining a protocol change and an ecosystem proposal.
  • Approach 2: no protocol changes. only an ecosystem proposal + making the issuer a co-signer on accounts that hold their trustline.

Given that both approaches utilize a similar ecosystem proposal, and that protocol changes take time, we can start from 2 and then easily migrate to 1 if/when the protocol changes.

Approach 1

Protocol changes

  • Allow TX_AUTHORIZATION_REQUIRED flag on accounts.
  • Require issuer signature for every transaction involving an asset that has TX_AUTHORIZATION_REQUIRED

UPDATE: a possible outline for the protocol changes: #146

Ecosystem Proposal

  • Add a TX_AUTH_SERVER to asset issuer's TOML. This points to their off-chain signing service.
  • Add a TX_AUTH_REQUIREMENTS to asset issuer's TOML. This will outline which specific requirements the issuer is looking for in transactions. This can be a human readable string or a transaction template or a set of predefined requirements that wallets can comply with. (TBD)
  • Define the protocol for a signer service. Essentially, a simple HTTP service that receives transactions. It signs compliant ones and provides meaningful errors for non-compliant ones.

Approach 2

Without any changes to the protocol, the issuers can create accounts for their signers, in which they are a co signer (2/2 scheme). This allows the SEP from approach 1 to be used as is.
However, this presents some issues, to name a few:

  • The account will need issuer approval for transactions unrelated to the issuer (XLM transfers, etc.)
  • Having multiple trustlines for assets that require tx authorization will put us in a world of pain.
@nikhilsaraf
Copy link
Contributor

We may be able to leverage the allow_trust operation to support this behavior. This will reduce the additional complexity needed to manage shared accounts with the issuer (via multisig).

The user's account starts out with a requested trustline to the issuer's asset. The trustline is NOT authorized yet.


Each transaction sent to the TX_AUTH_SERVER should be formatted in the following manner:

  1. first operation is an allow_trust operation with the issuer as the operation's source account. This operation allows the user's account to trust the issuer's asset and will complete the trustline for this transaction.
  2. this will be the desired operation (manage offer, payment, etc.) with the user's account as the source account, i.e. without explicitly setting the source account for this operation.
  3. last operation is an allow_trust operation with the issuer as the operation's source account. This operation revokes the user's trustline for the issuer's asset. This leaves the trustline back to where it started in an unauthorized state.

The benefit of doing it this way is:

  1. don't need to create 1 new account per issuer, can keep all your funds in the same account since the issuer is not a signer on the user's account.
  2. if there are multiple assets in a single transaction then we can pass the same transaction around to each issuers for approval and have each of them sign it to make the transaction valid (each issuer will have 2 operations on which they are the source so they will be required to sign it to allow it to be processed successfully). this can also be done in parallel and the signatures collated by the user's wallet since signatures against a transaction are unordered.
  3. we still get the benefits of a per-transaction-approval by the issuer because the funds are LOCKED in the user's account and can only be transacted with once signed by the issuer.

@nikhilsaraf
Copy link
Contributor

for the TX_AUTH_REQUIREMENTS, we should specify explicit fields and conditions, such as amount < 50.0, daily_amount < 5000, asset=ABC:GASDKLJ...., etc.

this will allow programmatic access to the validation information by wallets while also making requirements explicit to users since these fields will be standardized across all issuers.

the TX_AUTH_REQUIREMENTS should still allow freeform requirements to account for requirements that are out of the ordinary. If there is a common pattern between these freeform requirements we can always include a standardized version of it to make the requirement easier to work with.

@tomerweller
Copy link
Contributor Author

Regarding the allow_trust sandwich approach. I really like it but unfortunately it breaks on making offers. Essentially it means that people put an order and immediately get the trust-line revoked, which makes offer un-fillable.

Regarding explicit conditions - Yes, for sure. These will be part of the SEP.

@stanford-scs
Copy link
Contributor

I guess it's worth thinking about what changes would be required to make the sandwich approach viable, vs TX_AUTH_REQUIRED. The sandwich approach might require re-thinking offers so that the funds really belong to the order book (and the issuer can then cancel any order involving that asset).

I suspect TX_AUTH_REQUIRED will be simpler, but we still might need a way for the issuer to cancel transactions.

My main concern with both proposals is that there is some risk that the asset issuer will accidentally do something they don't want to do. There's a bit of a confused deputy problem in that the co-signing issuers has more authority than just to allow the transaction (the issuer can, for example, create trust lines). It would be nice if the key or signature could somehow be limited to prevent it from doing anything with the issuing account. This isn't exactly a vulnerability per se, but it's an error prone situation that could lease issuers to create vulnerabilities.

Another issue is that it would be nice to have some way to bypass this for certain accounts, so some people need co-signing and people don't.

Both of my concerns could be addressed by, for instance, attaching signers to the trustline instead of just one bit. But this is obviously a very heavy-weight change, so this would need to solve a bunch of other problems, too, before we seriously consider it.

@tomerweller
Copy link
Contributor Author

@stanford-scs The sandwich approach can be complementary. In both cases, there's still a requirement for an external signer service. So the issuer can declare that they will only sign sandwiched transactions. However, it doesn't solve the ghost offer issues.

Regrading bypassing for some accounts. That's a good point. Do you think this should be a flag on a trustline?

@michaeldowling
Copy link

Hi :)

I'm a little late to this thread, but wanted to add my $0.02. This issue really does get complex as you dive into the nature of the asset being exchanged or represented on the DLT. As much as I completely, 100% agree that it would be cleaner to implement flexibility in the protocol for these regulatory requirements, my fear is that the work will never become complete, and what will be complete will be a very complex mess of a base DLT protocol.

We've been working around this by utilizing option 2 - multisig. Yes, this does help our organization ensure proper fee structures by ensuring a payment transaction includes a fee payment to a 2nd address where required, but it also allows us to do some "online transaction processing," as the FFIEC puts it. This is essentially the ability to analyze the TX against some pretty sophisticated models to find risks of the individual payment.

Its possible that transactions between 2 addresses generates significant risk. It's also possible to receive letters from the various regulators about specific persons or specific addresses which can contain specific rules such as "dont allow this address to receive funds exceeding $1,000 per day."

...and there are SO MANY MORE examples here.

Basically, and the devil is in the details here, but is boils down to this: the organization anchoring real-world assets (vs. pure-play cryptocurrency or cryptoassets) has to have "skin in the game" when it comes to transfer of value. Today, multisig with explicit trustlines (with the unfortunate side-effect of 1 account for that asset) works OK for us. (we also manage XLM balances on each account o.b.o. clients)

The ecosystem proposal looks logical to me. FYI, we're using the following protocol (described in OpenAPI) for our "signing service" (we call "TX Verification"):
https://gist.github.com/michaeldowling/12eb63d9c08d9e24c25238170b708ef1

During meetings with regulators this month, we agreed to workshop some of these rules with them when it comes to real-world financial assets in custody, so hopefully will have more requirements to contribute.

Would love to be actively involved in this issue :)

@tomerweller
Copy link
Contributor Author

Thanks @michaeldowling for the feedback and the API reference. It's especially important since this proposal will help facilitate the exact conversations you're having with the regulators.

I want to empathize that the only suggested protocol change in Approach 1 is that issuers can define an asset to require authorization per transaction. How they communicate their requirements and facilitate signing is left to the ecosystem part of the proposal (which is identical to approach 2) and the issuer.

Like I mentioned, the problem with Approach 2 is that the issuer has too much power over a user's account. Every operation needs to be authorized, even if it doesn't involve the issuer's asset.

The current solution you're forced to implement, which is adding your self as a signer without a clear way to communicate this to the ecosystem is what we need to fix.

@jedmccaleb jedmccaleb added the CAP Represents an issue that requires a CAP. label Aug 3, 2018
@tomerweller
Copy link
Contributor Author

@michaeldowling regarding your signer service:

  • Does it expect the transaction to already be signed by the user before they submit it for approval?
  • How do you ensure that your view of the account/ledger/asset is up to date given that you can have numerous pending transactions that have been signed but not submitted to the ledger yet?

We want to ensure that the issuer:

  1. Has a reliable consistent view of the world.
  2. Can provide input regarding the structure of the transactions (for example: denominating a fee in non-native asset, adding an upper-bound time limit to ensure 1, etc.)

After some discussion, the draft might include a two-step process:

  1. Tx Validation: The user sends an unsigned tx which the issuer will examine and potentially augment it to match some invariants. Validated tx is sent back to user, still unsigned.
  2. Tx Signing: The user sends a tx that has been validated (by step 1) and signed by the user. Issuer will check that the transaction is indeed valid and that user signature/s is valid. The issuer then signs and returns a fully signed, ready to be submitted tx.

Thoughts?

@tomerweller
Copy link
Contributor Author

Update on the protocol side: #146

@michaeldowling
Copy link

Hey @tomerweller - sorry for the late reply.

1: No, the service does NOT expect a signed transaction from the entity
2: There are several ways we do this in the backend, but I do want to make clear that the purpose of the signing service is to check, at that moment in time, whether the transaction is A) constructed appropriately for the assets being exchanged ("Tx Validation") and B) regulatory, fraud, and other proprietary checks are done per regulatory requirements; assuming all looks good within 500ms you get a signed transaction from us. At any time, the entity can sign and submit (to our, or another, stellar-core).

Our signing service's scope is limited to those two key activities. Whether the user submits the transaction for ledger close is up to them; I will mention that it's an obvious red flag for future signing requests if the same device requests signatures for TXs that end up not getting submitted.

BTW, to follow up, I totally misunderstood the design you presented above - quickly reading, I thought you were proposing a complex stellar-core to stellar-core orchestration protocol at first; now I see you're proposing an endorsement-submission protocol. There is interesting precedent for something like this - Hyperledger Fabric uses something kinda-sorta similar in concept:
http://hyperledger-fabric.readthedocs.io/en/latest/endorsement-policies.html

(I'm not advocating Fabric, to be clear ;) )

Your proposal seems like a much cleaner design to go alongside an asset-specific flag for multisig. Right now, as you noted above, the "side effect" of the multisig approach today is a one-asset-one-account setup. Not sure how this negatively effects the network as a whole - we're not seeing super negative UX as a result. We're basically hiding the fact that a DLT is even involved. But we can easily help test the asset flag without much change on our end.

<3

@tomerweller
Copy link
Contributor Author

tomerweller commented Aug 13, 2018

Thanks for the feedback @michaeldowling. Will update.

One potential issue with the way that you describe your implementation: you don't expect a signed transaction yet it can still raise a "red flag". This means that a malicious user can construct a transaction that uses my source account, submit it for approval and have my account flagged due to content and/or behavior. If that's indeed the case, it can easily be solved by only accepting signed transactions and verifying that signature before proceeding.

@michaeldowling
Copy link

Actually if a user attempts to use a source acccount not previously associated with their authenticated device, the service will simply decline to sign. It won’t specifically raise a flag. What WILL raise a flag is if an authenticated device requests signing for transactions with their source account without submitting them.

Several hundred checks occur during this signing request, with lots of factors involved in the decision.

@ScottHogge
Copy link

One issue that is unfortunately not solved here (or really addressed beyond the 'motivation') is the need to attach fee structures to trades (see my latest reply in #101), as those should be applied at the time of the trade, not at the time of the ManageOffer operation. In most cases an issuer will not want to attach the same (or any) fee to offers that are later canceled before they are matched, or are canceled after a partial match. In addition, things get much more complicated when trying to change an offer because of the need to know the current state of the offer (which could change after signing, or even after being polled by the signing service) in order to apply deltas to the fees.

@johansten
Copy link
Contributor

johansten commented Sep 20, 2018

Has anyone thought through how this will work with path payments?

I have a feeling it may cause great havoc.

  • All issuers within a path will have to inspect the trades affecting them, and they will all have to give their blessing. If the route of no-ops is taken, all additional no-ops have to be added before the final transaction can be signed, adding quite some communications overhead.

  • Path finding will be the same, but presenting it to the user will get more complicated, since some paths mights get stopped, and you get stuck with trying out all the paths for a pair of assets, until you find one that gets accepted.

As much as I love the platform, without path payments, Stellar is just a slightly above average shitcoin.

@tomerweller
Copy link
Contributor Author

Without the protocol change (#146) I wouldn't expect to see any trades that involve more than one regulated asset, path payments included. It's unrealistic to maintain accounts that have multiple issuers as co-signers.

If the protocol change does take place, I don't think that adding the no-ops and requesting approval from all the issuers is a massive overhead. As a wallet developer, are you concerned about the added ~2 HTTP requests per approval or the user experience associated with it? I agree that if every issuer starts modifying your transactions with weird operations and send you back a PENDING response while waking up a representative, than yeah it might turn problematic.

It's hard to say this right now but due to the nature of these assets (probably securities) I don't see them being used as bridge currencies.

Regarding finding paths, that's a good question. I'd say that a good enough solution for now is to completely ignore whether or not an asset is regulated and to tackle that only when the user actually attempts to make a transfer.

@sui77
Copy link
Contributor

sui77 commented Sep 26, 2018

Just a security consideration:
Since the approval service would be a fully automated exposed system in many cases, there is a chance of leaking the cosigners keys. In this case I definitely would prefer changing just one signer that is somehow related to the asset/issuer instead of replacing the cosigner in thousands and more user accounts each.

@tomerweller
Copy link
Contributor Author

@sui77 this is a good point. dm's suggested protocol change (#146) will allow for simple key rotation but the current multi-sig approach does not. Do you mind opening a new issue for this discussion?

@johansten
Copy link
Contributor

johansten commented Sep 28, 2018

Even with protocol changes, what kind of restrictions can an issuer make that they can't do already?

You probably would like to be able to restrict who you trade with, but then you'd have to intercept the order matching, and I don't see that ever happening.

So you're stuck with things you can do already; limiting how much an individual account can hold, and if they can move your asset at all -- which is already done better by trust line limits, and auth_required.

@johansten
Copy link
Contributor

And how does it jive with state channels? Anyone?

@johansten
Copy link
Contributor

johansten commented Sep 29, 2018

If the protocol change does take place, I don't think that adding the no-ops and requesting approval from all the issuers is a massive overhead. As a wallet developer, are you concerned about the added ~2 HTTP requests per approval or the user experience associated with it? I agree that if every issuer starts modifying your transactions with weird operations and send you back a PENDING response while waking up a representative, than yeah it might turn problematic.

I'm more concerned about the number of different code paths, special cases, and added overhead I have to add, with no benefit for me.

  • We already have assets w/ trade restrictions, and no simple way of checking if they can be transacted with, since trust line authorization status isn't exposed through Horizon.
  • Path payments are basically unusable right now, and will become even less usable with this change.
  • No way for accounts to flag that they require a memo, so wallet devs have to try to keep up with all new exchanges coming onboard.
  • Lightning coming up. I don't see how state channels can work with the regulated assets proposal, so as a wallet, we'd have to have separate paths for that too.

All in all, you're outsourcing all of this business logic complexity to software with very limited monetization paths.

@johansten
Copy link
Contributor

@tomerweller

And it's not two requests extra.

  • You need to get the issuer account info, and check for home_domain
  • Get the stellar.toml
  • Potentially get the signature for the stellar.toml, if we ever add that
  • Tx validation
  • Tx signing

None of this is needed as of now. The first ones would be needed for any asset, regulated or not.

@tomerweller
Copy link
Contributor Author

Thanks for the feedback @johansten, I'll comment on some of these things but given that the initial version of this sep has been merged, it's better to open new individual issues.

what kind of restrictions can an issuer make that they can't do already?

To name a few: velocity constraints, min/max account holders (a trustline that has a balance>0), min/max balances.

You probably would like to be able to restrict who you trade with, but then you'd have to intercept the order matching, and I don't see that ever happening.

The issuer can disallow any offers that, if fully filled, will violate a constraint.

I'm more concerned about the number of different code paths, special cases, and added overhead I have to add, with no benefit for me.

I hear you. We should ensure that the various sdks have high level support for identifying these assets and doing the approval dance. Would appreciate any help with specing that out.

We already have assets w/ trade restrictions, and no simple way of checking if they can be transacted with, since trust line authorization status isn't exposed through Horizon.

Less relevant here. It's one of the milestones for horizon 0.15.0.

No way for accounts to flag that they require a memo, so wallet devs have to try to keep up with all new exchanges coming onboard.

Again, less relevant. Ideally this should be solved by exchanges implementing federation.

All in all, you're outsourcing all of this business logic complexity to software with very limited monetization paths.

Sep8 indeed outsources complexity, mostly to the asset issuers. Yes, it also adds complexity to the wallets and, like i mentioned above, we should ensure that the sdks make wallet developers' lives easier.

And it's not two requests extra.

If a wallet wants to present a user with basic information about a currency, such as an icon and some information about the issuer, they'll need to perform a toml lookup anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CAP Represents an issue that requires a CAP.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants