8.1. Permissions

Hyperledger Iroha uses a role-based access control system to limit actions of its users. This system greatly helps to implement use cases involving user groups having different access levels — ranging from the weak users, who can’t even receive asset transfer to the super-users. The beauty of our permission system is that you don’t have to have a super-user in your Iroha setup or use all the possible permissions: you can create segregated and lightweight roles.

Maintenance of the system involves setting up roles and permissions, that are included in the roles. This might be done at the initial step of system deployment — in genesis block, or later when Iroha network is up and running, roles can be changed (if there is a role that can do that :)

This section will help you to understand permissions and give you an idea of how to create roles including certain permissions. Each permission is provided with an example written in Python that demonstrates the way of transaction or query creation, which require specific permission. Every example uses commons.py module, which listing is available at Supplementary Sources section.

8.2. List of Permissions

Permission Name Category Type
can_create_account Account Command
can_set_detail Account Command
can_set_my_account_detail grantable Account Command
can_create_asset Asset Command
can_receive Asset Command
can_transfer Asset Command
can_transfer_my_assets grantable Asset Command
can_add_asset_qty Asset Quantity Command
can_subtract_asset_qty Asset Quantity Command
can_add_domain_asset_qty Asset Quantity Command
can_subtract_domain_asset_qty Asset Quantity Command
can_create_domain Domain Command
can_grant_can_add_my_signatory Grant Command
can_grant_can_remove_my_signatory Grant Command
can_grant_can_set_my_account_detail Grant Command
can_grant_can_set_my_quorum Grant Command
can_grant_can_transfer_my_assets Grant Command
can_add_peer Peer Command
can_append_role Role Command
can_create_role Role Command
can_detach_role Role Command
can_add_my_signatory grantable Signatory Command
can_add_signatory Signatory Command
can_remove_my_signatory grantable Signatory Command
can_remove_signatory Signatory Command
can_set_my_quorum grantable Signatory Command
can_set_quorum Signatory Command
can_get_all_acc_detail Account Query
can_get_all_accounts Account Query
can_get_domain_acc_detail Account Query
can_get_domain_accounts Account Query
can_get_my_acc_detail Account Query
can_get_my_account Account Query
can_get_all_acc_ast Account Asset Query
can_get_domain_acc_ast Account Asset Query
can_get_my_acc_ast Account Asset Query
can_get_all_acc_ast_txs Account Asset Transaction Query
can_get_domain_acc_ast_txs Account Asset Transaction Query
can_get_my_acc_ast_txs Account Asset Transaction Query
can_get_all_acc_txs Account Transaction Query
can_get_domain_acc_txs Account Transaction Query
can_get_my_acc_txs Account Transaction Query
can_read_assets Asset Query
can_get_blocks Block Stream Query
can_get_roles Role Query
can_get_all_signatories Signatory Query
can_get_domain_signatories Signatory Query
can_get_my_signatories Signatory Query
can_get_all_txs Transaction Query
can_get_my_txs Transaction Query

8.2.3. Supplementary Sources

commons.py
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#
# Copyright Soramitsu Co., Ltd. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
#

import ed25519
import irohalib
import primitive_pb2
import binascii
from time import time

command = irohalib.Iroha.command


def now():
    return int(time() * 1000)


