Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -390,8 +390,9 @@ So due to the additional data access required by the security checks, this opera

[[property-based-access-control-limitations]]
=== Property-based access control limitations
Extra node-level security checks are necessary when adding security rules based on property rules, and these can have a significant performance impact.
The following example shows how the database behaves when adding security rules to roles `restricted` and `unrestricted`:
Extra element-level security checks are necessary when adding security rules based on property rules, and these can have a significant performance impact.

The following example shows how the database behaves when adding security rules for nodes to roles `restricted` and `unrestricted`, the same limitations apply to relationships as well:

[source, cypher]
----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ CREATE ROLE regularUsers;
[[property-based-access-control]]
= Property-based access control

Property-based access control grants permissions to users to read node properties based on property/value conditions.
Property-based access control grants/denies permission to read or traverse elements based on property/value conditions.
Each property-based privilege can only be restricted by a single property.
For information about read privileges and their syntax, see xref:authentication-authorization/privileges-reads.adoc[Read privileges].
For information and syntax for these privileges, see xref:authentication-authorization/privileges-reads.adoc[Read privileges].

[IMPORTANT]
====
Expand All @@ -25,7 +25,7 @@ Users who can change this property can affect the granted property-based privile

== Syntax

To specify the property/value conditions of the read privilege, you can use the following syntax:
To specify the property/value conditions of the privilege, you can use the following syntax:

[source, syntax, role="noheader"]
----
Expand All @@ -40,7 +40,9 @@ To specify the property/value conditions of the read privilege, you can use the
| FOR {

([var][:label["|" ...]] "{" property: value "}")
| (var[:label["|" ...]])
| (var[:label["|" ...]])
| ()[<]-"["[var][:type["|" ...]] "{" property: value "}" "]"-[>]()
| ()[<]-"["var[:type["|" ...]]"]"-[>]()
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 } } )
Expand All @@ -57,7 +59,7 @@ See xref:authentication-authorization/limitations.adoc#property-based-access-con

When having property rules, the following factors can worsen the impact on performance:

* The number of properties on the nodes concerned (more properties = greater performance impact).
* The number of properties on the elements concerned (more properties = greater performance impact).
* The number of property-based privileges (more property-based privileges = greater performance impact).
* The type of the privilege: `TRAVERSE` property-based privileges have greater performance impact than `READ` property-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.
Expand All @@ -81,7 +83,7 @@ GRANT privilege-name ON GRAPH graph-name FOR pattern TO role-name
The user role does not need to have `READ` privilege for the property used by the property-based privilege.
====

=== Grant a property-based privilege on a specific property using its value
=== 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`:

Expand All @@ -97,6 +99,14 @@ Alternatively, you can use the following syntax:
GRANT READ { address } ON GRAPH * FOR (:Email|Website {domain: 'exampledomain.com'}) TO regularUsers
----

=== 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 `since` property on `OWNS` relationships having `classification` equal to `UNCLASSIFIED` to role `regularUsers`:

[source, syntax, role="noheader"]
----
GRANT READ { since } ON GRAPH * FOR ()-[o:OWNS]-() WHERE o.classification = 'UNCLASSIFIED' TO regularUsers
----

=== Grant a property-based privilege using `NULL`

Expand All @@ -109,20 +119,22 @@ GRANT TRAVERSE ON GRAPH * FOR (n:Email) WHERE n.classification IS NULL TO regula

=== Deny a property-based privilege using a comparison operator

The following example shows how to deny permission to `READ` and `TRAVERSE` nodes where the property `classification` is different from `UNCLASSIFIED` to role `regularUsers`:
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`:

[source, syntax, role="noheader"]
----
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 where the property `securityLevel` is higher than `3` to role `regularUsers`:
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`:

[source, syntax, role="noheader"]
----
GRANT READ {*} ON GRAPH * FOR (n) WHERE n.securityLevel > 3 TO regularUsers
GRANT READ {*} ON GRAPH * FOR ()-[r]-() WHERE r.securityLevel > 3 TO regularUsers
----

[NOTE]
Expand All @@ -132,22 +144,24 @@ The role `regularUsers` does not need to have `READ` privilege for the property

=== Deny a property-based privilege using a list of values

The following example shows how to deny permission to `READ` all properties on nodes where the property `classification` is not included in the list of `[UNCLASSIFIED, PUBLIC]`:
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]`:

[source, syntax, role="noheader"]
----
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
----

// The last two examples were added in 5.26.

=== Grant a property-based privilege using temporal value

The following example shows how to grant permission to `READ` all properties on nodes where the property `createdAt` is later than the current date:
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:

[source, syntax, role="noheader"]
----
GRANT READ {*} ON GRAPH * FOR (n) WHERE n.createdAt > date() TO regularUsers
GRANT READ {*} ON GRAPH * FOR ()-[r]-() WHERE r.createdAt > date() TO regularUsers
----

[NOTE]
Expand All @@ -174,6 +188,7 @@ SHOW ROLE regularUsers PRIVILEGES AS REVOKE COMMANDS
|===
|command
|"REVOKE GRANT READ {*} ON GRAPH * FOR (n) WHERE n.createdAt > date('2024-10-25') FROM `regularUsers`"
a|Rows: 1
|"REVOKE GRANT READ {*} ON GRAPH * FOR ()-[r]-() WHERE r.createdAt > date('2024-10-25') FROM `regularUsers`"
a|Rows: 2
|===