Skip to content
This repository was archived by the owner on Aug 2, 2022. It is now read-only.
This repository was archived by the owner on Aug 2, 2022. It is now read-only.

Advanced Permission Hierarchy  #7

Closed

Description

@bytemaster

Advanced Permission Infrastructure
EOS operates on the basis of pre-authenticated messages, but there is still a concept that all actions require a certain permission. Permissions are organized hierarchically. For example, in Steem an account has an owner, active, and posting permission. Owner can do everything, active can do everything exchange change owner, and posting can only make posts and vote.
Each permission in turn is defined as a dynamic, threshold multisig of the following authority structure:

Authority
   ThresholdWeight
   map< key, weight >
   map<  pair<AccountName,PermissionName>, weight >

Each account can define its own permission hierarchy using an number of named permissions each of which has a parent permission and an authority. This is a generalization of the system defined by Steem.

Contract Permission Hierarchy

Each contract can define its own permission hierarchy. By default there is a “Contract” level a per-message permission. But contracts can also group messages into an arbitrary permission hierarchy.
For Example:

ExchangeContract
   TradeAuthority
       CreateOrderMessage
       CancelOrderMessage
   WithdrawAuthority
       WithdrawMessage

A message is dispatched with a permission level of the sender which is evaluated by looking up the Authority structure on the sender and then recursively checking for signatures to verify the account has the authority.

Then we traverse the contract’s message authority tree from leaf permission on up.

ExchangeContract.WithdrawMessage->ExchangeContract.WithdrawAuthority-
>ExchangeContract->SenderActive->SenderOwner

For each level it checks the SenderAccount to see if it has an Authority specified for that level, if the sender has the authority specified, then checks to see if it was the authority on the message. If not it checks any parent-authority specified by the sender on up to active. If no match is found, then it goes to the next level up on the exchange permission tree.

