Graph and sub-graph access control

Privileges control the access rights to graph elements using a combined whitelist/blacklist mechanism. It is possible to grant access, or deny access, or a combination of the two. The user will be able to access the resource if they have a grant (whitelist) and do not have a deny (blacklist) relevant to that resource. All other combinations of GRANT and DENY will result in the matching path being invisible. It will appear to the user as if they have a smaller database (smaller graph).

If a user was not also provided with the database ACCESS privilege then access to the entire database will be denied. Information about the database access privilege can be found in The ACCESS privilege.

The GRANT, DENY and REVOKE commands

The GRANT command allows an administrator to grant a privilege to a role in order to access an entity. The DENY command allows an administrator to deny a privilege to a role in order to prevent access to an entity. The REVOKE command allows an administrator to remove a previously granted or denied privilege. The syntax is:

Table 1. General graph privilege command syntax
Command Description
GRANT graph-privilege ON GRAPH[S] {* | name} [entity] TO role[, ...]

Grant a privilege to one or multiple roles

DENY graph-privilege ON GRAPH[S] {* | name} [entity] TO role[, ...]

Deny a privilege to one or multiple roles

REVOKE GRANT graph-privilege ON GRAPH[S] {* | name} [entity] FROM role[, ...]

Revoke a granted privilege from one or multiple roles

REVOKE DENY graph-privilege ON GRAPH[S] {* | name} [entity] FROM role[, ...]

Revoke a denied privilege from one or multiple roles

REVOKE graph-privilege ON GRAPH[S] {* | name} [entity] FROM role[, ...]

Revoke a granted or denied privilege from one or multiple roles

Where the components are:

  • graph-privilege

    • TRAVERSE

      allows the specified entities to be found

    • READ

      allows the specified properties to be read on the found entities. Note that granting property READ access does not imply that the entities with that property can be found. For example if there is also a DENY on it, the entity will not be found. The props can be * which means all properties.

    • MATCH

      this combines both TRAVERSE and READ allowing an entity to be found and its properties read.

    • WRITE

      this privilege can only be assigned to all nodes, relationships and properties in the entire graph (this means that the entity part of the command must also be ELEMENTS * and cannot be more specific).

  • name

    • The graph or graphs to associate the privilege with. In 4.0 there can be only one graph per database, and therefore this command uses the database name to refer to that graph. Note that if you delete a database and create a new one with the same name, the new one will NOT have any of the privileges specifically assigned to the deleted graph.

    • It can be * which means all graphs. Any new databases created after this command will also be associated with these privileges.

  • entity

    • The graph elements this privilege applies to:

      • NODES label (nodes with the specified label(s)).

      • RELATIONSHIPS type (relationships of the specific type(s)).

      • ELEMENTS label (both nodes and relationships).

    • The label or type can be * which means all labels or types.

    • Multiple labels or types can be specified, comma-separated.

    • Defaults to ELEMENTS * if omitted.

  • role[, …​]

    • The role or roles to associate the privilege with, comma-separated.

It is important to note that using DENY does NOT erase a GRANT command; they both exist. The only way to erase a privilege is with REVOKE.
grant privileges graph
Figure 1. GRANT and DENY Syntax. The { and } are part of the syntax and not used for grouping.

The below image shows the hierarchy between the different graph privileges.

privilege hierarchy graph
Figure 2. Graph privileges hierarchy

Listing privileges

Available privileges for all roles can be seen using SHOW PRIVILEGES.

Query
SHOW PRIVILEGES

Lists all privileges for all roles. The table contains columns describing the privilege:

  • access: whether the privilege is granted or denied (whitelist or blacklist)

  • action: which type of privilege this is: access, traverse, read, write, token, schema or admin

  • resource: what type of scope this privilege applies to: the entire dbms, a database, a graph or sub-graph access

  • graph: the specific database or graph this privilege applies to

  • segment: for sub-graph access control, this describes the scope in terms of labels or relationship types

  • role: the role the privilege is granted to

Table 2. Result
access action resource graph segment role

"GRANTED"

"read"

"all_properties"

"*"

"NODE(*)"

"admin"

"GRANTED"

"write"

