Property-based access controlAuraDB Business CriticalAuraDB Virtual Dedicated CloudEnterprise Edition
Property-based access control grants or denies permission to read or traverse nodes or relationships based on property/value conditions. Each property-based privilege can only be restricted by a single property. For information about the syntax of these privileges, see Read privileges.
|
When using property-based access control, ensure the property used for the rule cannot be modified. Users who can change this property can affect the granted property-based privileges. |
Syntax
To specify the property/value conditions of the privilege, you can use the following syntax:
{GRANT | DENY | REVOKE [GRANT | DENY]}
[IMMUTABLE]
{MATCH | READ | TRAVERSE}
ON { HOME GRAPH | GRAPH[S] { * | name[, ...] } }
[
ELEMENT[S] { * | label-or-rel-type[, ...] }
| NODE[S] { * | label[, ...] }
| RELATIONSHIP[S] { * | rel-type[, ...] }
| FOR {
([var][:label["|" ...]] "{" property: value "}")
| (var[:label["|" ...]])
WHERE [NOT] var.property { { = | <> | > | >= | < | <= } value | IS NULL | IS NOT NULL | IN { "["[value[, ...]]"]" | listParam } }
| (var[:label["|" ...]]
WHERE [NOT] var.property { { = | <> | > | >= | < | <= } value | IS NULL | IS NOT NULL | IN { "["[value[, ...]]"]" | listParam } } )
| ()[<]-"["[var][:type["|" ...]] "{" property: value "}" "]"-[>]()
| ()[<]-"["var[:type["|" ...]]"]"-[>]()
WHERE [NOT] var.property { { = | <> | > | >= | < | <= } value | IS NULL | IS NOT NULL | IN { "["[value[, ...]]"]" | listParam } }
| ()[<]-"["var[:type["|" ...]]
WHERE [NOT] var.property { { = | <> | > | >= | < | <= } value | IS NULL | IS NOT NULL | IN { "["[value[, ...]]"]" | listParam } } "]"-[>]()
}
]
{TO | FROM} role[, ...]
Performance considerations
Adding property-based access control may lead to a significant performance overhead in certain scenarios. See Limitations for more detailed information.
When having property rules, the following factors can worsen the impact on performance:
-
The number of properties on the nodes and relationships concerned (more properties = greater performance impact).
-
The number of property-based privileges (more property-based privileges = greater performance impact).
-
The type of the privilege:
TRAVERSEproperty-based privileges have greater performance impact thanREADproperty-based privileges. -
The type of storage medium in operation. The impact of the property-based privileges on performance is considerably amplified by accessing disc storage.
To reduce the performance impact, it is recommended to use the block storage format as it is better optimized for the kind of read required for the resolution of property-based privileges.
For performance-critical scenarios, it is recommended to design privileges based on labels.
Examples
You can use the following syntax for defining a property-based privilege:
GRANT privilege-name ON GRAPH graph-name FOR pattern TO role-name
|
The user role does not need to have |
Grant a property-based privilege on a specific property using the value of another property
The following example shows how to grant permission to READ the address property on Email or Website nodes with domain exampledomain.com to role regularUsers:
GRANT READ { address } ON GRAPH * FOR (n:Email|Website) WHERE n.domain = 'exampledomain.com' TO regularUsers
Alternatively, you can use the following syntax:
GRANT READ { address } ON GRAPH * FOR (:Email|Website {domain: 'exampledomain.com'}) TO regularUsers
The following example shows how to grant permission to READ the since property on OWNS relationships having classification equal to UNCLASSIFIED to role regularUsers:
GRANT READ { since } ON GRAPH * FOR ()-[o:OWNS]-() WHERE o.classification = 'UNCLASSIFIED' TO regularUsers
Grant a property-based privilege using NULL
The following example shows how to grant permission to TRAVERSE nodes with the label Email where property classification is NULL to role regularUsers:
GRANT TRAVERSE ON GRAPH * FOR (n:Email) WHERE n.classification IS NULL TO regularUsers
Deny a property-based privilege using a comparison operator
The following example shows how to deny permission to READ and TRAVERSE nodes and relationships where the property classification is different from UNCLASSIFIED to role regularUsers:
DENY MATCH {*} ON GRAPH * FOR (n) WHERE n.classification <> 'UNCLASSIFIED' TO regularUsers
DENY MATCH {*} ON GRAPH * FOR ()-[r]-() WHERE r.classification <> 'UNCLASSIFIED' TO regularUsers
Grant a property-based privilege on all properties using a property value
The following example shows how to grant permission to READ all properties on nodes and relationships where the property securityLevel is higher than 3 to role regularUsers:
GRANT READ {*} ON GRAPH * FOR (n) WHERE n.securityLevel > 3 TO regularUsers
GRANT READ {*} ON GRAPH * FOR ()-[r]-() WHERE r.securityLevel > 3 TO regularUsers
|
The role |
Deny a property-based privilege using a list of values
The following example shows how to deny permission to READ all properties on nodes and relationships where the property classification is not included in the list of [UNCLASSIFIED, PUBLIC]:
DENY READ {*} ON GRAPH * FOR (n) WHERE NOT n.classification IN ['UNCLASSIFIED', 'PUBLIC'] TO regularUsers
DENY READ {*} ON GRAPH * FOR ()-[r]-() WHERE NOT r.classification IN ['UNCLASSIFIED', 'PUBLIC'] TO regularUsers
Grant a property-based privilege using temporal value
The following example shows how to grant permission to READ all properties on nodes and relationships where the property createdAt is later than the current date:
GRANT READ {*} ON GRAPH * FOR (n) WHERE n.createdAt > date() TO regularUsers
GRANT READ {*} ON GRAPH * FOR ()-[r]-() WHERE r.createdAt > date() TO regularUsers
|
The |
|
Not all temporal values are comparable, see Cypher Manual → Equality, ordering, and comparison of value types. |
You can show the privilege created by the command in the previous example as a revoke command by running:
SHOW ROLE regularUsers PRIVILEGES AS REVOKE COMMANDS
| command |
|---|
Rows: 2 |