cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

How do I assign built-in roles to users on specific databases?

Is there a way to assign built-in roles to users for specific databases (and not all?)
For example, I want to assign the admin role to a user for just one database.

With custom roles- what if I want to create a role that allows managing indexes, and then assign that role to users on different databases- is there a way to do this that I've missed?
I can see how to create custom roles with privileges for a specific database, and then assign that specific custom role to a user, but this would mean quite a bit of repetitive role creation on every database.

Any pointers are appreciated

1 ACCEPTED SOLUTION

So I think the key thing to start with is the observation that roles have privileges, and users do not. I'm not saying it works this way under the covers, but the way to think of it is like this:

(:User)-[:HAS]->(:Role)-[:HAS]->(:Privilege)-[:SCOPED_TO]->(:Graph)

Privileges are inherently bound to specific databases, or graphs. If you do SHOW PRIVILEGES on system, then you'll see the results come back with a "graph" field. If you do GRANT CREATE INDEX ON DATABASE db1 TO indexAdmin then "graph" will be "db1". (In Neo4j 4.0, graphs and databases are basically the same thing, but it's called "graph" and not "database" to leave open the possibility that in the future, a single database could contain multiple namespaced / addressable graphs)

So those I think are important fundamentals. So when you ask whether you can grant a user a role only on a particular database, the answer is no -- because "which database are we talking about" is baked into the privilege definition itself. And users can't have privileges, only roles can.

Note that the special reserved roles of admin, reader, architect -- in SHOW PRIVILEGES report that their graph is '*', which gives you part of the answer. You can't grant admin only on one database, and if you do grant admin to a user, because admin has certain privileges on graph *, they get admin everywhere. So you effectively can't express ideas like 'user foo has role admin, except on database supersecret'

So I think the solution in your case should be to define database-specific roles. For example:

CREATE ROLE db1Admin
GRANT ALL DATABASE PRIVILEGES ON DATABASE db1 TO db1Admin

And then grant db1Admin to whatever user needs it. Same approach for all other privilege sets that you'd want to grant. In effect, roles are bound to databases, users are not.

Related caveats that derive from how this works: GRANT/REVOKE/DENY on a role affects all users with that role

View solution in original post

4 REPLIES 4

Hi Stefan, I saw that I believe but it does not allow me assign the role to a user on a database.
Example, say I have a role indexAdmin and then

GRANT
CREATE INDEX ON DATABASE db1,db2
TO indexAdmin

And I have two admin users- db1Admin and db2Admin
If both db1Admin and db2Admin are assigned indexAdmin then we have a problem where they can create indexes on each others database.

I was looking for something like

GRANT
CREATE INDEX 
TO indexAdmin

GRANT indexAdmin to db1Admin on db1
and
GRANT indexAdmin to db2Admin on db2

Also, not sure if the built-in roles like PUBLISHER or ADMIN be assigned in this fashion?
I feel like I'm missing something here...

So I think the key thing to start with is the observation that roles have privileges, and users do not. I'm not saying it works this way under the covers, but the way to think of it is like this:

(:User)-[:HAS]->(:Role)-[:HAS]->(:Privilege)-[:SCOPED_TO]->(:Graph)

Privileges are inherently bound to specific databases, or graphs. If you do SHOW PRIVILEGES on system, then you'll see the results come back with a "graph" field. If you do GRANT CREATE INDEX ON DATABASE db1 TO indexAdmin then "graph" will be "db1". (In Neo4j 4.0, graphs and databases are basically the same thing, but it's called "graph" and not "database" to leave open the possibility that in the future, a single database could contain multiple namespaced / addressable graphs)

So those I think are important fundamentals. So when you ask whether you can grant a user a role only on a particular database, the answer is no -- because "which database are we talking about" is baked into the privilege definition itself. And users can't have privileges, only roles can.

Note that the special reserved roles of admin, reader, architect -- in SHOW PRIVILEGES report that their graph is '*', which gives you part of the answer. You can't grant admin only on one database, and if you do grant admin to a user, because admin has certain privileges on graph *, they get admin everywhere. So you effectively can't express ideas like 'user foo has role admin, except on database supersecret'

So I think the solution in your case should be to define database-specific roles. For example:

CREATE ROLE db1Admin
GRANT ALL DATABASE PRIVILEGES ON DATABASE db1 TO db1Admin

And then grant db1Admin to whatever user needs it. Same approach for all other privilege sets that you'd want to grant. In effect, roles are bound to databases, users are not.

Related caveats that derive from how this works: GRANT/REVOKE/DENY on a role affects all users with that role

@david.allen thanks for confirming that