def all_permissions():
    return [
        primitive_pb2.can_append_role,
        primitive_pb2.can_create_role,
        primitive_pb2.can_detach_role,
        primitive_pb2.can_add_asset_qty,
        primitive_pb2.can_subtract_asset_qty,
        primitive_pb2.can_add_peer,
        primitive_pb2.can_add_signatory,
        primitive_pb2.can_remove_signatory,
        primitive_pb2.can_set_quorum,
        primitive_pb2.can_create_account,
        primitive_pb2.can_set_detail,
        primitive_pb2.can_create_asset,
        primitive_pb2.can_transfer,
        primitive_pb2.can_receive,
        primitive_pb2.can_create_domain,
        primitive_pb2.can_read_assets,
        primitive_pb2.can_get_roles,
        primitive_pb2.can_get_my_account,
        primitive_pb2.can_get_all_accounts,
        primitive_pb2.can_get_domain_accounts,
        primitive_pb2.can_get_my_signatories,
        primitive_pb2.can_get_all_signatories,
        primitive_pb2.can_get_domain_signatories,
        primitive_pb2.can_get_my_acc_ast,
        primitive_pb2.can_get_all_acc_ast,
        primitive_pb2.can_get_domain_acc_ast,
        primitive_pb2.can_get_my_acc_detail,
        primitive_pb2.can_get_all_acc_detail,
        primitive_pb2.can_get_domain_acc_detail,
        primitive_pb2.can_get_my_acc_txs,
        primitive_pb2.can_get_all_acc_txs,
        primitive_pb2.can_get_domain_acc_txs,
        primitive_pb2.can_get_my_acc_ast_txs,
        primitive_pb2.can_get_all_acc_ast_txs,
        primitive_pb2.can_get_domain_acc_ast_txs,
        primitive_pb2.can_get_my_txs,
        primitive_pb2.can_get_all_txs,
        primitive_pb2.can_get_blocks,
        primitive_pb2.can_grant_can_set_my_quorum,
        primitive_pb2.can_grant_can_add_my_signatory,
        primitive_pb2.can_grant_can_remove_my_signatory,
        primitive_pb2.can_grant_can_transfer_my_assets,
        primitive_pb2.can_grant_can_set_my_account_detail
    ]


def genesis_block(admin, alice, test_permissions, multidomain=False):
    """
    Compose a set of common for all tests' genesis block transactions
    :param admin: dict of id and private key of admin
    :param alice: dict of id and private key of alice
    :param test_permissions: permissions for users in test domain
    :param multidomain: admin and alice accounts will be created in
    different domains and the first domain users will have admin right
    by default if True
    :return: a list of irohalib.Iroha.command's
    """
    peer = primitive_pb2.Peer()
    peer.address = '0.0.0.0:50541'
    # ed25519.publickey_unsafe takes and returns a bytes object, while we have hex strings
    peer.peer_key = binascii.hexlify(ed25519.publickey_unsafe(binascii.unhexlify(admin['key'])))
    commands = [
        command('AddPeer', peer=peer),
        command('CreateRole', role_name='admin_role', permissions=all_permissions()),
        command('CreateRole', role_name='test_role', permissions=test_permissions)]
    if multidomain:
        commands.append(command('CreateDomain', domain_id='first', default_role='admin_role'))
    commands.extend([
        command('CreateDomain',
                domain_id='second' if multidomain else 'test',
                default_role='test_role'),
        command('CreateAccount',
                account_name='admin',
                domain_id='first' if multidomain else 'test',
                public_key=irohalib.IrohaCrypto.derive_public_key(admin['key'])),
        command('CreateAccount',
                account_name='alice',
                domain_id='second' if multidomain else 'test',
                public_key=irohalib.IrohaCrypto.derive_public_key(alice['key']))
    ])
    if not multidomain:
        commands.append(command('AppendRole', account_id=admin['id'], role_name='admin_role'))
    return commands


def new_user(user_id):
    private_key = irohalib.IrohaCrypto.private_key()
    if user_id.lower().startswith('admin'):
        print('K{}'.format(private_key.decode('utf-8')))
    return {
        'id': user_id,
        'key': private_key
    }


def hex(generator):
    """
    Decorator for transactions' and queries generators.

    Allows preserving the type of binaries for Binary Testing Framework.
    """
    prefix = 'T' if generator.__name__.lower().endswith('tx') else 'Q'
    print('{}{}'.format(prefix, binascii.hexlify(generator().SerializeToString()).decode('utf-8')))