Is there a way to block chaincode access for SDK? #fabric-chaincode


Prasanth Sundaravelu
 

Hi Guys,

I've been trying to separate one big chaincode into multiple chaincodes and also for separating business logic from tech logic.

Here, the tech logic service (eg: EncryptAndSaveState) needs to be accessed by multiple other chaincodes. 

I have separated code into different chaincodes and instantiated in same single channel. 

The problem is, if I want to use one chaincode's service from another, I have to expose the functions in chaincode from Invoke / Query functions, so that I can use stub.InvokeChaincode() to call these services. But, if I expose these functions (eg: EncryptAndSaveState), it will be accessible by SDK aswell. I don't want the tech services chaincode to be accessed via SDK. 

Is there a way to identify if request is coming from chaincode (stub.InvokeChaincode()) or from SDK? 
or,
Is there a way to set configuration at peer, to not let request coming from SDK access certain chaincodes by name?

I've tried to do workaround for this by generating and storing a map of TxID and Random-Number at calling chaincode and attached this random number with the Invocation. When the called chaincode receives the Invoke, it again queries back to the calling chaincode (using stub.InvokeChaincode() again) to verify if this random number is infact generated by that chaincode. But, the last Invoke (verification) did not work, it threw: GRPC client failed to get a proper response from the peer \"grpcs://localhost:8051\"."

I would also like to know why this does not work.

Would really appreciate any clue.


Yacov
 

Each chaincode corresponds to a different namespace, and has a different endorsement policy.
Software engineering idioms such as "separation of business logic from tech logic" should never be a reason to separate one chaincode into several chaincodes.

That being said, you can actually prevent users from invoking certain chaincodes by writing and deploying your own authentication filter in the peer.
Take a look at https://github.com/hyperledger/fabric/blob/release-1.4/sampleconfig/core.yaml#L360-L374and at a built in filter we have for blocking expired client certificates in https://github.com/hyperledger/fabric/blob/release-1.4/core/handlers/auth/filter/expiration.go.

Basically you need to extract the target chaincode name from the signed proposal and return an error if it doesn't fit your whitelist.



From:        "Prasanth Sundaravelu" <prasanths96@...>
To:        fabric@...
Date:        12/02/2019 11:11 PM
Subject:        [EXTERNAL] [Hyperledger Fabric] Is there a way to block chaincode access for SDK? #fabric-chaincode
Sent by:        fabric@...




Hi Guys,

I've been trying to separate one big chaincode into multiple chaincodes and also for separating business logic from tech logic.

Here, the tech logic service (eg: EncryptAndSaveState) needs to be accessed by multiple other chaincodes.

I have separated code into different chaincodes and instantiated in same single channel.

The problem is, if I want to use one chaincode's service from another, I have to expose the functions in chaincode from Invoke / Query functions, so that I can use stub.InvokeChaincode() to call these services. But, if I expose these functions (eg: EncryptAndSaveState), it will be accessible by SDK aswell. I don't want the tech services chaincode to be accessed via SDK.

Is there a way to identify if request is coming from chaincode (stub.InvokeChaincode()) or from SDK?
or,
Is there a way to set configuration at peer, to not let request coming from SDK access certain chaincodes by name?

I've tried to do workaround for this by generating and storing a map of TxID and Random-Number at calling chaincode and attached this random number with the Invocation. When the called chaincode receives the Invoke, it again queries back to the calling chaincode (using stub.InvokeChaincode() again) to verify if this random number is infact generated by that chaincode. But, the last Invoke (verification) did not work, it threw: GRPC client failed to get a proper response from the peer \"grpcs://localhost:8051\"."

I would also like to know why this does not work.

Would really appreciate any clue.





Prasanth Sundaravelu
 

Thanks for quick reply!  I will try those suggestions. 

I had thought separating these chaincodes could help manageability more and might increase development pace. Although you make a valid point, I believe chaincode separation might be a good idea with our use case.

We actually have different categories of business logics that our customers can choose from. Later they can add more as per their needs. Multiple of these services commonly depend on some set of services. For this pay per service like flexibility, we chose this idea. 

On Tue, 3 Dec 2019, 2:55 am Yacov Manevich, <YACOVM@...> wrote:
Each chaincode corresponds to a different namespace, and has a different endorsement policy.
Software engineering idioms such as "separation of business logic from tech logic" should never be a reason to separate one chaincode into several chaincodes.

