Implementing and Updating Access Control Lists for Hyperledger Fabric

Aditya Arora
6 min readMay 25, 2019

--

Learn how to implement Access Control in Hyperledger Fabric project and update it dynamically.

This is an extensive guide for Hyperledger Fabric ACLs at the config level. Hyperledger Fabric is currently the most popular permissioned blockchain framework in the business world.

Hyperledger Fabric Image

This tutorial is divided into two parts.

  1. Understanding and Implementing Access Control List for Hyperledger Fabric.
  2. Updating the Access Control List(or any other configuration) from channel configuration dynamically.

We will implement policy based Access Control on a channel administration level in this tutorial. We will discuss default ACLs present in the fabric, how they’re formatted and how they can be overwritten.

Prerequisites

  1. Understanding of different components of Hyperledger Fabric.
    https://hyperledger-fabric.readthedocs.io/en/release-1.4/fabric_model.html
  2. Basic understanding of Hyperledger Fabric transaction workflow.
    https://hyperledger-fabric.readthedocs.io/en/release-1.4/txflow.html
  3. Installation of Hyperldger Fabric docker images and prerequisites for Fabric.
    https://hyperledger-fabric.readthedocs.io/en/release-1.4/prereqs.html
    https://hyperledger-fabric.readthedocs.io/en/release-1.4/install.html

Understanding and Implementing ACLs

To keep this article succinct, I will quickly state what has been clearly explained in the Fabric Read the docs.

Users interact with Fabric by targeting a user chaincode, system chaincode, or an events stream source. As such, these endpoints are considered “resources” on which access control should be exercised.

Application developers need to be aware of these resources and the default policies associated with them.

There are 2 types of policies we will be using in this.

  1. Signature Policies

These policies identify specific users who must sign in order for a policy to be satisfied.

Policies:
MyPolicy:
Type: Signature
Rule: “Org1.Peer OR Org2.Peer”

Signature policies support arbitrary combinations of AND, OR, and NOutOf, allowing the construction of extremely powerful rules like: “An admin of org A and two other admins, or 11 of 20 org admins”.

2. Implicit Meta Policies

These Implicit Meta policies aggregate the results of policies deeper into the configuration hierarchy that ultimately defined by the Signature policies. They support default rules like “A majority of the organization admins”. These policies use a different but still very simple syntax as compared to Signature policies: <ALL|ANY|MAJORITY> <sub_policy>.

Here’s an example of an ImplicitMeta policy structure:

Policies:
AnotherPolicy:
Type: ImplicitMeta
Rule: "MAJORITY Admins"

Access control defaults exist inside configtx.yaml, the file that configtxgen uses to build channel configurations.

Sample configtx.yaml file.

In this file, you can see from
line 35, Signature Policies are defined
line 194, ImplicitMeta Policies are defined
and from line 131, ACLs are defined.

These are ACLs are currently defined on the system chaincode’s functions.
Read this to understand more on system chaincodes and their respective functions.

Enough of theory now.

Now I will show a bit of code and new policy changes I made while testing ACLs

Let’s edit the Application: ACLs section inside configtx.yaml to change peer/Propose from this:

peer/Propose: /Channel/Application/Writers

To this:

peer/Propose: /Channel/Application/MyPolicy

where MyPolicy is defined as:

Policies: 
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
MyPolicy:
Type: Signature
Rule: "OR('Org1MSP.client')"

Here MyPolicy says only the Client has the right to perform the task.

Don’t forget to generate and update new CA and admin certificates.

Let’s run and try to invoke chaincode from Org1Client.

Now with Org2Client

As we can clearly see from the logs, peer/propose (invocation of function) cannot be done via the ORG2 client.

Updating the Access Control List from configuration (or any other configuration) dynamically.

Access control can be updated one of two ways, either by editing configtx.yaml itself, which will propagate the ACL change to any new channels or by updating access control in the channel configuration of a particular channel. We will update the access in the channel configuration of our channel.

You must have a network running before implementing the below steps.

  1. Access the cli
    There is a cli Docker container created automatically, it is a command line interface to control the nodes.
docker exec -it cli bash

Then, set up environment variables used by some programs:

export CHANNEL_NAME=mychannel
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

You could just copy all of them, then paste to your terminal and press “enter”.

2. Fetch the current channel configurations for mychannel — output: config_block.pb, which is a block file

peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA

3. Transform the config_block.pb configurations to an understandable JSON file — output: config.json

configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config > config.json

4. Make a copy of config.json to modified_config.json, which we will modify it according to what we need to update

cp config.json modified_config.json

5. Install vim for the modification of the JSON file

vim is a famous editing tool in Linux.

sudo apt-get update -y
sudo apt-get install vim -y

6. Modify configurations in modified_config.json

vim modified_config.json

We will change the MyPolicy description from Org1MSP to Org2MSP.

  1. Press “/” to start searching text
  2. Type “MyPolicy”

3. Now, Press “i” to enter insert mode in vim (thus we can start editing), after pressing, you should see that there is “ — Insert — ” on the left bottom of the terminal

4. Change Org1MSP to Org2MSP.

5. Then, press “esc” to exit insert mode of vim

6. Press “shift + :”, type “wq!”, and press “enter”. You should now leave vim and the modification is saved.

7. Transform modified_config.json to a block file — output: modified_config.pb

configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb

8. Transform config.json to a block file — output: config.pb

configtxlator proto_encode --input config.json --type common.Config --output config.pb

9. Compute the difference between modified_config.pb and config.pb — output: diff_config.pb

configtxlator compute_update --channel_id $CHANNEL_NAME --original config.pb --updated modified_config.pb --output diff_config.pb

10. Transform the diff_config.pb configurations to an understandable JSON file — output: diff_config.json

configtxlator proto_decode --input diff_config.pb --type common.ConfigUpdate | jq . > diff_config.json

11. Add envelope text in diff_config.json — output: diff_config_envelope.json

echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":'$(cat diff_config.json)'}}}' | jq . > diff_config_envelope.json

12. Transform diff_config_envelope.json to a block file — output: diff_config_envelope.pb

configtxlator proto_encode --input diff_config_envelope.json --type common.Envelope --output diff_config_envelope.pb

13. Sign diff_config_envelope.pb as Org1 admin (depending on policy)

In step 1, under “Access the Cli”, our cli is representing Peer0 in Org1 via environment variables.

export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

Now, we do signing:

peer channel signconfigtx -f diff_config_envelope.pb

If you are careful enough, you should observe that the file size of diff_config_envelope.pb before signing is smaller than that after signing.

And it is okay to sign multiple times, let’s try it yourself.

14. Sign diff_config_envelope.pb as Org2 admin

export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=peer0.org2.example.com:7051
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

Now, we do signing from Org2

peer channel signconfigtx -f diff_config_envelope.pb

When we make changes in ACLs all the organization admins need to sign the changes before updating it.

15. Send channel update transaction

It is time to update the channel!

peer channel update -f diff_config_envelope.pb -c $CHANNEL_NAME -o orderer.example.com:7050 --tls --cafile $ORDERER_CA

Let’s check the results by invoking the function again from both clients

Invoking from Org1 Client

Invoking from Org2 Client

As you can see, now only the client of Org2 can invoke the chaincode.

To practice on fabric-samples first-network with the node SDK, you can clone my repo.
https://github.com/aditya520/fabric_node_first_network

--

--

Aditya Arora

Tech Enthusiast | Blockchain | Machine Learning. Loves coding and gaming.