"all_properties"

"*"

"NODE(*)"

"admin"

"GRANTED"

"traverse"

"graph"

"*"

"NODE(*)"

"admin"

"GRANTED"

"read"

"all_properties"

"*"

"RELATIONSHIP(*)"

"admin"

"GRANTED"

"write"

"all_properties"

"*"

"RELATIONSHIP(*)"

"admin"

"GRANTED"

"traverse"

"graph"

"*"

"RELATIONSHIP(*)"

"admin"

"GRANTED"

"access"

"database"

"*"

"database"

"admin"

"GRANTED"

"admin"

"database"

"*"

"database"

"admin"

"GRANTED"

"schema"

"database"

"*"

"database"

"admin"

"GRANTED"

"token"

"database"

"*"

"database"

"admin"

"GRANTED"

"read"

"all_properties"

"*"

"NODE(*)"

"architect"

"GRANTED"

"write"

"all_properties"

"*"

"NODE(*)"

"architect"

"GRANTED"

"traverse"

"graph"

"*"

"NODE(*)"

"architect"

"GRANTED"

"read"

"all_properties"

"*"

"RELATIONSHIP(*)"

"architect"

"GRANTED"

"write"

"all_properties"

"*"

"RELATIONSHIP(*)"

"architect"

"GRANTED"

"traverse"

"graph"

"*"

"RELATIONSHIP(*)"

"architect"

"GRANTED"

"access"

"database"

"*"

"database"

"architect"

"GRANTED"

"schema"

"database"

"*"

"database"

"architect"

"GRANTED"

"token"

"database"

"*"

"database"

"architect"

"GRANTED"

"read"

"all_properties"

"*"

"NODE(*)"

"editor"

"GRANTED"

"write"

"all_properties"

"*"

"NODE(*)"

"editor"

"GRANTED"

"traverse"

"graph"

"*"

"NODE(*)"

"editor"

"GRANTED"

"read"

"all_properties"

"*"

"RELATIONSHIP(*)"

"editor"

"GRANTED"

"write"

"all_properties"

"*"

"RELATIONSHIP(*)"

"editor"

"GRANTED"

"traverse"

"graph"

"*"

"RELATIONSHIP(*)"

"editor"

"GRANTED"

"access"

"database"

"*"

"database"

"editor"

"DENIED"

"access"

"database"

"neo4j"

"database"

"noAccessUsers"

"GRANTED"

"read"

"all_properties"

"*"

"NODE(*)"

"publisher"

"GRANTED"

"write"

"all_properties"

"*"

"NODE(*)"

"publisher"

"GRANTED"

"traverse"

"graph"

"*"

"NODE(*)"

"publisher"

"GRANTED"

"read"

"all_properties"

"*"

"RELATIONSHIP(*)"

"publisher"

"GRANTED"

"write"

"all_properties"

"*"

"RELATIONSHIP(*)"

"publisher"

"GRANTED"

"traverse"

"graph"

"*"

"RELATIONSHIP(*)"

"publisher"

"GRANTED"

"access"

"database"

"*"

"database"

"publisher"

"GRANTED"

"token"

"database"

"*"

"database"

"publisher"

"GRANTED"

"read"

"all_properties"

"*"

"NODE(*)"

"reader"

"GRANTED"

"traverse"

"graph"

"*"

"NODE(*)"

"reader"

"GRANTED"

"read"

"all_properties"

"*"

"RELATIONSHIP(*)"

"reader"

"GRANTED"

"traverse"

"graph"

"*"

"RELATIONSHIP(*)"

"reader"

"GRANTED"

"access"

"database"

"*"

"database"

"reader"

"GRANTED"

"access"

"database"

"neo4j"

"database"

"regularUsers"

Rows: 41

Available privileges for a particular role can be seen using SHOW ROLE name PRIVILEGES.

Query
SHOW ROLE regularUsers PRIVILEGES

Lists all privileges for role 'regularUsers'

Table 3. Result
access action resource graph segment role

"GRANTED"

"access"

"database"

"neo4j"

"database"

"regularUsers"

Rows: 1

Available privileges for a particular user can be seen using SHOW USER name PRIVILEGES.

