Sawtooth Permissioning
Introduction
Sawtooth has two different kinds of permissioning, the first is the transaction permissioning, it controls who (user/clients) can submit transactions and batches to a validator, the second is validator key permissioning, this controls which nodes can connect to the Sawtooth network, only available with on-chain settings.
For this debugging and testing scenario we will have 2 nodes:
version: "2.1"
services:
v1:
image: hyperledger/sawtooth-validator:1.1
container_name: v1
command: bash
expose:
- 8000
v2:
image: hyperledger/sawtooth-validator:1.1
container_name: v2
command: bash
To start the nodes one by one, use docker-compose, for this we can use the DEV-engine mode, don't forget to bring up the settings-tp for each node as well:
$ docker-compose -f new-one.yaml run v1
$ sawadm keygen
writing file: /etc/sawtooth/keys/validator.priv
writing file: /etc/sawtooth/keys/validator.pub
$ docker-compose -f new-one.yaml run v2
$ sawadm keygen
...
Initial configuration
When you bootstrap your cluster you need to make sure your admin user pub key is able to change the settings, this operation is made by defining the sawtooth.settings.vote.authorized_keys in your Genesis block.
$ sawset genesis -k /etc/sawtooth/keys/validator.priv -A /etc/sawtooth/keys/validator.pub
Generated config-genesis.batch
$ sawadm genesis config-genesis.batch
gensis.batch
Only the genesis.batch must exists on your data_dir, it will be removed after the first node run. To confirm the genesis block holds your pub key check the state or use sawtooth settings list.
$ sawtooth state list
ADDRESS SIZE DATA
000000a87cb5eafdcca6a8cde0fb0dec1400c5ab274474a6aa82c12840f169a04216b7 145 b'\n\x8e\x01\n&sawtooth.settings.vote.authorized_keys\x12d/etc/sawtooth/keys/validator.pub,02049b8d437b55f06b3280ffdb3285e..
The validator key is the only able to change the settings until now. You can append more keys in a proposal later.
Off-chain transaction permissioning
Off-chain, this is configured by default when starting up the validator node, to configure this permissioning the user must check the validator.toml and choose a ROLE = policy_name, the policy is stored in policy_dir configuration on path.yoml
Since the most interesting feature is being able to use this live and propagate through the network lets take a look on on-chain.
On-chain transaction permissioning
This mode is available using the Identity namespace, so this requires an external daemon running the Identity TP.
Now lets suppose an Operator exists, and this is an external user with REST API access, we need to enable his public key to change the configurations of the identity using the Admin private key.
$ sawset proposal create sawtooth.identity.allowed_keys=03b6ffbc52e0c8b72a1141f85e016509f46d0cbe597828779cf75823398423654 -k /etc/sawtooth/keys/validator.priv
Start creating a new policy and bind it with the "network" role, it means we are going to deny the second node to join the network and allow other nodes to join, you can put multiple rules with space separation.
$ sawtooth identity policy create policy_1 "DENY_KEY 02ab649cd5579e87abc630314ef12b7aff1f2404308645046b8b0e23019eb94b16 PERMIT_KEY *"
$ sawtooth identity role create network policy_1
If you start the second node (v2) and set –peers tcp://v1:8800. You can see the node is not allowed to join the Gossip network.
[2019-12-08 22:48:22.351 DEBUG permission_verifier] Node is not permitted: 02ab649cd5579e87abc630314ef12b7aff1f2404308645046b8b0e23019eb94b16.
[2019-12-08 22:48:22.352 WARNING dispatch] Sending hang-up in reply to AUTHORIZATION_TRUST_REQUEST to connection 7269240ba0805959144ff5ba12432ec0c87cdabfcf5ca1b441d3ff3e3264b88df124856de32e8a92e55b545263fa578bd2246452158ce1f82524244e362dc6cbk
Otel and TP
I have added opentelemetry capabilities in the Identity for testing propose, you can see the Jaeger results in the screenshots below:
Policy create
Role with policy_1
More details in the fork: https://github.com/knabben/sawtooth-core/tree/master/families/identity/sawtooth_identity
Listening