Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
01-03-2020 11:36 AM
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
Solved! Go to Solution.
01-04-2020 10:27 AM
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
01-04-2020 01:47 AM
I guess this is what you've been looking for: https://neo4j.com/docs/cypher-manual/4.0-preview/administration/security/subgraph/#administration-se... ?
01-04-2020 02:18 AM
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...
01-04-2020 10:27 AM
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
All the sessions of the conference are now available online