Please note that if a non-native auth provider like LDAP is in use, SHOW USER PRIVILEGES will only work in a limited capacity; It is only possible for a user to show their own privileges. Other users' privileges cannot be listed when using a non-native auth provider.

Query
SHOW USER jake PRIVILEGES

Lists all privileges for user 'jake'

Table 4. Result
access action resource graph segment role user

"GRANTED"

"access"

"database"

"neo4j"

"database"

"regularUsers"

"jake"

Rows: 1

The TRAVERSE privilege

Users can be granted the right to find nodes and relationships using the GRANT TRAVERSE privilege.

Command syntax
GRANT TRAVERSE
    ON GRAPH[S] { * | name }
        [
            ELEMENT[S] { * | label-or-rel-type[, ...] }
            | NODE[S] { * | label[, ...] }
            | RELATIONSHIP[S] { * | rel-type[, ...] }
        ]
    TO role[, ...]

For example, we can allow the user jake, who has role 'regularUsers' to find all nodes with the label Post.

Query
GRANT TRAVERSE ON GRAPH neo4j NODES Post TO regularUsers

0 rows, System updates: 1

The TRAVERSE privilege can also be denied.

Command syntax
DENY TRAVERSE
    ON GRAPH[S] { * | name }
        [
            ELEMENT[S] { * | label-or-rel-type[, ...] }
            | NODE[S] { * | label[, ...] }
            | RELATIONSHIP[S] { * | rel-type[, ...] }
        ]
    TO role[, ...]

For example, we can disallow the user jake, who has role 'regularUsers' to find all nodes with the label Payments.

Query
DENY TRAVERSE ON GRAPH neo4j NODES Payments TO regularUsers

0 rows, System updates: 1

The READ privilege

Users can be granted the right to do property reads on nodes and relationships using the GRANT READ privilege. It is very important to note that users can only read properties on entities that they are allowed to find in the first place.

Command syntax
GRANT READ
    "{" { * | property[, ...] } "}"
    ON GRAPH[S] { * | name }
        [
            ELEMENT[S] { * | label-or-rel-type[, ...] }
            | NODE[S] { * | label[, ...] }
            | RELATIONSHIP[S] { * | rel-type[, ...] }
        ]
    TO role[, ...]

For example, we can allow the user jake, who has role 'regularUsers' to read all properties on nodes with the label Post. The * implies that the ability to read all properties also extends to properties that might be added in the future.

Query
GRANT READ { * } ON GRAPH neo4j NODES Post TO regularUsers

0 rows, System updates: 1

The READ privilege can also be denied.

Command syntax
DENY READ
    "{" { * | property[, ...] } "}"
    ON GRAPH[S] { * | name }
        [
            ELEMENT[S] { * | label-or-rel-type[, ...] }
            | NODE[S] { * | label[, ...] }
            | RELATIONSHIP[S] { * | rel-type[, ...] }
        ]
    TO role[, ...]

Although we just granted the user 'jake' the right to read all properties, we may want to hide the secret property. The following example shows how to do that.

Query
DENY READ { secret } ON GRAPH neo4j NODES Post TO regularUsers

0 rows, System updates: 1

The MATCH privilege

As a shorthand for TRAVERSE and READ, users can be granted the right to find and do property reads on nodes and relationships using the GRANT MATCH privilege.

Command syntax
GRANT MATCH
    "{" { * | property[, ...] } "}"
    ON GRAPH[S] { * | name }
        [
            ELEMENT[S] { * | label-or-rel-type[, ...] }
            | NODE[S] { * | label[, ...] }
            | RELATIONSHIP[S] { * | rel-type[, ...] }
        ]
    TO role[, ...]

For example if you want to grant the ability to read the properties language and length for nodes with the label Message, as well as the ability to find these nodes, to a role regularUsers you can use the following GRANT MATCH query.

Query
GRANT MATCH { language, length } ON GRAPH neo4j NODES Message TO regularUsers

0 rows, System updates: 3

Like all other privileges, the MATCH privilege can also be denied.

