Looking at securing confidential information in Hyperledger Composer
If assets and transactions in a business network have ACL's to prevent a competitor participant (non-owner) from viewing confidential information, what access can the competitor have to assets and transactions owned by another participant?
Can the competitor access the underlying Fabric ledger to view assets/transactions?
Can the competitor view the transaction processing function?
Can the competitor view the logs of the transaction processing function?
How secure are ACLs?
I don't know if there is some documentation covering this already, or how much is about the security of Fabric rather than Composer.
Dan Selman suggested on RocketChat to ask here.
Thanks
Andrew
Composer's Access Control Engine prevents transaction processor functions written in Javascript from accessing the data in the ledger, based on the type of access requested, the current participant, and the transaction being processed.
The ACL engine does not encrypt the data on the ledger, or attempt to filter the chaincode container logs to remove information.
So, I would say in its current incarnation it is not a suitable mechanism to prevent someone who has physical access to a peer (world state, or the blockchain itself) from viewing information they should not have access to. Modifications are obviously much harder, due to the immutable nature of the blockchain.
In many ways this is similar to access control logic for a relational database. Someone who has physical access to the database files on disk can likely circumvent all access control rules on tables/views etc.
I do believe that we need to go further than this, but first I think we need more detail on the requirements.
Related
I am currently designing an application with many organizations, and each organization will have many users. My concern is about the data privacy and security of these organizations/users. It should never happen that organization A would see data of organization B and vice versa.
I want to use PostgreSQL and Node.js (Nest.js), but the technology does not play a strong role here.
I wanted to have one PostgreSQL database where each organization has its schema, for example, orgA.organizations, orgB.organizations, etc. Unfortunately, I found that it is not a good solution. With many schemas, there can be a performance problem. Then I was thinking about database per organization, but it seems like a huge overhead to handle ~1000 databases.
Now, I am thinking about having a "flat database structure" - without any schemas and having just one database. Organizations would be just in one table and the same for users.
The concern with data privacy would be solved primarily on the application level - I would check if user A can access the data of organization A. Still, in the database, these data will "live together".
So, my question is - what is the best way/technique to ensure that user A that belongs to organization A, will never see the data of organization B?
I want to use Access control functionality in Fabric (like permission.acl in Hyperledger Composer), so how to achieve this in Fabric? and how to specify the user while accessing chaincode to test the Access controls provided for that user from node SDK.
eg:(like Tuna-network example in Composer) I want to give different CRUD access to chaincode functions to different participants/users.
There is no direct equivalent in hyperledger fabric for the Composer ACL functionality.
First you should look at access control lists in fabric to ensure that your fabric network has the correct level of security
https://hyperledger-fabric.readthedocs.io/en/release-1.3/access_control.html
(You would have to have done this anyway as even if you used composer ACLs to ensure a participant could not read something, if that pariticpant had the ability to query the ledger or is able to listen for block events they could still infer the data, unless encrypted, regardless of the Composer ACL denying read access).
The other fabric capability you could look at is what's termed "Attribute Based Access Control". This is where attributes with values are associated with a certificate and the fabric shims for each language provide a utility library to allow chaincode to extract those attribute values and then the chaincode implementation can make a decision on whether the identity making the request has the appropriate authority to perform whatever it has requested.
More details can be found here
https://hyperledger-fabric.readthedocs.io/en/release-1.3/chaincode4ade.html?highlight=client%20identity#chaincode-api
I would like to know how either Fabric or composer can enforce Access Control Logic (ACL). As I read through the documents, ACL is a way to control permission to peers within a channel. When I, as a peer, have a local copy of the ledger, what would prevent me from reading the data that I locally have, although in ACL I am denied to have access? In this case I am talking only about ACL without using the new feature private data collections.
I appreciate any help.
Thank you very much.
Nothing can prevent you from reading the data that you have locally, if you have access to that data.
ACL enforcement in Hyperledger Fabric works via policy evaluation - an ACL is just a policy, and for every action that a network node (peer or orderer) performs - it consults the policy to determine if the requester of the data is eligible according to the policy.
Note, that any data segregation mechanism may be not enough by its own, if the data may be obtained via other actions that have permissive policies. A good example for that is if you have a chaincode that checks that the client originates from a certain organization, but that client's certificate satisfies the "channel readers" policy - then the client can just request the block from the ordering service itself - and just compute the data that the client wants on its own after reading the data blocks.
Every peer can read from his local data but when it comes to data that is stored on ledger peers can't read that data without permission. Actually you as a peer only can access and store some part of ledger that is available not the whole of that.
In our application, we can have a lot of users. (10000 ++)
We would like to give our users the opportunity to sign their transactions, list their assets, in a private environment.
They have their own end users and assets, and will be able to manage them through the network.
At first, our users would use our network, and then we hope to be able to offer them a higher level of privacy by allowing them to interact with their own network. (via the ledger)
We have built a system using composer where our end users (our customers) have their own identities. But we need to be sure we will not have any limitations. Knowing that with this scheme, the number of participants can become huge and the management of identities could become a nightmare
We searched, but we did not find information related to the limitations of such a system built with hyperledger composer.
We understand that a business network is private, but in the case of a SAAS application what would be your recommendations?
So it sounds like you want to give organisations access to a SaaS application and (ultimately) maintain separation (privacy) of the ledger - for an individual organisation (and its users).
You can deploy the SAME business network (smart contract and deployed business model) on separate channels (as in Fabric channels) so then each organisation will have its own ledger. Furthermore, you as the SaaS provider can either issue identities from a central CA registrar in the SaaS network - or - more likely - each has access to their own CA to issue identities (ie certificates) - however that's configured - so that their users can sign transactions (eg from the application).
Those users would connect to their business network (and access that ledger) via business network cards - the 'card' contains the identity information and connection metadata to connect to the deployed business network (from the application in question, eg via the APIs). After an end-user signs in, a check can be made to see if they have a busness network card, to be able to interact with the ledger.
Its likely that the SaaS provider or individual organisations would (through some UI or management capability) issue the cards and have them persisted/stored centrally/securely - ie so the SaaS application running in the end-user's browser(say) can access the user's wallet in that org, which contains the business network card and identity info - just one possible implementation example).
The building of / issuing of cards can be automated (as can the creation of a participant in Composer - which maps to an identity). A CA server will issue a certificate for each identity registered, and each unique identity would therefore have a unique business card (miniscule footprint ie < 1k). Does that help ? So I don't see a major 'limitation', nor a major overhead in what you propose.
In the systems, there may be data that is restricted in nature.
Sometimes access to specific entities should be easily restricted or granted based on user or group membership.
What is the best way to implement this in the microservice architecture?
#1
Should access control, managing permissions etc. be the responsibility of the microserive itself? Developers will have to implement access control, store, and update permissions for every service. Seems like not very robust and error-prone approach.
#2
Create dedicated microservice handling permission management? This service will be called by other microserives to check access permissions for each entity and filtering entities before returning results. Centralized permissions storage and management is an advantage but microservice will have to make a call to "Permission Service" for each entity to check access rights what may have a negative influence on performance. And developers still have to integrate access checks into their services what leaves space for an error.
#3
Make access control responsibility of the API Gateway or Service Mesh. It is possible to think of an implementation that will automatically filter responses of all services. But in the case when the microservice returns list of entities permissions should be checked for each entity. Still a potential performance problem.
Example
Consider the following synthetic example.
Healthcare system dealing with test results, X-Ray images etc. Health information is very sensitive and should not be disclosed.
Test results should be available only to:
patient
doctor
laboratory
Attending doctor may send the patient to another specialist. A new doctor should have access to test results too. So access can be granted dynamically.
So each entity (e.g. test results, X-Ray image) has a set of rules what users and groups are allowed to access it.
Imagine there is a microservice called "Test Results Service" dealing with test results. Should it be responsible for access control, manage permissions etc.? Or permissions management should be extracted to separate microservice?
Healthcare system may also handle visits to a doctor. Information about patient's visit to the doctor should be available to:
patient
doctor
clinic receptionist
This is the example of a different entity type that requires entity level access restriction based on user or group membership.
It is easy to imagine even more examples when entity level access control is required.
I came to the following generic solution.
ACL security model is used. Each object in the system has associated set of permissions. Permissions defines who and what actions can perform on the object.
Microservices are responsible for entity-level authorization and filter objects in responses based on permissions of the objects.
Central Access Control Service is responsible for the creation, update, and deletion of permissions for all objects in the system. Access Control Service database is the primary store of objects' permissions.
Permissions stored in microservices databases are synchronized with Access Control Service database using event-carried state transfer. Every time, permissions are changed an event is sent to the message broker. Microservices can subscribe to these events to synchronize permissions.
API Gateway can be used as the additional protection layer. API Gateway can call Access Control Service directly (RPC) to check response objects' permissions or load recently revoked permissions.
Design features:
A way to uniquely identify each object in the system is required (e.g. UUID).
Permissions synchronization in microservices are eventual consistent. In case of partitioning between message broker and microservice permissions will not be synchronized. It may be a problem with revocation of the permissions. The solution to this problem is a separate topic.
Looks like security is a part of business logic here. In both examples.
Then security could be a part of data scheme.
For example,
Patient can see his tests:
select * from test_result where patient_id=*patient_id*
Doctor can see all test from his medical department:
select * from test_result where branch_id=*doctor_branch*
I believe that to have separate MS for access control is a really bad idea and could lead serious performance problems. Just imagine situation that somebody with zero entity access tries to fetch all entities each time :) You will always need to handle larger result sets than actually needed.
Firstly, this is very bad idea to have a separate (per microservice) security model. It should be single always cross-cutting all application, because it can lead to a hell with access management, permissions granting and mapping between entities in different microservices.
In second, I assume that you are wrong with understanding how to organize microservices..? You should dedicate the principle of splitting functionality into microservices: by features, by domain, etc. Look at Single Responsibility, DDD and other approaches which helps you to achieve clear behavior of your MS.
So, in best case, you should have to:
Choose right security model ABAC or RBAC - there are a lot of other options, but looking at your example I guess the ABAC is the best one
Create separate MS for access management - the main responsibility of this MS is a CRUD and assignment of groups/roles/permissions/attributes to the people accounts.
Create separate MS for providing only permitted health information.
In third, how it works?:
With ABAC you can setup hierarchical roles/permissions (based on groups/attributes) - it helps you to resolve a delegation path of who is permitted to the data
Setup authorization (via auth-MS) and store the list of permissions (in session, cookies, etc)
Check access for a given user for a needed data in health-info-MS. Here we have several options how to do this:
If you use memory-grids (hazelcast, coherence), you can easily create filters with predicates based on security attributes.
If you're using SQL (hibernate, plain SQL, etc.) you should generate queries to return only permitted data - add security specific criteria to the where clause
Few more details about SQL queries with security check in where: before the SQL execution (if hibernate & spring is easy to do with spring-method-auth hook) you should resolve all permissions assigned to a user - you can do this with call to auth-MS.
Example
We created CRUD permissions for TestResult entity - VIEW, EDIT, DELETE.
The role DOCTOR can see any TestResults - so, it has VIEW permission
The role PATIENT can see only his/her TestResults
So, you create a business rules which provide the correct where clause for each business role (DOCTOR, PATIENT, LAB, etc.) and at the end the SQL request would be like:
For patient who has assigned VIEW permission:
select * from test_result where id=*patient_id* and 1=1
For patient who hasn't assigned VIEW permission:
select * from test_result where id=*patient_id* and 1!=1
NOTE: In business rules we can add 1=1 or 1!=1 to permit/restrict query result