Keeping Properties Secret in Neo4j

We’re an open source company with nothing to hide, but some of our customers have things they need to keep close to their chest. Sometimes you don’t want everybody to have access to salary information, or future predictions. Maybe you want to hide Personally identifiable information (PII) or Health Insurance Portability and Accountability Act (HIPPA) data. In Neo4j 3.4 we are introducing more security controls. We are starting with Role based Database wide property key blacklists. That’s a bit of a mouthful but let’s walk through and example to see one of the ways it can be utilized. Imagine you are working in “Area 51” and have to deal with very important information.

You want your boss who has “Top Secret” access to know the truth, you want your friend James from “Area 50” who has “Secret” access to know a little less than they whole truth. You want those like Tim who have “Confidential” access to know a little less than that, and finally you want the public to know the least and only the Unclassified information. We will need to change the “neo4j.conf” file in the config directory of our Neo4j installation , add a couple of lines, save the file and restart Neo4j (on all cluster members):

 
dbms.security.property_level.enabled=true
dbms.security.property_level.blacklist=Secret=top_secret;Confidential=top_secret,secret;Unclassified=top_secret,secret,confidential

In Neo4j Enterprise edition you will need to create a few accounts. The format is:

 
CALL dbms.security.createUser(username, password, requirePasswordChange)

So for example:

 
CALL dbms.security.createUser("james", "1234", false); 
CALL dbms.security.createUser("tim", "5678", false);
CALL dbms.security.createUser("public", "password", false);

Next we will create Security Roles for these accounts:

 
CALL dbms.security.createRole("Secret");
CALL dbms.security.createRole("Confidential");
CALL dbms.security.createRole("Unclassified");

… and we will add the roles to the users:

 
CALL dbms.security.addRoleToUser("Secret", "james");
CALL dbms.security.addRoleToUser("Confidential", "tim");
CALL dbms.security.addRoleToUser("Unclassified", "public");

But before they can read anything from the database, they also need reader access:

 
CALL dbms.security.addRoleToUser("reader","james");
CALL dbms.security.addRoleToUser("reader","tim");
CALL dbms.security.addRoleToUser("reader","public");

We can call “listRoles” to see how it looks:

 
CALL dbms.security.listRoles();

Now that everything is set, we will create a report on the existence of “Aliens”.

We have different versions of the truth, so we will create multiple properties to answer the question in our document:

 
CREATE (u:Document {name:'Aliens?', 
                    top_secret:'They hate us!', 
                    secret:'They like us!', 
                    confidential:'They exist!', 
                    public:'They do not exist.'})

We can query for the truth using COALESCE. It will use the first non-null property it finds. Since we are logged on as the Neo4j admin user with full access when we ask:

 
MATCH (u:Document {name:'Aliens?'})
RETURN COALESCE (u.top_secret, u.secret, u.confidential, u.public) AS truth

We get the real answer “They hate us!”. Now let’s disconnect and try a different account.

 
:server disconnect

Log back in as James, and rerun the query and we get “They like us!”. Disconnect again, and log back in as Tim and you get “They exist!”. One more time as user public, and you get “They do not exist”. Pretty neat right? So you can use this feature to keep sensitive data away from people and also show different levels of detail. If you want to try it out, you can get a pre-release version of Neo4j 3.4 here.

Tagged , , , , ,

9 thoughts on “Keeping Properties Secret in Neo4j

  1. What if the user in the confidential role tries to query based on the property? something like:
    MATCH (u:Document {secret:’They like us!’}) return u.name

    Will that work?

  2. koen says:

    Hi, great extension ! So are the other roles pre-defined roles ? What do they stand for ? And would it be possible to have read access on one or more selected properties (i guess you need the reader role for that .. ) while having write authorization on other properties ? Thanks .. regards Koen

  3. Wil Parton says:

    Any plans to extend this to “Keeping Nodes Secet in Neo4j”. We have model segragation on our To Do list; essentially node ACLs based upon user roles/permissions to allow all or a subset of the graph to be visible to a user. Last time I asked support for this capabilty wasn’t on the product roadmap, just wondering if there was any change.

    • maxdemarzi says:

      We have more security features in the pipe, it’s just a matter of priority and engineering time while balancing performance. I would like to see more fine grained security as a plugin rather than built into Neo4j so people can choose to have it with the possible performance hit or not.

      • koen says:

        externalizing authorization decisions sounds like a good idea since that will also enable ABAC / NGAC kind of solutions to be placed in front (PEP/RAP combined with a PDP/PAP/PIP).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: