Skip to content

Commit 1ceeb0f

Browse files
committed
Restyle RBAC limitations
1 parent e6cd341 commit 1ceeb0f

File tree

1 file changed

+57
-50
lines changed

1 file changed

+57
-50
lines changed

modules/ROOT/pages/authentication-authorization/limitations.adoc

Lines changed: 57 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,32 @@ CREATE ROLE unrestricted;
1414
[[access-control-limitations]]
1515
= Limitations
1616

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.
1823

1924
[[access-control-limitations-indexes]]
2025
== Security and indexes
2126

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.
2329

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],
2733
the index will also return the same fewer results.
2834

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.
3339

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.
3743

3844
=== Example with denied properties
3945

@@ -54,16 +60,16 @@ Full-text indexes support multiple labels.
5460
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.
5561
====
5662

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.
5864
However, this is not completely accurate.
5965
The composite and full-text indexes behave in different ways and are focused on different use cases.
6066
A key difference is that full-text indexes are backed by _Lucene_, and will use the _Lucene_ syntax for querying.
6167

6268
This has consequences for users restricted on the labels or properties involved in the indexes.
6369
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.
6571

66-
Imagine the following nodes were added to the database:
72+
Imagine the following nodes are added to the database:
6773

6874
[source, cypher]
6975
----
@@ -120,7 +126,7 @@ CALL db.index.fulltext.queryNodes("userNames", "ndy") YIELD node, score
120126
RETURN node.name
121127
----
122128

123-
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.
124130
The steps taken by the query engine would be:
125131

126132
* 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
186192

187193
=== Traversing the graph with multi-labeled nodes
188194

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].
193202

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.
197203

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.
200206

207+
For example, if a user has the following role:
201208
[source, cypher]
202209
----
203210
GRANT TRAVERSE ON GRAPH * NODES A TO custom
204211
----
205212

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:
208215
[source, cypher]
209216
----
210217
MATCH (n:A)
211218
RETURN n, labels(n)
212219
----
220+
They will get a result with two nodes: the node with label `:A` and the node with labels `:A :B`.
213221

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:
217223

218224
[source, cypher]
219225
----
220226
MATCH (n:B)
221227
RETURN n, labels(n)
222228
----
223229

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.
226232

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.
228234
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:
230236

231237
[source, cypher]
232238
----
233239
DENY TRAVERSE ON GRAPH * NODES B TO custom
234240
----
235241

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
237244

238245
[source, cypher]
239246
----
@@ -257,25 +264,22 @@ In contrast to the normal graph traversal described in the previous section, the
257264
That means:
258265

259266
* 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.
264268

269+
For example, if a user has the following role:
265270
[source, cypher]
266271
----
267272
GRANT TRAVERSE ON GRAPH * NODES A TO custom
268273
----
269274

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:
273277
[source, cypher]
274278
----
275279
CALL db.labels()
276280
----
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.
279283

280284
[[access-control-limitations-non-existing-labels]]
281285
=== 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 `
332336
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.
333337

334338

335-
336339
[[access-control-limitations-db-operations]]
337340
== Security and performance
338341

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.
341345
For example, count store operations, which are usually fast lookups, may experience notable differences in performance.
342346

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.
344350

345351
[source, cypher]
346352
----
@@ -389,10 +395,11 @@ So due to the additional data access required by the security checks, this opera
389395
|===
390396

391397
[[property-based-access-control-limitations]]
392-
=== Property-based access control limitations
398+
=== Security rules based on property rules and performance
399+
393400
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.
394401

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`.
396403
The same limitations apply to relationships.
397404

398405
[source, cypher]

0 commit comments

Comments
 (0)