K8 secrets as Hyperledger Fabric wallet using Fabric Java SDK
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:
Follow these steps to setup and run this code pattern. The steps are described in detail below.
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 as sample_org1msp_profile.json
is available in repository.
Replace Your_Connection_Profile_Name
by the filename of your downloaded connection profile in src/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.
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.