Attribute based Access Control in Hyperledger fabric

While doing some POC work, we are confused between Ethereum and Hyperledger fabric. As per our requirement, we go with Hyperledger fabric. The reasons why we chosen Hyperledger fabric are:

  • It is private permission Blockchain.
  • Performance, scalability and level of trust is good for Fabric.
  • Hyperledger fabric has Modular Architecture with supporting plug-in components.
  • Private channel which help us to keep private data between 2 organisations.

What problem we faced?

When we register user on fabric-ca server, we assigned different roles (client, peer and admin) to the user. In configtx.yaml, we had specified the access rule of users. Below is the code snippet from configtx.yaml.

Policies:
  Readers:
     Type: Signature
     Rule: “OR(‘Org1MSP.admin’, ‘Org1MSP.peer’, rg1MSP.client’)”
  Writers:
     Type: Signature
     Rule: “OR(‘Org1MSP.admin’, ‘Org1MSP.client’)”
  Admins:
     Type: Signature
     Rule: “OR(‘Org1MSP.admin’)”

When we spun up a network and registered user with different roles, we found that these roles are not working as we expected. We asked query on Hyperledger fabric community and community member suggested us to use Attribute Based Access Control. So question comes in mind that what is Attribute Based Access Control?

Attribute Based Access Control:

In an attribute-based access control system, any type of attribute such as user attributes and resource attributes are used to determine access. These attributes are compared to defined static values or even to other attributes, which turns it into a relation-based access control. Attributes come in key-value pairs such as “Role=Supervisor,” which can be used to limit access to a certain feature of a system. In this case only users with the designation of supervisor or higher can be given access to that feature or system.

Implementation:

We had used fabric node SDK for communicating with Hyperledger fabric node and chaincode. We used node.js for writing chaincodes.

Server side code(Node):

Before performing any transactions on Hyperledger network, we need to register and then enroll the user. To know more about register function, please refer hyperledger Node SDK documentation. Below is the code snippet for registering user:

fabric_ca_client.register({ enrollmentID: username, affiliation: ‘org1.department1’, role: ‘client’, attrs: [{ name: ‘firstName’, value: ‘Mathan_sir’, ecert: true }] }, admin_user);

We have added attrs: [{ name: ‘firstName’, value: ‘Mathan_sir’, ecert: true }] as extra part in register function. Here you can specify key-value for new attribute. It can be anything you want.

Once user is registered successfully, we need to enroll the above user. To know more about enroll function, please refer hyperledger Node SDK documentation. Below is the code snippet for enrolling user:

fabric_ca_client.enroll({ enrollmentID: username, enrollmentSecret: secret, attr_reqs: [{ name: “firstName”, optional: false }]});

We have added attr_reqs: [{ name: “firstName”, optional: false }] as extra part in enroll function. Remember, you have to specify same key-value pair inwhile enrolling which you used while registering user.

Chaincode Code:

Now we can use above define attributes in chaincode to provide access to particular chaincode functionality. Just add below code in your chaincode and you are done.

Import a library:
const ClientIdentity = require(‘fabric-shim’).ClientIdentity;
Add below code in a function where you want to restrict access to the user:
let cid = new ClientIdentity(stub);
if (cid.assertAttributeValue(‘firstName’, ‘Mathan_sir’)) {
  throw new Error(‘Not a valid user’);
}

I hope above article will help you to implement user level access in Hyperledger fabric. You can generalised above code for different types of user. Is there another way to implement User Level Access in Hyperledger Fabric? If yes, I would love to hear from you.