Command syntax
DENY MATCH
    "{" { * | property[, ...] } "}"
    ON GRAPH[S] { * | name }
        [
            ELEMENT[S] { * | label-or-rel-type[, ...] }
            | NODE[S] { * | label[, ...] }
            | RELATIONSHIP[S] { * | rel-type[, ...] }
        ]
    TO role[, ...]

Please note that the effect of denying a MATCH privilege depends on whether concrete property keys are specified or a *. If you specify concrete property keys then DENY MATCH will only deny reading those properties. Finding the elements to traverse would still be allowed. If you specify * instead then both traversal of the element and all property reads will be disallowed. The following queries will show examples for this.

Denying to read the property ´content´ on nodes with the label Message for the role regularUsers would look like the following query. Although not being able to read this specific property, nodes with that label can still be traversed (and, depending on other grants, other properties on it could still be read).

Query
DENY MATCH { content } ON GRAPH neo4j NODES Message TO regularUsers

0 rows, System updates: 1

The following query exemplifies how it would look like if you want to deny both reading all properties and traversing nodes labeled with Account.

Query
DENY MATCH { * } ON GRAPH neo4j NODES Account TO regularUsers

0 rows, System updates: 2

Please note that REVOKE MATCH is not allowed, instead revoke the individual READ and TRAVERSE privileges.

The WRITE privilege

The WRITE privilege enables you to write on a graph.

Command syntax
GRANT WRITE
    ON GRAPH[S] { * | name }
    TO role[, ...]

For example, granting the ability to write on the graph neo4j to the role regularUsers would be achieved using:

Query
GRANT WRITE ON GRAPH neo4j TO regularUsers

0 rows, System updates: 2

Unlike with GRANT READ it is not possible to restrict WRITE privileges to specific ELEMENTS, NODES or RELATIONSHIPS.

For example, using NODES A will produce a syntax error.

Query
GRANT WRITE ON GRAPH neo4j NODES A TO regularUsers

The use of ELEMENT, NODE or RELATIONSHIP with the WRITE privilege is not supported in this version. (line 1, column 1 (offset: 0))
"GRANT WRITE ON GRAPH neo4j NODES A TO regularUsers"
^

The WRITE privilege can also be denied.

Command syntax
DENY WRITE
    ON GRAPH[S] { * | name }
    TO role[, ...]

For example, denying the ability to write on the graph neo4j to the role regularUsers would be achieved using:

Query
DENY WRITE ON GRAPH neo4j TO regularUsers

0 rows, System updates: 2

Users with WRITE privilege but restricted TRAVERSE privileges will not be able to do DETACH DELETE in all cases. See Operations Manual → Fine-grained access control for more info.

The REVOKE command

Privileges that were granted or denied earlier can be revoked using the REVOKE command.

Command syntax
REVOKE
    [ GRANT | DENY ] privilege
    FROM role[, ...]

Please note that REVOKE MATCH is not allowed, instead revoke the individual READ and TRAVERSE privileges.

An example usage of the REVOKE command is given here:

Query
REVOKE GRANT TRAVERSE ON GRAPH neo4j NODES Post FROM regularUsers

0 rows, System updates: 1

While it can be explicitly specified that revoke should remove a GRANT or DENY, it is also possible to revoke either one by not specifying at all as the next example demonstrates. Because of this, if there happen to be a GRANT and a DENY on the same privilege, it would remove both.

Query
REVOKE TRAVERSE ON GRAPH neo4j NODES Payments FROM regularUsers

0 rows, System updates: 2

Some privileges are compound privileges and contains sub-privileges, for example INDEX MANAGEMENT which covers CREATE INDEX and DROP INDEX. When these compound privileges are revoked, all sub-privileges matching the revoke command will also be revoked as shown in the example below.

Add CREATE INDEX and DROP INDEX privileges
GRANT CREATE INDEX ON DATABASE * TO indexUsers
GRANT DROP INDEX ON DATABASE * TO indexUsers
Query
REVOKE INDEX MANAGEMENT ON DATABASE * FROM indexUsers

0 rows, System updates: 2

Query
SHOW ROLE indexUsers PRIVILEGES

Both the CREATE INDEX and DROP INDEX privileges have been revoked:

Table 5. Result

(empty result)

Rows: 0