Security on the Hyperledger Fabric is enforced with digital signatures. All requests made to the fabric must be signed by users with appropriate enrolment certificates. Once user is enrolled, application persist certificate in wallet for future usages.
There are existing Fabric wallets like FileSystemWallet, CouchDBWallet which developers can leverage to store Blockchain identities. The security concern with these implementations is that they “externalize” associated privateKey of the identity which can be compromised if someone get access to these storage systems. Generally front-end client application and client SDK application (integration layer) gets deployed in the containerized environment i.e. into Kubernetes platform. So how about storing the wallet into Kubernetes platform itself? It would be considered more secure since it removes dependency to store wallet outside of Kubernetes platform.
Hence this code pattern demonstrates the methodology to store wallet into Kubernetes platform as secrets and use of those secrets further during transactions.
At the end of this code pattern, the users will understand how-to:
- store wallet as Kubernetes secrets
- use secrets while performing transaction using Fabric JAVA SDK
- Set up Hyperledger Fabric network using IBM Blockchain Platform.
- Deploy the client application built using Fabric Java SDK to communicate with blockchain network on IBM Kubernetes Cluster.
- Users with Admin identity registers new users to the blockchain network and then new users enroll to the network.
- The generated certificates will be stored as Kubernetes Secret.
- The certificates from Kubernetes Secrets will be used to do further transactions with blockchain network.
Follow these steps to setup and run this code pattern. The steps are described in detail below.
- Get the code
- Create IBM Cloud Services
- Setup Hyperledger Fabric Network using IBM Blockchain Platform
- Register and enroll user to connect to Hyperledger Fabric Network
- Deploy the Fabric Java SDK Client application on IBM Kubernetes Service
- Store Fabric wallet as Kubernetes secret
- Access the client application
- Clone the repo using the below command.
git clone https://github.com/IBM/k8-secrets-as-hyperledger-fabric-wallet.git
Create IBM Kubernetes Service Instance
Create two Kubernetes cluster with Kubernetes Service using IBM Cloud Dashboard. One Kubernetes service is required to setup IBM Blockchain Platform and other one is required to deploy client application. Though you can use one Kubernetes service only but thats not the recommended approach.
Note: It can take up to 15-20 minutes for the cluster to be set up and provisioned.
Create IBM Blockchain Platform Service Instance
Create IBM Blockchain Platform Service instance using IBM Cloud Dashboard.
Follow this tutorial to create fabric network using IBM Blockchain Platform. You can decide network components (number of organizations, number of peers in each org etc.) as per your requirement. For example, the blockchain network may consist of two organizations with single peer each and an orderer service for carrying out all the transactions.
Make a note of the Organization CA admin
username and password which you have created. It will be used further to register new users.
Install & Instantiation of Chaincode and Download Connection Profile
This code pattern can be executed with the sample chaincode fabcar.go or else you can install your own chaincode. Instantiate the chaincode after installation and then download the connection profile.
You can refer to step 12 to step 15 here to install smart contract, instantiate and to download the connection profile. The downloaded connection profile will be used in further steps.
-
Go to the cloned repository code.
cd k8-secrets-as-hyperledger-fabric-wallet
-
Copy the downloaded connection profile file(in previous step) at
src/main/resources
. The sample connection profile named assample_org1msp_profile.json
is available in repository. -
Replace
Your_Connection_Profile_Name
by the filename of your downloaded connection profile insrc/main/resources/application.yml
. -
Run the following commands in your terminal window. Make sure JDK11 and Maven path is set properly otherwise you will get errors. This command runs the utility class
application.secret.wallet.util.EnrollAdminAndUser
to register and enroll a new blockchain user using admin identity.mvn clean install mvn exec:java -Dexec.args="<your_connection_profile_filename> <admin_user_name> <admin_user_password> <new_user_name> <new_user_password>"
Note: Username and Password of admin identity should be the ones which was created in Step #3 above.
The output of this command will have the base64 encoded MSP ID, certificate and private Key for the new blockchain user. Make a note of those, it will be used in further steps.
As discussed before, need to decide on which Kubernetes cluster you would like to deploy the application and deploy your Java SDK client application.
-
Navigate to the root directory
k8-secrets-as-hyperledger-fabric-wallet
of the cloned repository code. -
Build and push your container image
If you are using IBM Cloud container registry to store your container image, then build and push your image using the following command:
$ ibmcloud cr build -t <deploy-target> .
where deploy-target is
<region>.icr.io/<my_namespace>/<image_name>:<tag>
as explained here.If you want to use Docker Hub to store images then you should have your Docker Hub account. Create new Docker Hub account if you do not have already and then execute the following steps:
$ export DOCKER_HUB_USER=<your-dockerhub-username> $ docker build -t $DOCKER_HUB_USER/<image_name>:<tag> . $ docker push $DOCKER_HUB_USER/<image_name>:<tag>
-
Update image location in
deployment.yaml
.$ sed -i '' s#IMAGE#<image_location># deployment.yaml ## mac OR $ sed -i s#IMAGE#<image_location># deployment.yaml ## linux
where image_location is either
<deploy-target>
or$DOCKER_HUB_USER/<image_name>:<tag>
. -
Deploy your application.
kubectl create -f deployment.yaml
Wait till the application gets deployed.
-
Get the public ip of your Kubernetes cluster using IBM Cloud Dashboard as
IBM Cloud Dashboard -> Clusters -> <your cluster> -> Worker Nodes (tab)
-
Access your application using:
http://<public_ip_of_cluster>:32424/swagger-ui.html
At this stage, application will not work as expected because user's wallet is not yet provided. Follow the next step for that.
In this step we will make wallet available as secret in the namespace in which the client application is deployed. Then application will use those secrets further to transact with blockchain network.
-
Update
scripts/env_setup.yaml
with the base64 encoded values of new user. Use the values noted in Step #4. -
Perform the steps provided under the access tab
IBM Cloud Dashboard -> Clusters -> <your cluster> -> Access
to get access of your cluster(where you have deployed the client application) through kubectl CLI. -
Run the below commands to store the blockchain user's credentials as Kubernetes secrets.
cd scripts kubectl apply -f ./env_setup.yaml
-
A secret can be used with a Pod in three ways - as files in a volume mounted, as container environment variable or by the kubelet when pulling images for the Pod. In this code pattern, we are using secret as container environment variable. Run the following command to expose Kubernetes secrets as container environment variables.
kubectl set env --from=secret/wallet deployment/fabric-java-sdk-client-app
Access your application at:
http://<public_ip_of_cluster>:32424/swagger-ui.html
You will get the below page on your browser.
Execute the invoke
and query
transactions for your chaincode. If you have deployed the sample fabcar
chaincode, then you can execute the transactions using the values shown below. Else please provide the values as per your chaincode.
Invoke
Click on Invoke Transaction > Try it out
. You can provide the following as invokeRequest
, modify the details as per your network and then Execute
.
{
"chaincodeMethod": "createCar",
"chaincodeName": "fabcar",
"channelName": "channel1",
"data": [
"CAR1","HONDA","CIVIC","Blue","Martin"
]
}
On successful invoke, it will return response code as 200. This time the SDK leverages the wallet from the environment variables which were exposed from Kubernetes secrets to execute the invoke transaction.
Query
To query, click on Query API > Try it out
. Try with the following values for fabcar chaincode and then Execute
.
It will show the list of all cars of which data has been inserted to blockchain.
Note: In this code pattern, we have installed
fabcar
chaincode on network, so we are callingqueryAllCars
chaincode function. Please do change this as per your chaincode functions.
- Quick start guide for IBM Blockchain Platform
- Learn more about wallets of Hyperledger Fabric
- Understand about Kubernetes secrets
This code pattern is licensed under the Apache Software License, Version 2. Separate third-party code objects invoked within this code pattern are licensed by their respective providers pursuant to their own separate licenses. Contributions are subject to the Developer Certificate of Origin, Version 1.1 (DCO) and the Apache Software License, Version 2.