Activity

  1. nathanielhourt commented on May 23, 2017

    @nathanielhourt
    Contributor

    My attempt at describing this system:

    Accounts define a hierarchy of Authority Levels, which are simply named nodes on a tree which always has Owner->Active at the root. Here's an example authority hierarchy for an account used for trading on exchanges:

    Owner
      Active
        Trading
    

    In the above hierarchy, a parent is able to do everything its children/grandchildren can do. Each node in the tree is an Authority structure, which has a threshhold of required approval weight, and a map of either keys to weight (such that a signature from that key conveys that much weight toward the threshold) or of an account-and-AuthorityLevel pair to weight (such that sufficient signatures to satisfy the specified Authority, or one of its parents, conveys that much weight toward the threshold). If enough weight is garnered to meet or exceed the threshold, the Authority is satisfied.

    In essence, the entire Authority Levels system is a way of defining which combination of keys convey what named levels of authority, but so far we haven't tied the named authorities to the actions they authorize, except for owner/active, which are used by core blockchain logic.

    Independently of these Authority Levels, accounts define a separate hierarchy of Permissions. For this, we can taken Dan's example of an account implementing an exchange smart contract:

    ExchangeContract
       TradeAuthority
           CreateOrderMessage
           CancelOrderMessage
    

    Each node in the Permissions tree corresponds to a set of contract handlers, with the leaves often corresponding directly with handlers of a particular message type. Ultimately, the flat list of message types are all that is here; the hierarchy of permissions is just a categorization/grouping technique based on the observation that, frequently, permission to invoke several message types is granted all at once, so it may be convenient to group those types under a single name so they can all be granted at once.

    Finally, to establish the links between the Authority Levels and the Permissions, accounts specify pairings of their own Authority Levels to some account's Permissions. For instance, the account with the Authority Levels we mentioned earlier would probably create a link connecting his PlaceOrder authority to the exchange's CreateOrderMessage permission, a link connecting CancelOrder to CancelOrderMessage. By doing so, he specifies that in order for his account to be sender on a message of type CreateOrderMessage to the exchange, the message must bear signatures satisfying his PlaceOrder Authority Level or higher.

    With these links defined, the account's Trading authority can authorize both PlaceOrderMessage and CancelOrderMessage message types, because these types each link to a child authority to Trading in the account's Authority Levels, thus Trading satisfies those authorities.

    @bytemaster Please review this for accuracy

  2. nathanielhourt commented on May 23, 2017

    @nathanielhourt
    Contributor

    To reiterate: A node in the the Authority Levels tree is an Authority object, which specifies (more or less) which keys must sign to convey its authority level.

    A node in the Permissions tree is a set/group of message types, given a convenient name. This group-naming is specified by the account which provides/hosts the smart contract that evaluates messages of those types. This categorization does nothing to restrict privileges on its own; it is provided solely as a convenience to accounts wanting to define authority levels more granular than active.

    The message types a smart contract handles can be thought of as that contract's API: each message type represents a function call (i.e. CreateOrder, CancelOrder, etc) on the smart contract.

    To restrict certain smart contract actions to certain authority levels, a user account creates links from a Permission in the Permissions tree (restated: from a set of message types, or API calls) to an Authority in its Authority Levels tree. This link establishes that the linked Authority, or a higher one, is required to authorize a message sent by the user account, to the account which hosts the contract, with a type contained in the Permission (restated: the linked Authority or a higher one is required to make one of those API calls).

  3. nathanielhourt commented on May 23, 2017

    @nathanielhourt
    Contributor

    The algorithm utilized by the blockchain to authorize messages in this system is as such:

    1. Determine required Authority

    • Given a message M, look up message recipient account R = M.recipient and sender account S = M.sender
    • Let Permission P be the leaf node in R's permission tree which corresponds to M.type
    • Check if S has defined a link L from one of its Authority Levels to P
      • If S has defined a link L to P
        • Return: required authority level is L.authorityLevel
      • Otherwise, let P = P.parent (walk up the permission tree to a more general grouping of calls) and repeat
    • If P reaches the top of the tree without finding a link, return: required authority level is S.active

    2. Verify required Authority is satisfied

    • Given a required authority A
    • Check if provided signatures satisfy A
      • If A is satisfied
        • Return: true
      • Otherwise, let A = A.parent (walk up the Authority Level tree to a more powerful authority)
    • A has reached top of tree (owner authority) and is not satisfied; return false
  4. nathanielhourt commented on Jul 5, 2017

    @nathanielhourt
    Contributor

    Current design:

    Keep the permission and message group trees discussed above

    Each Message declares a list of accounts and permission levels that were used to authorize it.

    At the beginning of the block, all messages in all transactions are validated, during which stage these declared authorities are checked to verify that (1) the declared authority is sufficient for the given message type and account declared, and (2) the signatures present are sufficient to satisfy that authority.

    To verify (1), we check if the account has defined a link from the message type to a permission in its permission tree. If a link is found, we follow it to find the required permission/authority. If no link is found, we move up to the next smallest grouping of message types, check if a link is found, and repeat until we either find a link, or reach the root of the contract's message type/group tree, in which case we default to requiring the user's active authority. Once the required authority is known, we verify that the message's declared authority is sufficient to satisfy it.

  5. added a commit that references this issue on Jul 27, 2017
  6. nathanielhourt commented on Jul 28, 2017

    @nathanielhourt
    Contributor

    Relevant: #2 (comment)

  7. added 3 commits that reference this issue on Aug 1, 2017
  8. added 2 commits that reference this issue on Aug 3, 2017
  9. 9 remaining items

  10. added 2 commits that reference this issue on Nov 28, 2018
  11. added 2 commits that reference this issue on Dec 29, 2018
    4260006
    daa83fd
  12. added a commit that references this issue on Mar 11, 2019
    8b9e8b9
  13. added a commit that references this issue on Apr 5, 2019
    7342e06
  14. added a commit that references this issue on Feb 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions