[FIP-40] Detailed Design

 

Purpose:

This document describes the detailed design that will be implemented to meet the requirements of FIP-40.

 

Links:

The FIP

https://github.com/fioprotocol/fips/blob/master/fip-0040.md

The design guide, containing initial design ideas for FIP-40.

 

 

Background/Motivation

The FIO protocol has need to permit an account (A) to perform an operation on data that is owned by another account (C). Furthermore it is necessary that account A will pay all fees for the operations to be performed.

The existing FIO/EOSIO authority model permits account A to perform operations as though they are account C, what this means is that C becomes the owner account, and thus gets charged any fees that result from the operation.

Research was performed into the ways in which this need might best be met by the FIO protocol. During this research it was identified that there are several cases where the FIO protocol could foresee making use of an access model where account A would be granted an access permission by account C. Thus Account A would perform the operation in question, and also pay any fees that are incurred. Providing an access/permission model which can provide any desired access for accounts to objects in state that are owned by others is not a new concept, however no models were identified in the crypto community that perform the access control meeting the presently identified needs of the FIO protocol.

 

Important Objectives:

while a user is actively managing a domain we want to permit the user to be able to manage access to the domain. we want to provide getters that help the user understand the grantees. We want to provide getters that allow a user to verify that they have been granted a permission. We want to provide getters that allow the owner of a permission to get a comprehensive list of the grantees of a permission. We want to provide endpoints that permit the owner to add and remove individual grantees easily.

Limitations

permissions are not hot deployable to the chain. The contracts must be modified to permit new permissions and integrate the business logic of each new permission.

 

 

System level Description

 

We will introduce a notion of a permission, which defines an access control within the protocol. Permissions definitions will be pluggable into the set of existing permissions in the FIO protocols state tables which address access control.

The system will maintain, at a contract code level, a set of the recognized permissions.

Any permission name not recognized by the protocol, and used by users will result in a user level error.

The following process will be used for the definition and integration of new access controls:

Step 1: define the permission desired.

Step 2: modify the fio.contracts affected by the new access to enforce and integrate the new permission.

Step 3: rollout the new permission into testnet and main net using the following actions

3.1. rollout the new version of the contracts supporting the new permission.

3.2 begin using the permission as indicated in the spec.

This provides some level of security in that the contracts must be modified to permit any permissions. In this way it limits the possible paths that can be used by those seeking to hack the FIO protocol.

 

The following vernacular is used throughout our design:

Permission – the name of the permission, the object that is to be controlled, the specific name of the object to be controlled, the owning account, and also including all parameterized data used by the permission according to the business logic required (such as access levels, or other abstractions that can be set when an account grants the permission).

Permission Auxilliary Info – the json definition of all of the parameterized data used by a given permission. for FIP-40 no additional data is necessary.

Grantor – the granting/owning account of the object that relates to the permission.

Object – the object that is being access controlled by a permission (for FIP-40 this is the domain).

Grantee – the non grantor account that is given the ability to register fio handles on a specific domain in the FIO protocol.

 

Query Requirements

The following query-ability requirements have been identified during brainstorming of the various lookups that might be useful for the contracts, block producers, and other community members.

 

Get all grantees by domain name – 2 queries, first get the permission id, then get paged list of accounts using offset and limit on the

Get all the objects that have a certain permission–

by owning account. – get all domains owned by this account that are using this permission.

all-inclusive -- get all domains protocol wide that are using this permission.

Get a list of all accounts granted a permission on a given object – get a comprehensive list of permissions on an object.

Get a list of accounts using a permission in the FIO protocol – return a paging enabled, by account view, of accounts using this permission.

Get a yes/no answer does this account have this permission granted. EX: hasPermission(params)

 

 

Detailed design:

 

The scheme will contain the following tables which will exist in state:

  • Permissions table – this table captures the info relating to the definition of a specific permission.

  • Access tablethis table records accounts that are given a permission from the set of permissions in the permissions table.

Permissions table

uint64_tId – the unique id for each record in the table

string (abcdefghjklmnopqrstuvwxyz1234567890_ max length 100 ) object type – the name of the type of object to be authorization controlled by a permission. the object type is a string constant defined in the fio.contracts, with value “domains” for fip40).

uint128_t object type hash – hash of the object type for index searches on object type.

