bsips/bsip-0040.md

423 lines
25 KiB
Markdown
Raw Permalink Normal View History

2018-07-25 11:19:23 +00:00
BSIP: 0040
Title: Custom active permissions
Authors:
2018-08-03 06:14:16 +00:00
Stefan Schießl <https://github.com/sschiessl-bcp>
2018-08-05 15:39:39 +00:00
Contributors and Reviewers:
2018-07-25 12:11:50 +00:00
Alex Megalokonomos <https://github.com/clockworkgr>
2018-07-25 11:19:23 +00:00
Fabian Schuh <https://github.com/xeroc>
2018-08-03 06:14:16 +00:00
Abit <https://github.com/abitmore>
Peter Conrad <https://github.com/pmconrad>
2018-07-25 11:19:23 +00:00
Status: Draft
Type: Protocol
Created: 2018-07-25
Discussion: https://github.com/bitshares/bitshares-core/issues/1061
Worker: <Id of worker proposal>
# Abstract
2018-07-27 11:14:48 +00:00
Strengthening user security is one of the main factors to elevate BitShares. In light of recent
2018-07-25 11:19:23 +00:00
hacking and phishing attempts this becomes even more important. The need for a more sophisticated
account security preceeded the idea for a finer-grained control of account permissions.
We propose to add an additional authority to the account, called Custom Active (Permission). The
permission contains a list of operationid-to-authority mappings that each grant access to the respective
operation as if it were the active permission of the account. Additionally, the arguments of said operation
can be restricted.
2018-08-10 05:27:42 +00:00
For the non-technical reader the section Specification can be skipped.
2018-07-25 11:35:17 +00:00
# Motivation
2018-07-25 11:19:23 +00:00
Any successfull hacking or phishing attempt on any of the web wallets that are powered by the
BitShares Blockchain is bad publicity. The user needs to be educated in account security, and this BSIP
2018-07-28 13:56:49 +00:00
aims to ensure all technical possibilities are met while being flexible to allow many use-cases.
2018-07-25 11:19:23 +00:00
2018-08-02 19:55:41 +00:00
With this BSIP any user can create additional keys with specific purpose (everything else is prohibited). We list some possibilities below:
2018-07-25 11:19:23 +00:00
- Witness Key: Only allows update signing key and publish price feed
- Trading Key: Only allows limit orders (arguments restricted to desired markets), update margin position and transfers (arguments restricted to certain accounts)
- Proposal Update Key: Approve proposals (2FA comes to mind)
2018-07-25 11:34:40 +00:00
- Faucet Key: Allow only to create accounts
- Withdrawal Key: Allow another account to transfer funds to himself
- Cold Storage Key: Only allow to move funds to the Hot Wallet
2018-07-25 11:19:23 +00:00
The above list of named keys is nothing that is known to the backend as the backend should have an abstract implementation.
2018-07-27 11:14:48 +00:00
The UI could provide a button "Create Trading Key" that properly configures the respective custom active permission entry.
2018-07-25 11:19:23 +00:00
2018-08-02 19:55:41 +00:00
Note: The user can still use the active authority just like used to, no change in existing behavior. The named keys only give an additional possibility. For example: The user can login the UI using the private key of such a named key. Then he only as access to the operations that this named key grants. He can still login with the existing password to gain full access (similar a local wallet can be created that only contains the named key).
2018-08-10 11:55:17 +00:00
This BSIP will be split into parts that will be voted on separately (see Milestones section). All of the above keys are possible with Milestone 1. Milestone 2 allows stateful restrictions (e.g. allow market orders up to some amount for every month), Milestone 3 gives finer control of how to combine restrictions and Milestone 4 allows to set a number of allowed executions per authority (introduces an additional on-chain dependency). Milestone 2, 3 and 4 will be put up for voting if Milestone 1 proves successful.
2018-07-30 13:24:31 +00:00
2018-08-13 11:00:04 +00:00
# Rationale
2018-07-25 11:19:23 +00:00
2018-08-08 14:48:25 +00:00
Custom active permission is a list of `custom active authorities`. A `custom active authority` contains an `operation_id`,
2018-08-10 11:53:57 +00:00
an `authority` (just like with active permission) and `restrictions` than can be used to restrict arguments.
Furthermore, such a `custom active authority` is only valid in a specified time period (`valid_from` and `valid_to`).
When handling incoming signed transactions, the backend checks
2018-08-08 14:48:25 +00:00
for each operation if there is a `custom active authority` for any of its required accounts. Check for every required
account of the transaction if all its belonging operations have at least one positively matched `custom active authority`
(see Specifications for definition of "matching"), and if so behave as if the active authority of the corresponding account is present (recursive authorities are excluded, see Examples).
2018-07-25 12:11:03 +00:00
2018-07-28 13:43:41 +00:00
# Specification
2018-07-28 22:01:37 +00:00
All descriptions in this section are on a pseudo/prosa level and no recommendation how it can best be implemented or serialized. They are meant to facilitate the understanding. If anything in the looping process or order of evaluation is unsuitable for actual implementation, changes can be made accordingly as long the same functionality is achieved.
2018-07-28 13:43:41 +00:00
2018-08-10 12:08:02 +00:00
Note: The impact of Milestone 4 is explained in its own subsection to not hinder the reading flow
2018-07-28 13:43:41 +00:00
### Custom active permission and custom active authority
2018-07-27 13:54:30 +00:00
2018-07-30 13:00:51 +00:00
A `custom active permission` contains a list of `custom active authorities` and looks like follows (in JSON-like/pseudo for clarification):
2018-07-25 12:11:03 +00:00
```
custom_active_permission = {
account_id, // account that is assigned to this permission
2018-07-30 13:00:51 +00:00
authorities = list of custom_active_authority objects
}
2018-07-25 12:11:03 +00:00
custom_active_authority = {
2018-08-10 11:53:57 +00:00
enabled, // status of this authority, true or false. true when created
valid_from, // timestamp when this is active
valid_to, // timestamp when this is invalid
operation_id, // operation id of the target operation,
authority, // same as for the existing authotities (multisig with weighted accounts or keys),
restrictions // see below
2018-07-25 12:11:03 +00:00
}
```
Note: This assumes `custom_active_permission` is stored in a separate index. Actual implementation details left to the implementer, as long as every `custom_active_permission` can be assigned to exactly one account.
2018-07-30 13:00:51 +00:00
A `custom active authority` is matched against operations of an incoming, signed transaction. The wording *matching* refers to:
- `operation_id` is equal to the id of the incoming operation
- `account_id` is in the required accounts of the operation
- the `authority` of the `custom_active_authority` is given by the signatures of the transaction
2018-07-30 13:00:51 +00:00
- timestamp `now` is within `valid_to` and `valid_from`
- all `restrictions` assert positively
2018-07-30 13:00:51 +00:00
### Restrictions
2018-07-27 13:54:30 +00:00
2018-07-30 13:00:51 +00:00
The `restrictions` field is a list of restrictions consisting of argument to assert mappings.
2018-07-30 12:39:45 +00:00
A dictionary-type object like
```
2018-07-30 13:00:51 +00:00
restriction = {
2018-07-30 12:39:45 +00:00
function, // argument_identifier
2018-07-30 14:16:18 +00:00
argument, // pointer to a dynamic value (argument of the operation, or attribute when nested)
2018-07-30 12:39:45 +00:00
data, // data specific to the function
}
```
2018-07-30 13:00:51 +00:00
is called a restriction, that can assert itself positively (passed) or negatively (violated). All restrictions are evaluated per default with `AND` logic to determine if the whole list has asserted positively.
2018-07-30 12:39:45 +00:00
2018-07-30 13:00:51 +00:00
List of possible restrictions are:
| function | data | state |
| ------------- |:-------------:| -----:|
| `any` | [`list`, `of`, `allowed`, `values`] | stateless |
2018-07-28 21:31:57 +00:00
| `none` | [`none`, `of`, `these`, `values`] | stateless |
2018-08-10 04:56:05 +00:00
| `lt, le, gt, ge, eq, neq` | `comparative` | stateless |
| `contains_all, contains_none` | [`list`, `of`, `values`] | stateless |
2018-07-27 13:54:30 +00:00
| `limit` | [`max_cumsum`, `interval_in_sec`] | [`current_cumsum`, `interval_began`] |
| `limit_monthly` | [`max_cumsum`, `interval_in_months`] | [`current_cumsum`, `interval_began`] |
2018-07-30 06:54:41 +00:00
| `attribute_assert` | list of restrictions | stateless |
2018-07-30 14:16:18 +00:00
| `logical_or` | list of restrictions lists | stateless |
Following cases must hold for a restriction:
2018-08-03 05:58:30 +00:00
- when the `custom_active_authority` is installed, the basic argument types (without nesting) are checked, and installing denying if not matching
2018-08-02 14:37:31 +00:00
- if there is no value given (e.g. an optional argument, or nested value not given), the restrictions is passed (even if the underlying operation understands the absence of a key as instructions to delete it on-chain, see bitshares/bitshares-core#838)
2018-08-03 05:58:30 +00:00
- if the expected type of the argument does not match the given type (no implicit type conversion), the restriction is violated (needed for nested `attribute_assert`)
2018-07-30 13:00:51 +00:00
- if the function of the restriction asserts negatively, the restriction is violated
2018-07-27 13:54:30 +00:00
Note:
- If required a field can be added that stores the assumed type of the argument
- This list of restrictions may be redefined to improve clarity, performance or to reduce complexity of implementation while maintaining the intended functionality
2018-07-27 13:54:30 +00:00
2018-07-30 13:00:51 +00:00
In the following we list possible `restriction`s. Mentioning `argument value` in the text below refers to the value of
the argument of the operation specified by `argument` of a restriction.
2018-07-28 21:31:57 +00:00
2018-07-27 13:54:30 +00:00
#### `any`
Stateless assert, all argument types. `Argument value` must be equal to one of values in the data list.
Note
- If beneficial for performance or complexity an additional operator `equal` can be implemented that only compares to one.
2018-07-28 21:31:57 +00:00
#### `none`
Stateless assert, all argument types. `Argument value` must NOT be equal to any of the values in the list.
Note
- If beneficial for performance or complexity an additional operator `not_equal` can be implemented that only compares to one.
2018-07-27 13:54:30 +00:00
2018-08-10 04:56:05 +00:00
#### `lt, le, gt, ge, eq, neq`
2018-08-02 14:37:31 +00:00
Stateless assert. Allows explicit type conversion:
- `int` type: use as is
2018-07-30 10:41:56 +00:00
- `string` type: use `length` of string as `argument value`
2018-08-09 09:09:37 +00:00
- `object` type: use `size` of object as `argument value`
- `list` type: use `length` of the list as `argument value`
The different asserts read as:
2018-07-28 21:43:28 +00:00
- `lt`: `Argument value` must be less than `comparative`
- `le`: `Argument value` must be less than or equal to `comparative`
- `gt`: `Argument value` must be greater than `comparative`
- `ge`: `Argument value` must be greater than or equal to `comparative`
2018-08-09 09:09:37 +00:00
- `eq`: `Argument value` must equal to `comparative`
- `neq`: `Argument value` must NOT be equal to `comparative`
Note
- `eq` and `neq` are implicit number comparators and not to be mistaken by a strict left must equal right operator, just like `lt, le, gt, ge` (for example, comparing `1 > list object` would have no sense)
- If beneficial for performance or complexity the implicit type conversions can be removed and distinct operators introduced that do not have implicit type conversions
2018-07-27 13:54:30 +00:00
#### `contains_all, contains_none`
2018-08-09 09:19:19 +00:00
Stateless assert, for `list` type arguments.
- `contains_all`: The `argument value` must contain all items specified by `data`, but can contain more
- `contains_none`: The `argument value` must NOT contain any of the items specified by `data`, but can contain others
2018-08-09 09:19:19 +00:00
2018-07-27 13:54:30 +00:00
#### `limit`
2018-08-02 14:37:31 +00:00
Stateful assert, only `int` type arguments. When the authority is created, `interval_began` is set to `valid_from` from its custom active authority and `max_cumsum` to `0`. Incoming operations are first tried to match all stateless asserts,
and if all passes continue with stateful asserts. If `now > interval_began + interval_in_sec`, then set `max_cumsum = 0` and set `interval_began = now`.
2018-07-30 13:00:51 +00:00
The assert that needs to pass is now `current_cumsum + incoming value <= max_cumsum`. If all `asserts` of this `custom_active_authority` pass, update `current_cumsum = current_cumsum + incoming value`.
2018-07-27 12:52:29 +00:00
2018-07-27 13:54:30 +00:00
#### `limit_monthly`
2018-08-02 14:41:11 +00:00
Stateful assert, only `int` type arguments. Analogue to `limit`, but `interval_began` is initially set to `month(valid_from)` and set to `month(now)` on update, additionally the time assert is `month(now) >= interval_began + interval_in_months` (include logic for month overflow when year changes). The `month(now)` call assumes zulu time to calculate month number.
#### `attribute_assert`
2018-07-30 13:00:51 +00:00
Stateless assert, only for dictionary type objects. The data list contains restrictions that all must pass, the reference for the `argument` of the child restriction is nested into the attributes of the parent dictionary type object. Allows nesting of `attribute_assert`.
2018-07-30 13:29:19 +00:00
#### `logical_or`
Stateless assert, only for dictionary type objects. The data is a list of restrictions lists, i.e.
2018-07-30 14:16:18 +00:00
`data = [ [restriction 1, restriction 2], [restriction 3, restriction 4], ... ]`. If one of the restrictions sub-lists in data passes as whole, this restriction passes. In above miniexample that would mean if `restriction 1` and `restriction 2` pass, the whole `logical_or` restriction is considered to be passed as well.
2018-07-30 12:39:45 +00:00
2018-07-30 13:35:12 +00:00
### Outline of handling incoming transactions
When a signed transaction arrives and before the backend evaluates if all necessary authorities are present through the signatures, do the following:
- iterate over `required accounts`
2018-08-03 06:26:15 +00:00
- iterate over all `operations` (child operations of proposal are not included) within the transactions that require the active authority of this account
- iterate the `custom_active_authorities` of this account, and if it matches, remember that and continue with next `operation`
2018-08-10 12:07:07 +00:00
- if a `custom active authority` match was found for every operation in the loop, behave as if the `active authority` of this account is present for the corresponding operations.
2018-07-30 13:35:12 +00:00
Note:
2018-08-09 08:44:26 +00:00
- A `custom_active_authority` can only grant the `active authority` of the required account of the corresponding operation, nothing more
- The actual active authority of a required account can still be given as before, existing behavior is not to be changed
- This for illustration, not actual implementation instructions
2018-07-30 13:35:12 +00:00
2018-07-30 13:38:47 +00:00
### Modification to the backend
2018-07-30 13:35:12 +00:00
2018-07-30 13:38:47 +00:00
* Add a new index or extend the account object to store custom active permission are assigned to an account and contain a list of custom active authorities. Multiple custom active authority entries are possible for one operation
* Provide operations: `install_custom_active_authority`, `update_custom_active_authority`, `delete_custom_active_authority` to allow changing the custom active permission (3 operation to allow custom transaction fees and avoid having to send the complete list of all authorities for every update)
2018-08-03 05:58:30 +00:00
* If the active authority of the account is updated, all custom active authorities are disabled and must be manually specified / re-enabled. User can either
1. keep the authorities enabled by specifying them in a list of `custom_active_authorities` in `extensions` of `account_update_operation`
2. enable them again afterwards by using `update_custom_active_authority`
2018-07-30 13:38:47 +00:00
* Operation-specific authorities (if present) must be evaluated in incoming transactions
2018-08-03 05:58:30 +00:00
* Remove expired custom_active_authorities on maintenance if they are expired for longer than one month
2018-07-30 13:38:47 +00:00
* Additional committee parameters may be needed to limit the extend of usage of this feature
2018-07-30 13:35:12 +00:00
2018-07-30 13:38:47 +00:00
Notes: The implementation must not differentiate on which operation the custom active authority is applied, all operations are treated in same fashion
2018-07-30 13:35:12 +00:00
2018-08-10 12:07:07 +00:00
### Milestone 4: Number of executions
If Milestone 4 is implemented, a `custom active authority` receives an additional field `remaining_executions` to
specify the allowed number of executions.
The user can choose to restrict the valid time period and/or the number of executions, but the number of executions can only
be unlimited (not set) if a time period is specified. A `custom active authority` then matches if the time period is
valid or not set, and `remaining_executions` is either not set or > 0. When a `custom active authority` successfully grants
the active authority for the corresponding operation and the whole transaction is executed, `remaining_executions` is
decreased by one. If it becomes zero, the `custom active authority` becomes disabled.
If the `custom active authority` does not get replenished by the user within one month, it will be deleted.
2018-08-10 05:26:10 +00:00
# Economics
Adding a custom active authority means increased effort for the backend, and with a stateful one also the need for more storage. Proposed transaction fees:
- `install_custom_active_authority`: Normal accounts can only create custom active authoritites with a duration of maximum 1 year, LTM can do any duration. Two options come to mind:
- A fixed high fee independent of authorities content
2018-08-12 18:45:24 +00:00
- Tied to the duration and complexity of the custom active authority. Transaction fee is then `fee = flat_fee + basic_fee * duration` where `basic_fee` is calculated according to complexity (e.g. size of authority, number of restrictions and etc.). The period `duration` refers to the time that is still left, not the set duration
2018-08-10 05:26:10 +00:00
(i.e. `date_to - max(now, date_from)`)
2018-08-10 20:42:02 +00:00
- `update_custom_active_authority`: Base fee similar to `account_update` plus dynamic one for any duration increase, no payback if duration in decreased (increase/decrease is evaluated on both interval ends separately)
2018-08-10 05:26:10 +00:00
- `delete_custom_active_authority`: Cheap similar to `limit_order_cancel`
This logic forces the user to think about the desired duration and enforces to put it rather too short than too long.
If a custom active is expired, or considered to be too short, extending it is easily doable.
After expired, the custom active becomes disabled and can still be enabled again with a new period, paying the fee for that new period.
2018-08-12 18:45:24 +00:00
Note:
- For Milestone 4 the install fee would be dependent on the number of executions if no time period is set.
2018-08-10 12:07:07 +00:00
2018-07-30 13:35:12 +00:00
# Discussion
To be found in the [issue](https://github.com/bitshares/bitshares-core/issues/1061) and [pull request](https://github.com/bitshares/bsips/pull/86).
# Examples
These examples are for illustration and no specification of actual serialization.
#### Example: Nested arguments like `options`
Assume `asset_update_operation`. All attributes of its `options` must be filled on update call. This assert can not be used to realize a "may only change attribute xzy of `options`". This would require that the logic knows which of the arguments are reflected on-chain and it knows how to query it for every operation that contains `options`. If `options` are to be restricted with this assert, all values that should not change would need be fixated by defining an `any` assert for those attributes, while having e.g. a `lt` assert for the one attribute that is allowed to change.
2018-07-28 21:38:48 +00:00
2018-07-28 22:18:01 +00:00
#### Example: Simple transfer
2018-07-30 13:35:12 +00:00
Assume account A and B and some unrelated key K.
The custom active authority should be put such that a transfer transaction sending funds away from A can be signed with key K, as long as the receiver is B. More concrete, the authority would look like
2018-07-25 11:34:40 +00:00
```
custom active authority = {
valid_from: 7.7.2018 00:00
valid_to: 8.7.2018 00:00
2018-07-30 13:00:51 +00:00
operation_id: transfer,
2018-07-25 11:50:14 +00:00
authority: {
threshold: 1
2018-07-30 13:18:43 +00:00
key_auth: [key K, 1]
2018-07-25 11:50:14 +00:00
account_auth: []
},
2018-07-30 13:18:43 +00:00
restrictions: [
2018-07-30 12:39:45 +00:00
{
function: any,
2018-07-30 12:39:45 +00:00
argument: to,
2018-07-30 13:18:43 +00:00
data: [account B]
2018-07-30 12:39:45 +00:00
} // this restricts the argument identified with "to"
]
2018-07-25 11:34:40 +00:00
}
```
Exemplatory outcomes:
- Transfer asset X with amount Y from account A to account B, signed with Key K: Accepted
- Transfer asset X with amount Y from account B to account A, signed with Key K: Denied
- Transfer asset X with amount Y from account A to account C, signed with Key K: Denied
- Transfer asset X with amount Y from account A to account B, signed with active authority of B: Denied
- Transfer asset X with amount Y from account A to account B, signed with active authority of A: Accepted
2018-08-07 20:34:03 +00:00
- Create a proposal that includes operation 'transfer asset X with amount Y from account A to account B, signed with Key K: Accepted. Anyone can create a proposal.
Note:
- This is included with the first Milestone
- Normal permission logic is not altered. Account A can still sign the a transfer from account A to account B with its active authority
2018-07-25 11:19:23 +00:00
2018-08-07 20:34:03 +00:00
#### Involving multi-sig
Account A has multi-sig active authority of account B and C. Account A has a custom active authority that grants key K transfer priviliges (any asset to any account). Account B has a custom active authority that grants key L transfer priviliges (any asset to any account).
The transaction contains a transfer from A to account D. Required active authority of this operation is A.
- Signed by B and C: Accepted
- Signed by L and C: Denied. The custom active authority of B does not match, only applies for transfers with B as sender
- Signed by K: Accepted, basically bypassing multisig. This is intended, as the multisig needs to approve the installment of the custom active authority in the first place
2018-07-28 13:43:41 +00:00
2018-08-08 14:48:25 +00:00
#### Recursive active authority
Suppose Alice has a custom active authority with key K for transfers to Charlie. Bob has Alice as his active authority account. Suppose a transaction containing two operations
1. transfer 1 BTS from Alice to Charlie
2. transfer 1000 BTS from Bob to some other account
Cases:
- Transaction is signed by K
- Operation 1. requires Alice as active authority, and there is a matching custom active authority, thus this operation would be allowed to execute
- Operation 2. requires Bob as active authority. Even though Bob has Alice as active authority, K can NOT grant recursively the active authority of Bob
- The whole transaction is denied
- Transaction is signed by K and A
- Operation 1. requires Alice as active authority and is also directly present, is allowed
- Operation 2. requires Bob as active authority, which is indirectly present through A, execution is allowed (existing logic)
- The whole transaction is denied because too many signatures are present (existing logic)
- Transaction is signed by K and B
- Operation 1. requires Alice as active authority, and there is a matching custom active authority, thus this operation would be allowed to execute
- Operation 2. requires Bob as active authority and is also directly present, is allowed
- Transaction may execute
2018-07-30 13:18:43 +00:00
#### Example: Either or
2018-07-30 13:35:12 +00:00
Assume account A, B and C and asset X and asset Y. The custom active authority should now achieve
that a transfer transaction sending funds away from A can be signed with with active authority of account B if
- it sends less than 10000 of asset X to account C
- it sends less than or equal to 20000 of asset Y to account C
More concrete, the authority would look like
2018-07-30 13:18:43 +00:00
```
custom active authority = {
valid_from: 7.7.2018 00:00
valid_to: 8.7.2018 00:00
operation_id: transfer,
authority: {
threshold: 1
key_auth: []
account_auth: [account B, 1]
},
2018-07-30 14:16:18 +00:00
restrictions: [
{
function: logical_or,
data: [ either_list, or_list ]
}
]
2018-07-30 13:18:43 +00:00
}
either_list =
2018-07-30 13:21:09 +00:00
[
{
function: attribute_assert,
argument: amount,
data: [
2018-07-30 13:18:43 +00:00
{
2018-07-30 13:21:09 +00:00
function: lt,
argument: amount,
data: 10000
2018-07-30 13:18:43 +00:00
},
{
2018-07-30 13:21:09 +00:00
function: any,
argument: asset_id,
data: [ asset X ]
2018-07-30 13:18:43 +00:00
}
]
2018-07-30 13:21:09 +00:00
},
{
function: any,
argument: to,
data: [ account C ]
}
]
2018-07-30 13:18:43 +00:00
or_list =
2018-07-30 13:21:09 +00:00
[
{
function: attribute_assert,
argument: amount,
data: [
2018-07-30 13:18:43 +00:00
{
2018-07-30 13:21:09 +00:00
function: le,
argument: amount,
data: 20000
2018-07-30 13:18:43 +00:00
},
{
2018-07-30 13:21:09 +00:00
function: any,
argument: asset_id,
data: [ asset Y ]
2018-07-30 13:18:43 +00:00
}
]
2018-07-30 13:21:09 +00:00
},
{
function: any,
argument: to,
data: [ account C ]
}
]
2018-07-30 13:18:43 +00:00
```
2018-07-30 13:35:12 +00:00
Note: This is included with the third Milestone
2018-07-30 13:18:43 +00:00
2018-07-28 13:43:41 +00:00
2018-07-28 22:18:01 +00:00
#### Example: Checking for custom active authorities
2018-07-28 22:16:52 +00:00
Assume Account A, B and C. Now A has two `custom active authorities`:
- `custom active authority 1`: Allow Account B to transfer asset X to D
- `custom active authority 2`: Allow Account C to transfer asset X to D
2018-07-28 22:18:01 +00:00
The incoming transaction now contains `transfer 100 asset X from A to D, signed by all signatures required for active authority of C`.
The required accounts (meaning required active authority) for the transaction is Account A.
Backend would start considering `custom active authority 1` and check if active authority of account B is present through signatures.
It is not, thus continue by checking if authority of `custom active authority 2` is present, which it is.
2018-08-08 14:48:25 +00:00
Behave as if active authority of Account A is present for the matched operation and continue with normal authority checks.
2018-07-28 22:18:01 +00:00
Since the required accounts is Account A, and the given accounts is also Account A through `custom active authority 2`,
the transaction is executed.
2018-07-28 22:16:52 +00:00
2018-07-30 13:38:47 +00:00
# Milestones
2018-08-13 11:01:42 +00:00
We propose do split the implentation into multiple milestones. Each milestone will be voted on separately:
2018-07-30 13:38:47 +00:00
1. Implementation of basic functionaliy to allow custom active permissions and authorities, including `any`, `none` and `lt, le, gt, ge, eq, neq`, `contains_all, contains_none` and `attribute_assert` `asserts`. If deemed necessary by developpers, reduce to only allow one key or one account for every `custom active authority`
2018-07-30 13:38:47 +00:00
2. Implement stateful asserts `limit` and `limit_monthly`
3. Implement `logical_or`
2018-08-10 11:53:57 +00:00
4. Implement `remaining_executions`
2018-07-30 13:38:47 +00:00
2018-07-25 11:19:23 +00:00
# Summary for Shareholders
2018-07-25 11:34:40 +00:00
Bad publicity in terms of security can have very negative effect on the BTS value. This BSIP allows that traders can e.g. use a trading key, witnesses can use their witness key and a faucet can use a faucet key. If then for some reason the key or witness/faucet server becomes compromised, such a key can do little harm to the account holders, minimizing the risk.
This BSIP opens up a lot of use-cases as presented in Motivation section. The intention is to not alter any existing logic of the permission system, which reduces the risk of malfunctioning.
2018-07-25 11:19:23 +00:00
# Copyright
This document is placed in the public domain.