That being said, you can actually prevent users from invoking certain chaincodes by writing and deploying your own authentication filter in the peer.
Take a look at https://github.com/hyperledger/fabric/blob/release-1.4/sampleconfig/core.yaml#L360-L374and at a built in filter we have for blocking expired client certificates in https://github.com/hyperledger/fabric/blob/release-1.4/core/handlers/auth/filter/expiration.go.

Basically you need to extract the target chaincode name from the signed proposal and return an error if it doesn't fit your whitelist.



From:        "Prasanth Sundaravelu" <prasanths96@...>
To:        fabric@...
Date:        12/02/2019 11:11 PM
Subject:        [EXTERNAL] [Hyperledger Fabric] Is there a way to block chaincode access for SDK? #fabric-chaincode
Sent by:        fabric@...




Hi Guys,

I've been trying to separate one big chaincode into multiple chaincodes and also for separating business logic from tech logic.

Here, the tech logic service (eg: EncryptAndSaveState) needs to be accessed by multiple other chaincodes.

I have separated code into different chaincodes and instantiated in same single channel.

The problem is, if I want to use one chaincode's service from another, I have to expose the functions in chaincode from Invoke / Query functions, so that I can use stub.InvokeChaincode() to call these services. But, if I expose these functions (eg: EncryptAndSaveState), it will be accessible by SDK aswell. I don't want the tech services chaincode to be accessed via SDK.

Is there a way to identify if request is coming from chaincode (stub.InvokeChaincode()) or from SDK?
or,
Is there a way to set configuration at peer, to not let request coming from SDK access certain chaincodes by name?

I've tried to do workaround for this by generating and storing a map of TxID and Random-Number at calling chaincode and attached this random number with the Invocation. When the called chaincode receives the Invoke, it again queries back to the calling chaincode (using stub.InvokeChaincode() again) to verify if this random number is infact generated by that chaincode. But, the last Invoke (verification) did not work, it threw: GRPC client failed to get a proper response from the peer \"grpcs://localhost:8051\"."

I would also like to know why this does not work.

Would really appreciate any clue.





Mayank Tiwari
 

Prasanth, did you check for private data collection implementation in the chaincodes?


Regards,
Mayank Tiwari.


On Tue, 3 Dec 2019 at 3:26 AM, Prasanth Sundaravelu <prasanths96@...> wrote:
Thanks for quick reply!  I will try those suggestions. 

I had thought separating these chaincodes could help manageability more and might increase development pace. Although you make a valid point, I believe chaincode separation might be a good idea with our use case.

We actually have different categories of business logics that our customers can choose from. Later they can add more as per their needs. Multiple of these services commonly depend on some set of services. For this pay per service like flexibility, we chose this idea. 

On Tue, 3 Dec 2019, 2:55 am Yacov Manevich, <YACOVM@...> wrote:
Each chaincode corresponds to a different namespace, and has a different endorsement policy.
Software engineering idioms such as "separation of business logic from tech logic" should never be a reason to separate one chaincode into several chaincodes.

That being said, you can actually prevent users from invoking certain chaincodes by writing and deploying your own authentication filter in the peer.
Take a look at https://github.com/hyperledger/fabric/blob/release-1.4/sampleconfig/core.yaml#L360-L374and at a built in filter we have for blocking expired client certificates in https://github.com/hyperledger/fabric/blob/release-1.4/core/handlers/auth/filter/expiration.go.

Basically you need to extract the target chaincode name from the signed proposal and return an error if it doesn't fit your whitelist.



From:        "Prasanth Sundaravelu" <prasanths96@...>
To:        fabric@...
Date:        12/02/2019 11:11 PM
Subject:        [EXTERNAL] [Hyperledger Fabric] Is there a way to block chaincode access for SDK? #fabric-chaincode
Sent by:        fabric@...




Hi Guys,

I've been trying to separate one big chaincode into multiple chaincodes and also for separating business logic from tech logic.

Here, the tech logic service (eg: EncryptAndSaveState) needs to be accessed by multiple other chaincodes.

I have separated code into different chaincodes and instantiated in same single channel.