string object name (alphanumeric no Length limit – the name of the object being authorized in state. (This is the domain name for FIP-40).

uint128_t object name hash – the hash of the object name

string permission name –(alphanumeric no length limit) the name of the permission (for this example “register_address_on_domain”). Permission names are pre-defined by FIO.

uint128_t permission name hash – the hash of the permission name.

uint128_t permission control hash – this indexing assumes that when we combine object_type, object_name, and permission_name, we get a unique record from this table. We combine object type, object name, permission name and hash them for permission lookup. We assume the input string being hashed is not longer than max_length. this will be enforced during validations.

uint64_t owner – this is the fio account owning the permission. (for fip40 this is the account that owns the domain being controlled).

string (json) Auxilliary info -any other useful info relating to this permission control contained in a json string

for FIP-40 this is empty. This auxiliary info is placed in the table to maintain room to expand the notion of a permission as system needs evolve.

 

candidate indexes

primary index

id – provide a unique id for each record for admin purposes.

secondary index

object type hash – lookup by object type

object name hash – lookup by object name.

permission name hash – lookup by permission name.

permission control hash – lookup by permission control (combined hash of object type, object name, and permission name)

owner – lookup by owner

 Access table

uint64_t Id – provide a unique id for records for adminstration purposes.

uint64_t Permission Id – this is the id from the permissions table for the granted permission.

uint64_t Grantee account – this is the account of the grantee.

uint128_t Access hash – hash of grantee account and permission id

 

candidate indexes

primary index

id – provide a unique index for each record for admin purposes.

secondary indices

permission id – lookup by permission id

grantee account – lookup by grantee account

access hash – lookup by grantee account + string(permission), quick 128 bit access for hasPermission(name account, uint64_t permission).

fio.perms contract actions

addperm – this action will create a new permission in the permission table and add an entry for authorization into the perms table.

auth – domain owner only. actor must be the signer of the tx

parameters

grantee account – deshputyz

actor – asdftredg

object type –“domain”

object name – “fredspace”

permission name – “register_address_on_domain”

Auxilliary info - ““ (this means no aux info for this access)

this will perform steps 2 and 3 in the below example.

 

rmperm this action will remove a permission and associated access records from the permission table.

auth – domain owner only. actor must be the signer of the tx

parameters

permission name – name of permission to be removed.

grantee account – the account granted the permission.

object name – object name being controlled (for fip40 this is the domain name).

actor – the calling account, must the the owner of the permission (for domain access the owner account of the domain).

verify inputs as per spec, look up the permission id using permission name, object type (this can be assumed by the system as it is implementation specific and relates to the permission name), object name. Then we look up the permission using the permission and actor account. When we are removing the only entry for the specified permission, consider removing the permission in the permissions table.

clearperm – this action will be called by the address contract only, this action will remove all permissions and accesses associated with the domain in question.

parameters

auth – fio.address only, all other callers disallowed.

permission name

object name

 

important design decisions --

limit the number of grantee accounts to be 100 in the protocol. See below for details.

key decision drivers –

user experience – housekeeping/cleanup of permissions is completed by FIO as the domain lifespan proceeds

 

Issues Identified during detailed design:

limit the number of grantee accounts to be 100 in the protocol. See below for details.

with FIP-40 when a user transfers a domain, the domain may be permitted to have a very large number of granted accesses associated with it. This number of grantee accounts can conceivably be so many that the time to perform housekeeping of permissions could exceed the transaction time limits of the block chain.

There are several ways we can handle this.

First, if there are more than some number of grantee accounts for this domain, we might permit the addition of more grantees, and when a user tries to transfer a domain that has too many grantees we might message to the user "This domain has a permissions for a large number of accounts, please use remperm to remove all permissions that have been granted for domain : "domain name". " if there are less than the max grantees then transfer domain can we can probably safely remove these during the transfer.

Second, we can allow any number of grantees without restriction, and put it on the owner accounts to manage these over the life of the domain.

Third, we can limit the number of grantees to some number that permits housekeeping of permissions in the smart contracts using the permissions.

 

 

Discussions

options 1 and 2 above seem to have use cases where users can be disoriented and burdened with error prone and fiddly activities relating to permissions when they have the least interest in managing a domain, this being when they let the domain expire, and when they transfer ownership of the domain.

if we look at other permissions schemes in place in the linux world. Systems do not limit how users leverage or use permissions. This places admins into the unfortunate situation of having to define and execute offline projects to perform analysis and cleanup whenever there are many accounts using a given permission and that permission needs to change or be removed. in FIO we want to try to provide some ease of use for FIO state permissions. We will need to limit the number of grantee accounts to be a number of accounts that can be reasonably managed during the execution time of a tx to allow the smart contracts to manage housekeeping and cleanup of permissions where this is desirable. (this is option 3 above)

 

pawel agreed to this limiting of the number of accesses per permission, additional performance studies were completed on a local dev box to try to better understand what number is a maximal number of records to have in the accesses table per permission for the permission used by FIP-40.

 

This issue relates to transferring domains, and burning of expired domains. We need to understand the number of accesses that can reasonably be removed from state when a domain is being burned..

performance testing of grantees observed the following

(this is on a dev box running a three node test net)

6K grantees per permission – the local dev net was able to clear all accesses and permissions in one tx.

20k accesses per permission – the local dev net experienced a cpu error when trying to clearar all 20k accesses in one tx.

10k accesses per permission – the local dev net had a CPU limit exceeded error

8k accesses per permission – the local dev net had a CPU limit exceeded error.

 

chat with pawel finds that FIP-40 will limit the number of accounts with a permission to be 100. An error will be reported when add perm is used with more than 100 grantees for the permission, This number can be increased if necessary in the futures needed with a contract update.

 

Getter analysis--

getters will be prototyped to understand how they meet the objectives stated above.