Hyperledger Fabric with LDAP integration — part 2
In the previous article i have described set up process of LDAP and Fabric CA. As the result of the exercise presented there, you should be able to enroll a user that was previously registered on LDAP. You can find it here
In this short article we will continue working on LDAP and Fabric CA integration and we will focus more on playing with an identity attributes.
I will explain mechanism of translating LDAP attributes into these, which can be interpretable by Hyperledger Fabric. Before going into details, please take a look into LDAP structure that will be used in our examples:
Attributes
First things first — attributes. What can we do with them and how can they come handy to us while working with Hyperledger Fabric ?
Hyperledger Fabric comes with a few predefined attributes that can be attached to the identity. Their responsibility is generally to make access control decisions. The attributes can be as follow:
- hf.Registrar.Roles
- hf.Registrar.DelegateRoles
- hf.Registrar.Attributes
- hf.GenCRL
- hf.Revoker
- hf.AffiliationMgr
- hf.IntermediateCA
Detailed description and possible values of above can be found in the documentation. Some of them are useless while working with LDAP since the process of registration is not going via Fabric CA, but still we can take an advantage of the rest of them.
Example: Iam interested in hf.GenCRL attribute, which is type of Boolean and if set to true, identity is able to generate Certificate Revocation List.
Let’s assume that our requirement is to allow admin1 user to generate CRL.
In order to make our example working, we will need to define converters between LDAP and Fabric CA. It should be done in the converter section of fabric-ca-server-config.yaml file and it would look like this:
attribute:
names: ['cn']
converters:
- name: hf.GenCRL
value: attr("cn") =~ "admin1"
Above code is rather self explanatory, but let me just summarize: hf.GenCRL evaluates to true when cn parameter is equal to admin1 in LDAP. Elements of names array contains LDAP attribute names which are requested from the LDAP server for an LDAP identity’s entry.
The next step is to add attributes into the enrollment certificates (ECerts). We will do it during the enrollment process:
fabric-ca-client enroll -u http://admin1:admin1pw@localhost:7054 --enrollment.attrs hf.GenCRL
Now we can check if admin1 is able to generate CRL:
fabric-ca-client gencrl
As the result you should see that CRL was generated:
[INFO] Configuration file location: /etc/hyperledger/fabric-ca-server/fabric-ca-client-config.yaml
[INFO] Successfully generated the CRL
[INFO] Successfully stored the CRL in the file %s/etc/hyperledger/fabric-ca-server/msp/crls/crl.pem
Ok, so we can try to enroll another identity and generate CRL:
fabric-ca-client enroll -u http://admin2:admin2pw@localhost:7054 --enrollment.attrs hf.GenCRL
fabric-ca-client gencrl
The outcome should be error message
Note
Currently incorrect message is returned from CLI, you will see Response from server: Error Code: 20 — Authorization failure but in logs you can find proper description of the issue: The identity ‘admin2’ does not have authority to generate a CRL. I already reported issue on Hyperledger Jira: https://jira.hyperledger.org/browse/FABC-729
So far we know that there are some attributes that Fabric CA can interpret, but we can define other attributes and connect them with the identity. The question is how can they help us since CA will not be able to interpret them?
Attribute-Based Access Control
Hyperledger Fabric provide functionality of Attribute-Based Access Control (ABAC). As name suggests, access rights are granted based on a set of attributes. What’s more, a decision can be taken at runtime, for example in chaincode.
Assuming that admin1 user in LDAP has role attribute set to aws (attribute is not visible on LDAP structure diagram above), our requirement is to create custom attribute called adminRole and use that attribute in our chaincode to make an access decision.
To achieve that, we have to define a new converter, which will translate LDAP role attribute into adminRole passed during enrollment:
names: ['cn','role']
converters:
- name: hf.GenCRL
value: attr("cn") =~ "admin1"
- name: adminRole
value: map(attr("role"),"roleMap")
maps:
roleMap:
- name: aws
value: AmazonWebService
- name: gcp
value: GoogleCloudPlatform
And off course enroll user:
fabric-ca-client enroll -u http://admin1:admin1pw@localhost:7054 --enrollment.attrs adminRole
Now, during runtime we can check in chaincode if user has attribute adminRole set to AmazonWebService and use it, for instance, to allow particular user to execute some logic.
References:
https://hyperledger-fabric-ca.readthedocs.io/en/latest/users-guide.html#configuring-ldap