You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: modules/ROOT/pages/authentication-authorization/limitations.adoc
+57-50Lines changed: 57 additions & 50 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,26 +14,32 @@ CREATE ROLE unrestricted;
14
14
[[access-control-limitations]]
15
15
= Limitations
16
16
17
-
The known limitations and implications of Neo4j's role-based access control security are described in this section.
17
+
Using Neo4j's role-based access control imposes some limitations and implications that users should be aware of, such as:
18
+
19
+
* Impact on query results regardless of whether the indexes are used.
20
+
* Impact results when nodes have multiple labels.
21
+
* Potential performance impacts when querying large graphs with complex security rules.
22
+
* The need for careful management of user roles and privileges to avoid unintended data exposure.
18
23
19
24
[[access-control-limitations-indexes]]
20
25
== Security and indexes
21
26
22
-
As described in link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/overview/[Cypher Manual -> Indexes for search performance], Neo4j {neo4j-version} supports the creation and use of indexes to improve the performance of Cypher queries.
27
+
Neo4j lets you create and use indexes to speed up Cypher queries.
28
+
See the link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/[Cypher Manual -> Indexes] for more details on the different types of indexes available in Neo4j.
23
29
24
-
Note that the Neo4j security model impacts the results of queries, regardless if the indexes are used or not.
25
-
When using non full-text Neo4j indexes, a Cypher query will always return the same results it would have if no index existed.
26
-
This means that, if the security model causes fewer results to be returned due to restricted read access in xref:authentication-authorization/manage-privileges.adoc[Graph and sub-graph access control],
30
+
However, Neo4j’s security model still controls what results you see, regardless of whether or not you use indexes.
31
+
For example, when you use link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/overview/[search-performance indexes] (non–full-text) indexes, queries return the same results they would without any index.
32
+
This means that, if the security model causes fewer results to be returned due to restricted read access in xref:authentication-authorization/manage-privileges.adoc[graph and sub-graph access control],
27
33
the index will also return the same fewer results.
28
34
29
-
However, this rule is not fully obeyed by link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/semantic-indexes/full-text-indexes/[Cypher Manual -> Indexes for full-text search].
30
-
These specific indexes are backed by _Lucene_ internally.
31
-
It is therefore not possible to know for certain whether a security violation has affected each specific entry returned from the index.
32
-
In face of this, Neo4j will return zero results from full-text indexes in case it is determined that any result might be violating the security privileges active for that query.
35
+
link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/semantic-indexes/full-text-indexes/[Full-text indexes] work differently.
36
+
These indexes use Lucene under the hood.
37
+
Because of that, Neo4j cannot check whether a security violation has affected each specific entry returned from the index.
38
+
So, if there is any chance a result might violate active security privileges for a query, Neo4j returns zero results from the full-text indexes.
33
39
34
-
Since full-text indexes are not automatically used by Cypher, they do not lead to the case where the same Cypher query would return different results simply because such an index was created.
35
-
Users need to explicitly call procedures to use these indexes.
36
-
The problem is only that, if this behavior is not known by the user, they might expect the full-text index to return the same results that a different, but semantically similar, Cypher query does.
40
+
Also, Cypher does not use full-text indexes automatically — you have to explicitly call procedures to use them.
41
+
This avoids a situation where the same Cypher query would return different results simply because such an index exists.
42
+
The problem is that if you do not know this behavior, you might expect the full-text index to return the same results that a different but semantically similar Cypher query does.
37
43
38
44
=== Example with denied properties
39
45
@@ -54,16 +60,16 @@ Full-text indexes support multiple labels.
54
60
See link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/semantic-indexes/full-text-indexes//[Cypher Manual -> Indexes for full-text search] for more details on creating and using full-text indexes.
55
61
====
56
62
57
-
After creating these indexes, it would appear that the latter two indexes accomplish the same thing.
63
+
After creating these indexes, it may look that the latter two indexes accomplish the same thing.
58
64
However, this is not completely accurate.
59
65
The composite and full-text indexes behave in different ways and are focused on different use cases.
60
66
A key difference is that full-text indexes are backed by _Lucene_, and will use the _Lucene_ syntax for querying.
61
67
62
68
This has consequences for users restricted on the labels or properties involved in the indexes.
63
69
Ideally, if the labels and properties in the index are denied, they can correctly return zero results from both native indexes and full-text indexes.
64
-
However, there are borderline cases where this is not as simple.
70
+
However, there are borderline cases where this is not that simple.
65
71
66
-
Imagine the following nodes were added to the database:
72
+
Imagine the following nodes are added to the database:
The problem now is that it is not certain whether the results provided by the index were achieved due to a match to the `name` or the `surname` property.
129
+
The problem now is that it is not certain whether the results provided by the index are achieved due to a match to the `name` or the `surname` property.
124
130
The steps taken by the query engine would be:
125
131
126
132
* Run a _Lucene_ query on the full-text index to produce results containing `ndy` in either property, leading to five results.
@@ -186,54 +192,55 @@ In this case, the query will return zero results rather than simply returning th
186
192
187
193
=== Traversing the graph with multi-labeled nodes
188
194
189
-
The general influence of access control privileges on graph traversal is described in detail in xref:authentication-authorization/manage-privileges.adoc[Graph and sub-graph access control].
190
-
The following section will only focus on nodes due to their ability to have multiple labels.
191
-
Relationships can only have one type of label and thus they do not exhibit the behavior this section aims to clarify.
192
-
While this section will not mention relationships further, the general function of the traverse privilege also applies to them.
195
+
In Neo4j, nodes can have multiple labels, but relationships only have one type.
196
+
This is important when it comes to controlling who can see what.
197
+
198
+
The following section only focuses on nodes because they can have multiple labels.
199
+
The same general rules apply to relationships, but they are simpler.
200
+
201
+
For details on the general influence of access control privileges on graph traversal, see xref:authentication-authorization/manage-privileges.adoc[Graph and sub-graph access control].
193
202
194
-
For any node that is traversable, due to `GRANT TRAVERSE` or `GRANT MATCH`,
195
-
the user can get information about the attached labels by calling the built-in `labels()` function.
196
-
In the case of nodes with multiple labels, they can be returned to users that weren't directly granted access to.
197
203
198
-
To give an illustrative example, imagine a graph with three nodes: one labeled `:A`, another labeled `:B` and one with the labels `:A` and `:B`.
199
-
In this case, there is a user with the role `custom` defined by:
204
+
If a user is granted access to a traversable node using `GRANT TRAVERSE` or `GRANT MATCH`, they will be able to get information about the attached labels by calling the built-in `labels()` function.
205
+
In the case of nodes with multiple labels, this means that the user will be able to see all labels attached to the node, even if they were not granted access to traverse on some of those labels.
200
206
207
+
For example, if a user has the following role:
201
208
[source, cypher]
202
209
----
203
210
GRANT TRAVERSE ON GRAPH * NODES A TO custom
204
211
----
205
212
206
-
If that user were to execute
207
-
213
+
And the graph contains three nodes: one labeled `:A`, another labeled `:B`, and one with both labels `:A` and `:B`.
214
+
If the user executes the following query:
208
215
[source, cypher]
209
216
----
210
217
MATCH (n:A)
211
218
RETURN n, labels(n)
212
219
----
220
+
They will get a result with two nodes: the node with label `:A` and the node with labels `:A :B`.
213
221
214
-
They would get a result with two nodes: the node that was labeled with `:A` and the node with labels `:A :B`.
215
-
216
-
In contrast, executing
222
+
In contrast, if the user executes:
217
223
218
224
[source, cypher]
219
225
----
220
226
MATCH (n:B)
221
227
RETURN n, labels(n)
222
228
----
223
229
224
-
This will return only the one node that has both labels: `:A` and `:B`.
225
-
Even though `:B` did not have access to traversals, there is one node with that label accessible in the dataset due to the allow-listed label `:A` that is attached to the same node.
230
+
They will get only the node that has both labels: `:A` and `:B`.
231
+
Even though `:B` does not have access to traversals, there is one node with that label accessible in the dataset due to the allow-listed label `:A` that is attached to the same node.
226
232
227
-
If a user is denied to traverse on a label they will never get results from any node that has this label attached to it.
233
+
If a user is denied to traverse on a label, they will never get results from any node that has this label attached to it.
228
234
Thus, the label name will never show up for them.
229
-
As an example, this can be done by executing:
235
+
For example, if the user has the following role:
230
236
231
237
[source, cypher]
232
238
----
233
239
DENY TRAVERSE ON GRAPH * NODES B TO custom
234
240
----
235
241
236
-
The query
242
+
And the graph contains the same three nodes as before, the user will not be able to traverse the node with label `:B`.
243
+
Thus, the query
237
244
238
245
[source, cypher]
239
246
----
@@ -257,25 +264,22 @@ In contrast to the normal graph traversal described in the previous section, the
257
264
That means:
258
265
259
266
* If a label is explicitly whitelisted (granted), it will be returned by this procedure.
260
-
* If a label is denied or isn't explicitly allowed, it will not be returned by this procedure.
261
-
262
-
Reusing the previous example, imagine a graph with three nodes: one labeled `:A`, another labeled `:B` and one with the labels `:A` and `:B`.
263
-
In this case, there is a user with the role `custom` defined by:
267
+
* If a label is denied or is not explicitly allowed, it will not be returned by this procedure.
264
268
269
+
For example, if a user has the following role:
265
270
[source, cypher]
266
271
----
267
272
GRANT TRAVERSE ON GRAPH * NODES A TO custom
268
273
----
269
274
270
-
This means that only label `:A` is explicitly allow-listed.
271
-
Thus, executing
272
-
275
+
and the graph contains three nodes: one labeled `:A`, another labeled `:B`, and one with both labels `:A` and `:B`,
276
+
the user will be able to execute the following query:
273
277
[source, cypher]
274
278
----
275
279
CALL db.labels()
276
280
----
277
-
278
-
will only return label `:A`, because that is the only label for which traversal was granted.
281
+
This will return a list of labels, which in this case will only include the label `:A`.
282
+
The label `:B` will not be returned, because the user does not have access to traverse on it.
=== Privileges for non-existing labels, relationship types, and property names
@@ -332,15 +336,17 @@ To ensure success on the first attempt, when setting up the privileges for the `
332
336
In this example, when creating the custom role, connect to `testing` and run `CALL db.createLabel('A')` to ensure Alice creates the node successfully on her first attempt.
333
337
334
338
335
-
336
339
[[access-control-limitations-db-operations]]
337
340
== Security and performance
338
341
339
-
The rules of a security model may impact the performance of some database operations.
340
-
This is because extra security checks are necessary, and they require additional data access.
342
+
=== Security rules and database operations
343
+
344
+
The rules of a security model may impact the performance of some database operations, because Neo4j has to do extra security checks, which require additional data access.
341
345
For example, count store operations, which are usually fast lookups, may experience notable differences in performance.
342
346
343
-
The following example shows how the database behaves when adding security rules to roles `restricted` and `unrestricted`:
347
+
Let's take the following example.
348
+
The database has two roles defined `restricted` and `unrestricted`.
349
+
The `restricted` role has limited access to traversals, while the `unrestricted` role has no restrictions.
344
350
345
351
[source, cypher]
346
352
----
@@ -389,10 +395,11 @@ So due to the additional data access required by the security checks, this opera
389
395
|===
390
396
391
397
[[property-based-access-control-limitations]]
392
-
=== Property-based access control limitations
398
+
=== Security rules based on property rules and performance
399
+
393
400
Extra node or relationship-level security checks are necessary when adding security rules based on property rules, and these can have a significant performance impact.
394
401
395
-
The following example shows how the database behaves when adding security rules for nodes to roles `restricted` and `unrestricted`.
402
+
The following example shows how the database behaves when adding security rules for nodes to roles `restricted` and `unrestricted`.
0 commit comments