- Hey, good afternoon, everybody.
Welcome to another stream with me.
I'm Cowley.
I'm a Developer Relations Engineer Neo4j.
So today, issue is coming
at a slightly earlier time.
And what I wanna do today
is I wanna go through
the New Role-Based Access Control Features
That Are In Neo4j 4.1.
So this blog post appeared on
the, on the neo4j.com today,
and essentially it is going
through the the new features
of Neo4j 4.1.
So six months after we released 4.0,
and the 4.1 is now available.
So this blog post here has a
list of all of the features
that are inside Neo4j
4.1 or the improvements
that we've done.
But the one I wanna focus on today
is this Role-based Access
Control and Granular Security.
So to give you a little bit of background
in terms of Neo4j and access control.
So in version 3.1,
we got the introduction of Native roles
inside the Neo4j.
So you had a user be able to login.
So for example, Neo4j user.
But these Native roles
allowed you to dictate
what those users could do.
So for example,
a read-only has read-only
access all the way up to an app
in control everything
including creating schema,
and constraints and indexes
and things like that.
And the way that that
was administered in 3.x
was through procedures.
So for example, you
would call DBMS security
to create user, to create user
and then you would assign them to a role.
I've changed in version 4.0,
where we had the introduction
of cipher commands
that would allow you to create
and create users and roles.
So for example, we have
this the create user role.
And what that allows you
to do is just create a user
with a name.
So instead of calling the procedure
and you call the cipher query instead.
So in version four,
we know this we also have this some basic
grant into NIH for access control.
So for example,
you could grant the
ability to traverse read
and match on a graph,
but what has been added into into Neoj4.1
is extra ability is now
for REITs in tax as well.
So you can, rather than
just being able to control
what you can read,
you can also control what the user writes.
So what I'm gonna do today is I'm gonna go
through this blog post
that I've written was published today
on Role Based Access Control.
So if you go to medium.com,
forward slash Neo4j, you
should be able to find this
and a lot more articles on Neo4j.
And this is one of many streams
that we're going out this week,
based around the features of 4.1.
Someone does walkthrough a worked example,
so the official documentation
itself gives you a walkthrough
of Fine-Grained Access Control
from a healthcare point of view.
So we have patients symptoms and diseases
and patients have a
diagnosed with a disease
and depending on the user,
and depending on the role,
and different people are given
access to different things.
I'm gonna put a slightly
different spin on this,
I'm gonna look at the
the Northwind example.
So if you go to the Developer Guides,
and under Data import,
there's RDBMS to Graph guide.
So this guides you through the important
of the Northwind dataset.
So I said dataset, I
remember back from college,
it was kind of a dataset that taught you
how to use Microsoft Access.
So it consists of
customers who place orders,
those orders have details,
and then they order products.
There's also information
suppliers and employees,
which we're not gonna
go into too much detail
about today..
But yeah, it's really
interesting use case.
So this guide will walk you through
how to import the data into Neo4j
And so essentially,
there's a Browsers Guide,
which you can run by using this command.
So I'm gonna do, I'm gonna go through
and create a new version Neo4j4.1.
And so the 4.1 is not
available at the moment
in Neo4j Desktop,
I'm using Neo4j Desktop Canary.
So it's the latest
version of Neo4j Desktop,
the dead version.
So if you if you wanna use it right now,
then download Neo4j Desktop Canary,
otherwise it should be released
a bit later in the week.
Cool, that's my database
there of Northwind.
So while that's starting up,
I'll go through a little bit through this.
So the way the model works
is you have a Customer,
which Purchased Orders
and then there's orders
contain relationships
to one or more products.
And then those Products
are part of Categories
and also supplied by a Supplier.
So the the spin I'm gonna
put on this essentially
coming up with like a
scenario around GDPR.
So if the information around a customer
or their orders was leaked for any reason,
then this could be a
nightmare for GDPR purposes.
And so what I'm gonna do is
I'm gonna create some credit knees........
and then create some,
some constraints around
what they can and can't do.
So first if I go through
and run the play card,
and what we'll do is we will...
so I'll do this I'll go through
and walk through the
play card very briefly.
Okay, let's go ahead and
play and then Northwind
so essentially what he's saying is
that it's a step by step process
importing the Northwind data.
And so this is CSV file.
So you can imagine that these
files have been exported
from a relational database of
your choice into a CSV file
and then import them.
So essentially,
the first one for anyone
who hasn't seen this before,
the delayed CSV command takes a CSV file,
and then converts it into Neo4j types
and the cipher type system.
So we're saying that
load CSV with the headers
from this file here.
So if we take a quick look at this,
we can see that there's a
product as a product name
is partly categorized, quantities, prices
and things like that.
So we're not gonna be too interested
in all the information side there,
but we'll import it in either way.
So what we're doing is we're
saying load CSV from that file,
and then we're assigning
it to a variable rope,
creating a new product node.
And so I made a list of
them with labour product.
And then this is a mass assignment
to say that for every
item inside that roadmap,
then set that as a
property on this end node.
And then so by default,
when you import things in inside load CSV,
everything is a string.
So what these three lines
at the bottom are doing
is just casting the data
into the correct format.
So the unitPrices is a float.
And so I would just take that
and then convert it into
float decimal points.
And then everything is toIntegers.
And then this discontinued is a Boolean,
and to load that data in.
The next one is an important
The Categories so again,
we're take this row
so we've got description
over the category name,
we've got the ID, and we've
got a picture there as well.
If we run that,
then I'll create that data
and the same with supplies as
well as the particular plan.
Then we have a country,
we have a supplier ID,
we have an address,
contact title, et cetera
And then so then next we're
creating some some indexes.
So what the indexes do is
they give you a starting point
of a query.
So, for example,
if I say Match p Product
RETURN p limit 10.
So if I take, for example, this one here,
so we've got a Northwoods Cranberry Sauce,
which would have the product name there.
So when you run a query inside Neo4j,
what it will do is we'll
use some sort of index
or some scan to load the...
To find the starting
point in the traversal.
And then what it will do
is it will traverse our freedom
relationships from there.
So by creating the indexes,
it means that we can easily
identify a individual product.
So for example, on the product ID,
we can go straight to a product ID eight
rather than having to look through all
of the nodes in the database.
And create some relationships
between the Products
and the Category.
So this is sort of like
denormalizing the data in a way
and calculating joins them
and putting them in there.
So then when we actually query the data,
we can do that by using the
extra adjacency in real time,
rather than having to compute
those at the query time.
So that's the really the benefit
of Neo4j really is to query things
in using the index free adjacency.
And you're basically pointer
chasing in memory rather
than having to compute, join tables
and compute things in
memory as the query runs.
So if we take a look here,
so we can see that we're
finding all the Suppliers
and Products and Categories,
then returning the name of the company
and the categories that they sell him.
So it's great.
We've got some data in there now.
Perfect so and for the customers again,
we're doing the same thing.
So from the customers dot CSV file,
creating a customer and then
setting the everything inside
that roadmap property, sales orders,
and then creating the constraints
and indexes on those
relationship between them
again with the order details as well cool.
So, if we take a look at the schema.
So, now we can see
that we have a customer
which has purchased an order
and that order as orders
relationships to products,
product is supplied by supplier.
So supply supply is that product.
And that product is part of a category,
as I said the data that we have in there.
so if we take one example so we go
for a customer, success
customer company name,
so, I'm not going to try
and pronounce that but
we've got this customer
which is then credit disorder.
And then the order contains
these four products.
So example is product Ron Brown,
as ordered by many other people as well,
but it's part of the beverages category
and then there's a
supplier in there as well,
supplied by Martin Bain.
Cool.
So if we go back to the example
of this sensitive information,
so there may be a case
that you have many
different types of users
that need to access the
application at any time.
So I've drawn out some,
some users here that may potentially want
to access the data.
So, for example,
if we have some application servers
that connect to Neo4j using
the the official drivers,
they should only be allowed
to do certain things.
So, for example, I should be
able to read all of the data
from the website,
so you should have access to
all of the customer information
to allow them to log in,.
You want a full view of the
the products in the category,
so the user can browse the site
and they should also be
able to create new orders.
So creating the order notes
and then the relationships in the orders
and the the products and the customers
and even the customers themselves.
So if a customer signs up,
then the application
should be able to add that.
But just in case anything could go wrong
and maybe got some hackers on the site
or some manner,
you may wanna restrict them
from from doing certain things.
So did they really want read access
to the products and the
categories and the supplies?
There's no reason for that
website user to access those.
So for the same sort of
thing for supplies as well.
So if imagine we had
a supplier application
or maybe we supply suppliers
with direct credentials
to access the database and then allow them
to create their own products
and category lessons,
then we should allow them to do that.
But they shouldn't have
access to anything else.
And then for example,
like a Data science team should be able
to access the Products and the Orders,
but without having any access
to the Customer details themselves.
So what we can do is we
can use these new features,
well the features from 4.0
to restrict the access to the reading
of data to these users,
and then we can use the new
features of 4.1 to restrict
that any particular user
or group is allowed to write to the banks.
So what we can do is we can run a command
to create a new user.
And so actually,
one of the notes that I have
on this blog post is that
previously you had to do colon use system
in order to switch the system database
to run system commands.
But actually as of 4.1,
it's now clever enough to
know that the system command
and then pass it through
to the system database,
we don't need to worry
too much about that.
But what I'll do is
I'll create a new route,
the new user for the website.
So to do that,
I use the CREATE USER command,
and then let's call a website
and set the initial password for the user.
Let's just say let me in for now.
And then we say that the
change is not required.
If I say show users,
so I can now see that
we have the nifty use of the
web logged in at the memo,
which has a role of
admin and a role public.
And this new website
user that we've created
with it with a role of public.
So this public role is a new feature 4.1.
And it is basically a way of allowing you
to assign certain privileges to everybody
in the database.
So this is a...
When you create new users
automatically give them the public role
and it's inherited by every database
and every user by default.
So it can be modified
and you can change the
privileges that each
or the public role has,
but it can be removed.
so back in February I wrote this blog post
about this fictional
company called Vendor Power.
So Vendor Power iS fictional company
that sells software as a
service and products to clients
and allows them to view
and track sales of juniors.
So it may be similar to something used
inside your business certainly
something we use inside out.
And essentially the reason
for this blog post was
to demonstrate the features
of firstly multitenancy
and but also the built in roles
and how can how you can keep
the data safe and segregated.
So the idea behind the use case is
that every time a customer
signs up for vendor power,
then a new database or
is creating assign Neo4j,
multitenancy database create inside Neo4j.
And then a set of seeding scripts.
So psycho scripts are run
to create the initial
environment for that user.
So what I had to do inside this blog post
or in order to get this to work was
to create a customer role.
Great world customer.
And essentially what this did is,
this acted as a way for me to be able
to restrict the access for everybody.
And so what I would do is
for each of those customers,
and so for each of the abuses
that has that customer role,
I would deny access to
the database customers,
which is where the overarching customer
information was held.
And then every time I created a database,
I created a new database with
the name of the customer.
And then I would deny
access to to the customer,
which was his public role,
and then create a new
user with the same name
as his name and then grant
that role of customer
so it will have access to all
of the other customer roles,
but then create a custom one
which would then allow it
to access their individual database.
So that's a long winded way of
saying that this public roll
now allows us to do that.
And so by default that role is there.
So we don't have to create
our own one for that...
For the users.
And what we can do is we can use that
to restrict the access,
and grant the access that
we want everybody to have.
So for example, now I have this user,
if I now connect as that user.
So username website, and then
the password was let me in.
So now, it's now logged into to database.
I've got access to Neo4j,
which is the default database,
that's the default system behavior.
But right now I don't have access
to that Northwind database
that we've created.
So what I need to do,
I need to explicitly allow that
So what I'll do is I'll
create that using cipher show
in nifty terminal.
So if you click open terminal,
what it does,
it opens up a terminal
window inside the root
of this database.
So I've got a for example
of the bin folder,
which has all of the
binary files in there,
the input folder, the config and the data.
So inside the bin
folder, I've got seifish,
which is what I'm interested in.
So I can log in with my username
and password since I've been a user.
And what we'll do is it'll go
and it will connect to the database then
and connect to the to the default one.
So if I say show databases,
so I can see that I've now
got that next gen system.
Okay, Phyllis, yeah,
so for this user again,
so we don't have any...
We have no load, no levels
only relationship types.
So we don't have any
access to that database.
And so, what I can do now is
because I want essentially
every user should
have read access to product
and category names inside the database.
What I can do is I can
grant access to those nodes.
So if we take a look at this,
so we've got grant the privilege name
on graphs to arrow.
So in this case,
what I want to do is on a
grant access to that user
and so grant access on graph Neo4j
and then wanted to find
the note that I'd see
so that the labels are nice
that they should be
allowed to see the products
in the category nodes to puppet.
Sorry, so the first thing I wanna do is
to grant access on graph
Neo4j to the public role.
On database, one database.
There we go, cool.
So now for example, if I
could refresh the database,
I might have access to this database.
If I call DB dot schema dot visualization,
see what's in the database,
I've got nothing in that at the moment.
So I still don't have
to access those nodes.
So if I...
Now in this case, grant
the ability to match,
and I wanna match
everything from graph Neo4j.
Now I'm specifying that
the nify for the product
and category names.
To public and tells me everything is fine.
So now if I refresh this,
I've now got the categorization
on about the products.
So I can match on a category.
I can see information about the category.
So all of the properties there.
So I did the grant match star.
So inside he can provide
a comma delimited list
of all of the properties
that you're interested in.
So you can access everything
on those on those nodes,
but right now if I double
click, for example,
there's no relationships between them.
There's no relationship types there.
The reason for this is
because the that the
user doesn't have access
to traversive nature.
And so in order to do this,
there's a graph privilege called traverse.
So, if I say owner to a grant traverse
on the graph Neo4j,
and I can specify their relationships.
So for example,
parts of is the relationship
that we have between product
and the category.
Say to public.
Now, if I call do schema
visualization again,
if I refresh this,
so now I've got that the products
that are part of the categories.
So now if I double click on
one of these nodes, and yeah,
it should give me the
relationships, just perfect.
So because that's granted
to the public user,
then that is available to everybody.
So if I create a new
user or create new role,
then that will be available for them.
Cool.
So the next step then is
to restrict the rights
or allow writes.
So for example, if I try
to create a category node,
I will get an error.
And so create node with the
labels category is not allowed
for the user website with these roles.
And so it makes sense.
So, by default, there's no way
to create nodes inside the database,
you have to be explicit about that.
And so instead of assigning
visibility to the public, well,
which is not what we want,
and what we should do instead is
we should create a new role,
and then assign these to the role.
So in order to create the role,
you use the Create role command.
And that's cool,
this just website user.
And then if I am grant for
all websites user to website.
And then I can...
For example, I can say, Show roles.
Give me the rest of the role.
So I've got these,
and the public role the admin architects,
all the ones that have built in,
we've also got this website user here.
And so if I say,
share roles with users,
I can see that for the public role,
we've got three users
and in the city users,
so Neo4j and this website I've created.
But for this website user
there's one which is website.
So now that we know that,
that users is part of that role,
and we can now start to assign
some more details to them.
So by default the public
role only has access
to products and categories.
But another thing that the
the website user will need
is access to customers and orders as well.
So if I say for example,
we grant match on
everything to the customer
and order nodes to our website user.
So grant match,
and then everything on graph Neo4j,
nodes customer order
to website user and then I refresh,
this visualization I should
now have these two new nodes
and so I've got the customer
there and I've got the order.
Cool.
So the next thing to do on
that is to grant the trust
on the relationships.
So, GRANT TRAVERSE ON GRAPH Neo4j
and the relationships will be purchased
and orders to website user.
Cool, refresh this again.
And I've now got this.
This whole chain there.
So the customer purchase an order
which is an order of products,
which is part of a category.
Perfect.
So we can check the the privileges
that the user has by using
the show user command.
So if I say SHOW USER WEBSITE PRIVILLAGES,
then we can see there that everything
that has been granted for
them and for that user,
so they have access to
the default database
through the role of public
and the match role properties on category
and product base on public.
And you can see that these
are the the new privileges
that we've granted for
the website user role.
So I can see that the
customer knows order nodes
and relationships of orders and purchase.
This Cool.
So, now if I run a query on that,
so to test that,
so the customer can just
pick a specific user.
So, purchased an order,
which orders a product,
which is part of category,
which take the first node paths.
Now we can see that all
of the data is there,
which is great.
But we still can create
the data for that user.
So this user should have access to...
For example, to create
an order, for example.
So if I run create order at the moment,
it'll tell me that the user
which has these two roles
of public website user doesn't have access
to create those orders.
So in order to do that we can
grant the Create privileges.
So on graph Neo4j add
order to website user.
So now if I refresh that, the query again,
I'll run that again.
And now lets me do that
which is exactly what we want it to do.
Cool.
So if I run a crate now with
the properties on there,
it won't let me do that at the moment
because right now I don't have
the privileges to do that.
So I'm not able to set the
property order ID based
on my roles,
so you have to be explicit about the roles
you can set as well.
So, there are...
Essentially there are
two ways of doing this.
So, we can be explicit
about the properties
that we do allow them to set.
So for example,
we could be explicit about the fact
that they could say the customer ID
or the ship city and things like that,
but that may cause
problems as we move ahead.
So say for example, there's
a new field is added
to the database
and we forget to update the privileges
and that could bring
down the whole website,
which isn't great.
So what we can do instead
is we can use the wildcard
in order to allow
everything and then instead,
we should restrict what we
don't want the user to edit.
And so say for example,
we have a couple of couple
of different systems
that have access to the database.
So all of this information,
like the work shipped to the customer ID
and things like that,
we should let them
access that information.
But there may be other
things inside the database
that we don't want to access.
And so for example,
that let's take and the employee
ID and then the ship date.
So we don't want the user role
to update those explicitly
because we have like another
back office process that does
that for us.
So, instead what we can do
is we can grant the credit on everything
and also grant set on everything
and then be restrictive on
what they can't sense that.
So for example,
I can say so grant set so
they're the privileges is set,
property and then we say
all of them on graph Neo4j.
Nodes order to website user coop
and then we can deny the
set of the properties
of employee ID and
shipping on graph Neo4j.
Names order website user,
I check back again.
Check privileges, we can now
see the extra information
so we have the...
We can create an element
and we can set all of the properties,
then it will share with the
properties that we have.
So if I try and do that for example,
and create one with the
order ID of 9999999.
Okay, so one thing to
remember inside Neo4j
is the properties enable.
So all of the data that you add
into Neo4j is actually case sensitive.
So I've got lower case
over there in order,
so that's why that's not working.
So nodes order to website either.
So similarly the role
and the user names are
case sensitive as well.
Right?
So if I try that again,
then it's added the database,
but if I add the employee ID
Sorry, my mistake so I'm yet
to grant everything there.
And then I want to
restrict the employee ID
and the shipping.
cool
So did I set property of employee ID
or ship date on the graph Neo4j
with a known order to the website user?
Perfect.
So if I run this again, perfect.
So now because I've tried to
set both of those properties,
and it doesn't allow me
to set the employee ID
then it will return
back a forbidden error.
Cool, okay.
So, and if for example,
you do make any mistakes
like I have done here,
what you can do is you can
use the the revoke command
to revoke the permission
that you've granted.
So for example,
if I take this with the
lowercase and order.
And so I can say, for example,
revoke, deny set property.
Okay, let's ignore that for now.
And yeah, so he should be able to revoke.
And we'll see why that's not working.
Assets from Robin to.
So you grant them to and
then you revoke it from,
kinda make sense.
(giggles)
Cool.
So yeah, so now we can
see that's been removed.
So essentially as a way
of removing something,
if you make any mistakes,
and you can just revoke those.
So I guess one thing to mention as well,
if you're doing anything
on the public role
and you kinda have to be careful.
So one of the things that I found is that
when adding things to the public role,
and if I made a mistake it would cascade
across to everybody.
So in theory, you could
provide some sort of access
to every user by accident.
Or there may be some
unintended side effects.
So just something to be aware of.
So that's like a small
subset of the commands
that are available
so inside the blog post there's
a whole list of everything
that you can do.
So based on the OGS I've split these out
and see some of the new
things that have been added.
So fOR we don't access,
there's grant access,
and then there's grant match to the role.
In terms of the the editor,
so the editor has read
access to everything plus,
like the limited ability
to write to the graph.
And so you can create
a node with properties
that are there already,
but it won't let you whenever
you create anything new.
So that I guess that the example
that I always give to
people with this is that
if you've got like a new
developer that's joined the team
and they're not used to
the the naming conventions
that you've got.
It can be really easy to add
like bad data into into Neo4j,
so employee ID with a uppercase D
and a lower case d would
be will be different.
So, you just needs to be
sort of careful about that.
And given them the editor
privilege will stop
that from happening.
And so the publisher
has all of that ability,
but also has the ability
to create new keys
and to create constraints.
So for example,
here we have the grant main management,
which allows you to create new keys.
The architects has the
ability to do all that,
but also gives you the the
ability to create constraints
and indexes.
So for example,
and grant index management
to a particular user,
or grant constraint management without
that they weren't able
to create constraints.
And then for anybody that or any role
that you want to give and have access to
So you've got DBMS privileges.
So the ability to update the
DBMS database management system
take for example adding a user,
the database privileges is
all around creating databases
and graphs and then the
transaction management means
that a user can't kill
somebody else's transaction
so by default,
you can only kill your own transactions
and but with this permission,
and then you can you can kill
other people's transactions as well.
So that's everything from for me today.
So if there's any for my guest,
for further reading,
there's this role based
access control in Neo4j4.1.
Blog posts if you go to medium.com/neo4j
should be someone in this awful list,
you take a look at the
the cipher manual entry
on some graph security.
So that gives you more detail
on the controls themselves.
Or if you want a work example,
then you can go
through the authorization
access control page
on the operations manual,
and that's the one that gives
you the healthcare example.
And if anybody has any questions,
any comments, any feedback,
then feel free to get in touch.
My name is Adam Cowley on Twitter,
or you can join the
the Neo4j query website
and start conversation there
at community.neo4j.com.
Otherwise, enjoy your
afternoons and speaking.