The problem is, if I want to use one chaincode's service from another, I have to expose the functions in chaincode from Invoke / Query functions, so that I can use stub.InvokeChaincode() to call these services. But, if I expose these functions (eg: EncryptAndSaveState), it will be accessible by SDK aswell. I don't want the tech services chaincode to be accessed via SDK.

Is there a way to identify if request is coming from chaincode (stub.InvokeChaincode()) or from SDK?
or,
Is there a way to set configuration at peer, to not let request coming from SDK access certain chaincodes by name?

I've tried to do workaround for this by generating and storing a map of TxID and Random-Number at calling chaincode and attached this random number with the Invocation. When the called chaincode receives the Invoke, it again queries back to the calling chaincode (using stub.InvokeChaincode() again) to verify if this random number is infact generated by that chaincode. But, the last Invoke (verification) did not work, it threw: GRPC client failed to get a proper response from the peer \"grpcs://localhost:8051\"."

I would also like to know why this does not work.

Would really appreciate any clue.





Prasanth Sundaravelu
 

No, we need the data to exist in all the nodes in network. No hiding required. 

Can you elaborate a little on how do you suggest to use private data here? Id you're thinking about some special exploitation of it?

On Tue, 3 Dec 2019, 8:18 am Mayank Tiwari, <sidharth.mayank@...> wrote:
Prasanth, did you check for private data collection implementation in the chaincodes?


Regards,
Mayank Tiwari.


On Tue, 3 Dec 2019 at 3:26 AM, Prasanth Sundaravelu <prasanths96@...> wrote:
Thanks for quick reply!  I will try those suggestions. 

I had thought separating these chaincodes could help manageability more and might increase development pace. Although you make a valid point, I believe chaincode separation might be a good idea with our use case.

We actually have different categories of business logics that our customers can choose from. Later they can add more as per their needs. Multiple of these services commonly depend on some set of services. For this pay per service like flexibility, we chose this idea. 

On Tue, 3 Dec 2019, 2:55 am Yacov Manevich, <YACOVM@...> wrote:
Each chaincode corresponds to a different namespace, and has a different endorsement policy.
Software engineering idioms such as "separation of business logic from tech logic" should never be a reason to separate one chaincode into several chaincodes.

That being said, you can actually prevent users from invoking certain chaincodes by writing and deploying your own authentication filter in the peer.
Take a look at https://github.com/hyperledger/fabric/blob/release-1.4/sampleconfig/core.yaml#L360-L374and at a built in filter we have for blocking expired client certificates in https://github.com/hyperledger/fabric/blob/release-1.4/core/handlers/auth/filter/expiration.go.

Basically you need to extract the target chaincode name from the signed proposal and return an error if it doesn't fit your whitelist.



From:        "Prasanth Sundaravelu" <prasanths96@...>
To:        fabric@...
Date:        12/02/2019 11:11 PM
Subject:        [EXTERNAL] [Hyperledger Fabric] Is there a way to block chaincode access for SDK? #fabric-chaincode
Sent by:        fabric@...




Hi Guys,

I've been trying to separate one big chaincode into multiple chaincodes and also for separating business logic from tech logic.

Here, the tech logic service (eg: EncryptAndSaveState) needs to be accessed by multiple other chaincodes.

I have separated code into different chaincodes and instantiated in same single channel.

The problem is, if I want to use one chaincode's service from another, I have to expose the functions in chaincode from Invoke / Query functions, so that I can use stub.InvokeChaincode() to call these services. But, if I expose these functions (eg: EncryptAndSaveState), it will be accessible by SDK aswell. I don't want the tech services chaincode to be accessed via SDK.

Is there a way to identify if request is coming from chaincode (stub.InvokeChaincode()) or from SDK?
or,
Is there a way to set configuration at peer, to not let request coming from SDK access certain chaincodes by name?

I've tried to do workaround for this by generating and storing a map of TxID and Random-Number at calling chaincode and attached this random number with the Invocation. When the called chaincode receives the Invoke, it again queries back to the calling chaincode (using stub.InvokeChaincode() again) to verify if this random number is infact generated by that chaincode. But, the last Invoke (verification) did not work, it threw: GRPC client failed to get a proper response from the peer \"grpcs://localhost:8051\"."

I would also like to know why this does not work.

Would really appreciate any clue.