Identity in Hyperledger Fabric (Part 1)

Overview

Identity is an important feature of permissioned blockchain platform. In Hyperledger Fabric, each component needs to be identified before accessing the fabric network. The identity is represented by an X.509 digital certificate. When interacting with a fabric network, the actor specifies and presents the digital certificate, and the fabric network accepts or denies based on the policy.

Setup: Simple Asset Chaincode on Basic Network

We begin with the most simple chaincode and fabric network. Here we are using Simple Asset Chaincode and Basic Network.

Basic Network

It is the simplest setup good for quick demonstration. We can start the basic network by simply running the script ./start.sh.

cd fabric-samples/basic-network
./start.sh
Four containers up and running after start.sh script
This peer has already joint mychannel

Simple Asset Chaincode

The Simple Asset Chaincode (SACC) also comes in fabric-samples. It provides the very basic functions of storing an asset in the ledger. The asset is represented by a key-value pair. When chaincode is first instantiated in a channel, an initial key-value is required. Later the chaincode can be invoked with “get/set” command, to get the value of a key or set a new key-value or a new value to an existing key. You can refer to the SACC here.

Deploy SACC onto Basic Network

Note that the chaincode itself does not contain any fabric network and channel information. We need to deploy the chaincode onto our Basic Network and mychannel.

docker-compose -f docker-compose.yml up -d clidocker exec cli peer chaincode install -n sacc -v 0 -p github.com/saccdocker exec cli peer chaincode instantiate -n sacc -v 0 -C mychannel -c '{"Args":["a", "100"]}'
docker exec cli peer chaincode invoke -n sacc -C mychannel -c '{"Args":["get", "a"]}'
docker exec cli peer chaincode invoke -n sacc -C mychannel -c '{"Args":["set", "a", "500"]}'docker exec cli peer chaincode invoke -n sacc -C mychannel -c '{"Args":["get", "a"]}'

Observing Identity in Fabric Network

As mentioned above, as a permissioned blockchain platform, we expect that every transaction in a fabric network is initiated by an identified user. If we revisit what we have been done, it seems we never touch on any identity: we only issue command peer chaincode from CLI.

Inside CLI Container

Let’s take a look on the environment variable setup in CLI container.

docker exec cli env
CORE_PEER_MSPCONFIGPATH specifies the identity
docker exec -e "CORE_PEER_MSPCONFIGPATH=" cli peer chaincode invoke -n sacc -C mychannel -c '{"Args":["get", "a"]}'
Access denied when no identity is specified
docker exec cli ls crypto/peerOrganizations/org1.example.com/users
docker exec -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp" cli peer chaincode invoke -n sacc -C mychannel -c '{"Args":["set", "a", "300"]}'docker exec -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp" cli peer chaincode invoke -n sacc -C mychannel -c '{"Args":["get", "a"]}'
Chaincode invoke can be done by User1.

Inside Docker-Compose File

The CLI container is instantiated from docker-compose file. Here is the part of docker-compose file about CLI.

cli:
container_name: cli
image: hyperledger/fabric-tools
tty: true
environment:
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- FABRIC_LOGGING_SPEC=info
- CORE_PEER_ID=cli
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
- CORE_CHAINCODE_KEEPALIVE=10
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: /bin/bash
volumes:
- /var/run/:/host/var/run/
- ./../chaincode/:/opt/gopath/src/github.com/
- ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
networks:
- basic
  • The identity information is kept in /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto directory inside the container, which is a volume mapped from ./crypto-config on our localhost.

Inside ./crypto-config directory

Here is our directory structure of ./crypto-config in our localhost.

Admin’s X509 Certificate
User1’s X509 Certificate
CA’s certificate: a self-signed certificate
OrdererOrgs:
- Name: Orderer
Domain: example.com
Specs:
- Hostname: orderer
PeerOrgs:
- Name: Org1
Domain: org1.example.com
Template:
Count: 1
Users:
Count: 1

Access Control in Chaincode

The way to enforce access control at chaincode level is through a library provided by Hyperledger Fabric: Client Identity Chaincode Library (link).

cd fabric-samples/chaincode
cp -r abac/ sacc-ac/
cp sacc/sacc.go sacc-ac/go/sacc-ac.go
cd sacc-ac/go
rm abac.go

Modify SACC-AC Code

Here is the modified SACC (sacc-ac.go). Only the modification part is shown.

import ("fmt""github.com/hyperledger/fabric/core/chaincode/shim/ext/cid"
"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/protos/peer"
)
func set(stub shim.ChaincodeStubInterface, args []string) (string, error) {

// only Admin can set value
x509, _ := cid.GetX509Certificate(stub)
if x509.Subject.CommonName != "
Admin@org1.example.com" {
return "", fmt.Errorf("Only Admin can set new value.")
}
...
original code
...
}

Deploy SACC-AC onto Basic Network

As before, we install and instantiate the chaincode. Our chaincode is now called sacc-ac.

docker exec cli peer chaincode install -n sacc-ac -v 0 -p github.com/sacc-ac/godocker exec cli peer chaincode instantiate -n sacc-ac -v 0 -C mychannel -c '{"Args":["a", "100"]}'

Invoke SACC-AC Chaincode

We first use User1 (setting the environment variable) to get the value, and then set the value.

docker exec -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp" cli peer chaincode invoke -n sacc-ac -C mychannel -c '{"Args":["get", "a"]}'docker exec -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp" cli peer chaincode invoke -n sacc-ac -C mychannel -c '{"Args":["set", "a", "500"]}'
User1 cannot set a new value.
docker exec cli peer chaincode invoke -n sacc-ac -C mychannel -c '{"Args":["set", "a", "500"]}'

Summary

Through the Basic Network and Simple Asset Chaincode, we understand a bit about identity in Hyperledger Fabric. Each activity on fabric network and chaincode requires identity, presented as X.509 digital certificate. As far as the issuer CA is trusted by fabric network, the activity is accepted and processed. With client identity chaincode library, we then modified the SACC and include the access control based on the subject common name. This demonstrated how access control can be enforced at the chaincode level.

Visit http://www.ledgertech.biz/kcarticles.html for all my works. Reach me on https://www.linkedin.com/in/ktam1/ or follow me @kctheservant in Twitter.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store