From d227601efbe13ad6bcaffa6806da98a6caed6444 Mon Sep 17 00:00:00 2001 From: Colin Barry Date: Wed, 29 Oct 2025 11:28:53 +0000 Subject: [PATCH 01/12] chore: Empty commit just to create PR From abc097e98b02adf8dc0d63f818e38809849749f7 Mon Sep 17 00:00:00 2001 From: Colin Barry Date: Wed, 29 Oct 2025 11:55:01 +0000 Subject: [PATCH 02/12] doc: Update syntax for multi-tenancy setup --- pages/database-management/multi-tenancy.mdx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pages/database-management/multi-tenancy.mdx b/pages/database-management/multi-tenancy.mdx index e5933fb2d..49129b3ba 100644 --- a/pages/database-management/multi-tenancy.mdx +++ b/pages/database-management/multi-tenancy.mdx @@ -65,17 +65,17 @@ CREATE ROLE tenant2_user; -- Grant appropriate permissions to tenant roles GRANT MATCH, CREATE, MERGE, SET, DELETE, INDEX TO tenant1_admin; -GRANT CREATE_DELETE ON LABELS * TO tenant1_admin; -GRANT CREATE_DELETE ON EDGE_TYPES * TO tenant1_admin; +GRANT CREATE, READ, UPDATE, DELETE ON NODES CONTAINING LABELS * TO tenant1_admin; +GRANT CREATE, READ, UPDATE, DELETE ON EDGES CONTAINING TYPES * TO tenant1_admin; GRANT MATCH, CREATE, MERGE, SET, DELETE TO tenant1_user; -GRANT CREATE_DELETE ON LABELS * TO tenant1_user; -GRANT CREATE_DELETE ON EDGE_TYPES * TO tenant1_user; +GRANT CREATE, READ, UPDATE, DELETE ON NODES CONTAINING LABELS * TO tenant1_user; +GRANT CREATE, READ, UPDATE, DELETE ON EDGES CONTAINING TYPES * TO tenant1_user; GRANT MATCH, CREATE, MERGE, SET, DELETE, INDEX TO tenant2_admin; -GRANT CREATE_DELETE ON LABELS * TO tenant2_admin; -GRANT CREATE_DELETE ON EDGE_TYPES * TO tenant2_admin; +GRANT CREATE, READ, UPDATE, DELETE ON NODES CONTAINING LABELS * TO tenant2_admin; +GRANT CREATE, READ, UPDATE, DELETE ON EDGES CONTAINING TYPES * TO tenant2_admin; GRANT MATCH, CREATE, MERGE, SET, DELETE TO tenant2_user; -GRANT CREATE_DELETE ON LABELS * TO tenant2_user; -GRANT CREATE_DELETE ON EDGE_TYPES * TO tenant2_user; +GRANT CREATE, READ, UPDATE, DELETE ON NODES CONTAINING LABELS * TO tenant2_user; +GRANT CREATE, READ, UPDATE, DELETE ON EDGES CONTAINING TYPES * TO tenant2_user; -- Grant access only to tenant databases GRANT DATABASE tenant1_db TO tenant1_admin, tenant1_user; From 735729f14e60e358d70fb05728c2b26e48231fce Mon Sep 17 00:00:00 2001 From: Colin Barry Date: Fri, 7 Nov 2025 09:48:59 +0000 Subject: [PATCH 03/12] docs: Changes for new fine-grained access permissions --- .../role-based-access-control.mdx | 242 ++++++++++++------ 1 file changed, 170 insertions(+), 72 deletions(-) diff --git a/pages/database-management/authentication-and-authorization/role-based-access-control.mdx b/pages/database-management/authentication-and-authorization/role-based-access-control.mdx index e83499792..16de27fb4 100644 --- a/pages/database-management/authentication-and-authorization/role-based-access-control.mdx +++ b/pages/database-management/authentication-and-authorization/role-based-access-control.mdx @@ -20,18 +20,18 @@ privileges to roles, but for even more control over who can access certain data, Memgraph Enterprise offers [fine-grained access control](#fine-grained-access-control). Additionally, you can use [user profiles](/database-management/authentication-and-authorization/user-profiles) -to set resource limits for users. +to set resource limits for users. [Multi-role users and multi-tenant roles](/database-management/authentication-and-authorization/multiple-roles) for more information regarding assigning multiple roles to users or assigning roles for a specific database. -## User roles +## User roles Users can be assigned multiple roles simultaneously, with permissions from all roles being combined. User roles are abstractions that capture the privilege -levels of a set of users. +levels of a set of users. For example, suppose that `Dominik` and `Marko` belong to the upper management of a certain company. It makes sense to grant them a set of privileges that @@ -52,7 +52,9 @@ following rules: permission - **Database Access**: If any role grants access to a database, the user has access -- **Fine-grained Permissions**: Combined using the same grant/deny logic +- **Fine-grained Permissions**: Label-based and edge type permissions are merged +using grant/deny logic. See [Label-based access control](#label-based-access-control) +below for details on how fine-grained permissions work and are combined. To create a user role, run the following query: @@ -186,7 +188,7 @@ roles. All system queries (auth, replication and multi-database) now target the default "memgraph" database. Meaning that in order to execute one of these queries, a user must have the appropriate privilege AND access to "memgraph" database. The recommendation is to use the default "memgraph" database as an -admin/system database and store graphs under other databases. +admin/system database and store graphs under other databases. @@ -272,7 +274,7 @@ NULL | DENY | DENY NULL | NULL | DENY Once the privileges are changed, they take full effect once the user reconnects -to the database. +to the database. #### Grant privileges @@ -289,7 +291,7 @@ For example, to grant `AUTH` and `INDEX` privileges to users with the ```cypher GRANT AUTH, INDEX TO moderator: ``` -#### Deny privileges +#### Deny privileges Similarly, denying privileges is done using the `DENY` keyword instead of `GRANT`. @@ -341,11 +343,11 @@ REVOKE ALL PRIVILEGES FROM ; The user needs to reconnect to the database for the changes to take effect. - + If you get an error: `Vertex not created due to not having enough permission!` you probably need to grant the fine-grained access control to the user. The [fine-grained access control](#fine-grained-access-control) -section provides more details. +section provides more details. @@ -380,7 +382,7 @@ SHOW PRIVILEGES FOR user_or_role ON DATABASE database_name; These commands return the aggregated privileges (including label-based permissions) for the user or role in the specified database context. -**Note**: +**Note**: - For **users**: In multi-tenant environments, you must specify the database context. - For **roles**: This command does not require database specification, even in @@ -407,14 +409,29 @@ adequate permission. ### Label-based access control -Label-based permissions are divided into 4 hierarchical parts or levels: +Label-based permissions are set using `CREATE`, `READ`, `UPDATE`, and `DELETE` +permissions, along with `NOTHING` to deny access: - `NOTHING` - denies user visibility and manipulation over nodes and - relationships +relationships +- `CREATE` - grants the user creation of a node or relationship - `READ` - grants the user visibility over nodes and relationships - `UPDATE` - grants the user visibility and the ability to edit nodes and - relationships -- `CREATE_DELETE` - grants the user visibility, editing, creation, and deletion -of a node or a relationship +relationships +- `DELETE` - grants the user deletion of a node or a relationship + + +**Breaking change in v3.7.0**: Label-based access control has significant changes: + +- Label-based permissions have changed from a fixed hierarchical model to +flexible discrete permission bits. The `CREATE_DELETE` permission has been split +into separate `CREATE` and `DELETE` permissions. + +- Fine-grained access control rules are now set on sets of labels, and these +apply to nodes either `MATCHING ANY` of the given labels, or `MATCHING EXACTLY` +the rule's label specification. + +See the [migration guide](link-to-migration-guide) for details. + #### Node permissions @@ -422,72 +439,157 @@ Granting a certain set of node permissions can be done similarly to the clause privileges using the following command: ```cypher -GRANT permission_level ON LABELS label_list TO user_or_role; +GRANT permission ON NODES CONTAINING LABELS label_list [MATCHING ANY| MATCHING EXACTLY] TO user_or_role; ``` with the legend: -- `permission_level` is either `NOTHING`, `READ`, `UPDATE` or `CREATE_DELETE` +- `permission` is either `NOTHING`, or a comma-separated list containing one + or more of: `CREATE`, `READ`, `UPDATE` or `DELETE` - `label_list` is a set of node labels, separated with a comma and with a colon -in front of each label (e.g. `:L1`), or `*` for specifying all labels in the +in front of each label (e.g. `:Person`), or `*` for specifying all labels in the graph - `user_or_role` is the already created user or role in Memgraph +- `MATCHING ANY` means that the rule will apply to any vertex having one or more +of the specified labels, regardless of any additional labels that the vertex may +have +- `MATCHING EXACTLY` will mean that the rule will apply to any vertex having +all of the labels specified, and no additional labels +- If the `MATCHING` clause is omitted, `MATCHING ANY` is assumed by default -For example, granting a `READ` permission on labels `L1` and `L2` would be -written as: +For example, granting a `READ` permission on any vertices with labels `User` or +`Product` to user `charlie` would be written as: ```cypher -GRANT READ ON LABELS :L1, :L2 TO charlie; +GRANT READ ON NODES CONTAINING LABELS :User, :Product MATCHING ANY TO charlie; ``` -while granting both `READ` and `EDIT` permissions for all labels in the graph, -would be written as: +Note that the `MATCHING ANY` clause may be omitted because this is the default +for labels. The following statement behaves identically to the previous example: ```cypher -GRANT UPDATE ON LABELS * TO charlie; +GRANT READ ON NODES CONTAINING LABELS :User, :Product TO charlie; ``` -For denying visibility to a node, the command would be written as: +Multiple permissions can be granted using multiple statements, building up the +allowed permissions piece-by-piece: ```cypher -GRANT NOTHING ON LABELS :L1 TO charlie; +GRANT CREATE ON NODES CONTAINING LABELS :Item TO charlie; +GRANT READ ON NODES CONTAINING LABELS :Item TO charlie; +GRANT UPDATE ON NODES CONTAINING LABELS :Item TO charlie; ``` -#### Relationship permissions +Or they can be granted in a single statement using a comma-separated permission +list: -Relationship permission queries are in essence the same as node permission -queries, with the one difference that the name of the relationship type is -`EDGE_TYPE` and not `LABEL`. +```cypher +GRANT CREATE, READ, UPDATE ON NODES CONTAINING LABELS :Item TO charlie; +``` -Granting a certain set of edge type permissions can be done similarly to the -clause privileges by issuing the following command: +Global permissions for all labels can be granted using `*` instead of a list of +labels: ```cypher -GRANT permission_level ON EDGE_TYPES edge_type_list TO user_or_role; +GRANT READ ON NODES CONTAINING LABELS * TO charlie; ``` -with the same legend as the node permissions. +For denying visibility to a node, use the `NOTHING` permission. Granting +`NOTHING` creates an explicit DENY rule for the given label specification, +which overrides any existing permissions. -For example, granting a `READ` permission on relationship type `:CONNECTS` would -be written as: +```cypher +GRANT NOTHING ON NODES CONTAINING LABELS :User, :Person TO charlie; +``` + +Permissions can be revoked using the following syntax: ```cypher -GRANT READ ON EDGE_TYPES :CONNECTS TO charlie; +REVOKE permission ON NODES CONTAINING LABELS label_list [MATCHING ANY| MATCHING EXACTLY] FROM user_or_role; ``` -#### Revoke label-based permissions +The rules for specifying `REVOKE` label specifications are identical to those +when using `GRANT`. + +Note that revoking all permissions for a label specification is not the same as +`GRANT`ing `NOTHING`. The former removes already `GRANT`ed permissions for the +label specification; the latter sets an explicit `DENY` on that label +specification. This distinction is particularly important when it comes to +merging permissions. + +#### Relationship permissions + +Edge type permissions work similarly to node permissions, and have the same +permission types (`CREATE`, `READ`, `UPDATE`, `DELETE`, and `NOTHING`). -To revoke any of the label-based permissions, users can use one of the following -commands: +Permissions can be granted using the following syntax: ```cypher -REVOKE (LABELS | EDGE_TYPES) label_or_edge_type_list FROM user_or_role +GRANT permission ON EDGES OF TYPE edge_type_list TO user_or_role; ``` where: -- `label_or_edge_type_list` is a list of labels or edge types with a colon in -front of each label or edge type (or `*` for specifying all labels or edge -types) -- `user_or_role` is the existing user or role in Memgraph +- `permission` is either `NOTHING`, or a comma-separated list containing one or +more of: `CREATE`, `READ`, `UPDATE` or `DELETE` +- edge_type_list is a set of edge types, separated with a comma and with a colon +in front of each type (e.g. `:KNOWS, :FOLLOWS`), or `*` for all edge types +- `user_or_role` is the already created user or role in Memgraph + +Note that edge type permissions do not support MATCHING clauses: edges can only +have a single type, so matching modes are not applicable. + +For example, granting `READ` permission on edge type `:CONNECTS` to user charlie: + +```cypher +GRANT READ ON EDGES OF TYPE :CONNECTS TO charlie; +``` + +Granting multiple permissions on multiple edge types: + +```cypher +GRANT CREATE, READ, UPDATE ON EDGES OF TYPE :KNOWS, :FOLLOWS TO charlie; +``` + +Global permissions for all edge types: + +```cypher +GRANT READ ON EDGES OF TYPE * TO charlie; +``` + +Revoking edge type permissions uses similar syntax: + +```cypher +REVOKE permission ON EDGES OF TYPE edge_type_list FROM user_or_role; +``` + +For example: + +```cypher +REVOKE CREATE ON EDGES OF TYPE :KNOWS FROM charlie; +``` + +As with node permissions, revoking all permissions is not the same as granting +NOTHING. Revoking removes granted permissions, while NOTHING creates an explicit +DENY rule. + +#### Permission merging + +When a user has multiple roles, or when a user has both role-based and +user-specific permissions, individual permission bits (`CREATE`, `READ`, +`UPDATE`, `DELETE`) are combined using OR logic for grants and explicit denies: + +- If any role or the user grants a specific permission on a label specification, +the user has that permission +- If any role or the user grants `NOTHING` (explicit deny) on a label +specification, the user is denied all access to that label specification, +overriding any grants +- Each label specification is evaluated independently based on its label list +and matching mode + +For example, if a user has Role A granting `READ` on `:Item` and Role B granting +`UPDATE` on `:Item`, the user will have both `READ` and `UPDATE` permissions on +`:Item` nodes. However, if Role C grants `NOTHING` on `:Item`, the explicit deny +overrides all grants, and the user will have no access to any `:Item` nodes. + #### Show privileges for label-based access control @@ -520,7 +622,7 @@ SHOW PRIVILEGES FOR user_or_role ON DATABASE database_name; These commands return the aggregated privileges (including label-based permissions) for the user or role in the specified database context. -**Note**: +**Note**: - For **users**: In multi-tenant environments, you must specify the database context. - For **roles**: This command does not require database specification, even in @@ -534,8 +636,8 @@ To grant all privileges to a superuser (admin): ``` GRANT ALL PRIVILEGES TO admin; GRANT DATABASE * to admin; -GRANT CREATE_DELETE ON LABELS * TO admin; -GRANT CREATE_DELETE ON EDGE_TYPES * TO admin; +GRANT CREATE, READ, UPDATE, DELETE ON NODES CONTAINING LABELS * TO admin; +GRANT CREATE, READ, UPDATE, DELETE ON EDGES OF TYPE * TO admin; ``` To grant all read and write privileges: @@ -543,22 +645,22 @@ To grant all read and write privileges: ``` DENY ALL PRIVILEGES TO readWrite; GRANT CREATE, DELETE, MERGE, SET, REMOVE, INDEX, MATCH, STATS TO readWrite; -GRANT CREATE_DELETE ON LABELS * TO readWrite; -GRANT CREATE_DELETE ON EDGE_TYPES * TO readWrite; +GRANT CREATE, READ, UPDATE, DELETE ON NODES CONTAINING LABELS * TO readWrite; +GRANT CREATE, READ, UPDATE, DELETE ON EDGES OF TYPE * TO readWrite; ``` -To grant read only privileges: +To grant read only privileges: ``` DENY ALL PRIVILEGES TO readonly; GRANT MATCH, STATS TO readonly; -GRANT READ ON LABELS * TO readonly; -GRANT READ ON EDGE_TYPES * TO readonly; +GRANT READ ON NODES CONTAINING LABELS * TO readonly; +GRANT READ ON EDGES OF TYPE * TO readonly; ``` ### Examples -Below are several examples of using the Enterprise security features. +Below are several examples of using the Enterprise security features. #### Grant read permissions @@ -598,14 +700,10 @@ Since Bob is not an administrator, he was not able to see any data points in the graph. In other words, he does not have `READ` permission on the `DataPoint` label. -Memgraph's label-based access control is hierarchically constructed, and the -first permission one can be given on node labels or relationship edge types is -`READ`. - Alice now updates Bob's permissions by executing: ```cypher -GRANT READ ON LABELS :DataPoint TO analyst; +GRANT READ ON NODES CONTAINING LABELS :DataPoint TO analyst; ``` Bob is now executing his queries normally and is able to get insights from the @@ -627,7 +725,7 @@ doesn't have permission to view the relationships. The database administrator executes the following command to solve the problem: ```cypher -GRANT READ ON EDGE_TYPES :NEXT TO analyst; +GRANT READ ON EDGES OF TYPE :NEXT TO analyst; ``` Since the users are initially constructed without any permission, they would @@ -644,7 +742,7 @@ updating the classes of the data points if they are labeled incorrectly. For example, the class of one `DataPoint` might be 'dog', while in fact it is an 'elephant', but it was wrongly selected in the rush of labeling many data points. Charlie needs to update the wrongly labeled data points, and he already -has the IDs of all the nodes he must update. +has the IDs of all the nodes he must update. The administrator has already set up his account with the following commands: @@ -656,8 +754,8 @@ GRANT DATABASE exampledb TO Charlie; GRANT MATCH, SET TO tester; -GRANT READ ON LABELS :DataPoint TO tester; -GRANT READ ON EDGE_TYPES :NEXT TO tester; +GRANT READ ON NODES CONTAINING LABELS :DataPoint TO tester; +GRANT READ ON EDGES OF TYPE :NEXT TO tester; ``` He now has read privileges just like all the data analysts, but when he gets an @@ -672,7 +770,7 @@ nodes in the graph. The database administrator needs to update Charlie's permissions and grant him access to update the node properties with: ```cypher -GRANT UPDATE ON LABELS :DataPoint TO tester; +GRANT UPDATE ON NODES CONTAINING LABELS :DataPoint TO tester; ``` Charlie is now able to update the labeled categories of any data point in the @@ -694,8 +792,8 @@ GRANT DATABASE exampledb TO David; GRANT MATCH, DELETE TO dataEngineer; -GRANT UPDATE ON LABELS :DataPoint TO dataEngineer; -GRANT UPDATE ON EDGE_TYPES :NEXT TO dataEngineer; +GRANT UPDATE ON NODES CONTAINING LABELS :DataPoint TO dataEngineer; +GRANT UPDATE ON EDGES OF TYPE :NEXT TO dataEngineer; ``` However, `UPDATE` privilege capabilities only grant manipulation of properties, @@ -705,13 +803,13 @@ not the nodes and relationships themselves. Therefore, the query: MATCH (n:DataPoint) WHERE localDateTime() - n.date > Duration({day:365}) DETACH DELETE n; ``` -results in an error. The permission that grants read, update, create, and delete -rights over the nodes and relationships in the graph is `CREATE_DELETE`. By +results in an error. To delete nodes and relationships, David needs both +`CREATE` and `DELETE` permissions (as well as `READ` to query them). By executing the following commands: ```cypher -GRANT CREATE_DELETE ON LABELS :DataPoint TO dataEngineer; -GRANT CREATE_DELETE ON EDGE_TYPES :NEXT TO dataEngineer; +GRANT CREATE, READ, DELETE ON NODES CONTAINING LABELS :DataPoint TO dataEngineer; +GRANT CREATE, READ, DELETE ON EDGES OF TYPE :NEXT TO dataEngineer; ``` The permission is executed on relationships as well, since David needs to detach @@ -737,8 +835,8 @@ GRANT DATABASE exampledb TO Eve; GRANT MATCH, DELETE TO seniorEngineer; -GRANT CREATE_DELETE ON LABELS * TO seniorEngineer; -GRANT NOTHING ON LABELS :SecretLabel TO seniorEngineer; +GRANT CREATE, READ, UPDATE, DELETE ON NODES CONTAINING LABELS * TO seniorEngineer; +GRANT NOTHING ON NODES CONTAINING LABELS :SecretLabel TO seniorEngineer; ``` When granting `NOTHING`, the user is denied both visibility and manipulation of From 8dcf8b68e0da7fae2e8892c7629070fe92d9a9fd Mon Sep 17 00:00:00 2001 From: Colin Barry Date: Fri, 7 Nov 2025 10:09:19 +0000 Subject: [PATCH 04/12] docs: Add example for combining rules --- .../role-based-access-control.mdx | 51 ++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/pages/database-management/authentication-and-authorization/role-based-access-control.mdx b/pages/database-management/authentication-and-authorization/role-based-access-control.mdx index 16de27fb4..9f558d11e 100644 --- a/pages/database-management/authentication-and-authorization/role-based-access-control.mdx +++ b/pages/database-management/authentication-and-authorization/role-based-access-control.mdx @@ -530,8 +530,8 @@ GRANT permission ON EDGES OF TYPE edge_type_list TO user_or_role; where: - `permission` is either `NOTHING`, or a comma-separated list containing one or more of: `CREATE`, `READ`, `UPDATE` or `DELETE` -- edge_type_list is a set of edge types, separated with a comma and with a colon -in front of each type (e.g. `:KNOWS, :FOLLOWS`), or `*` for all edge types +- `edge_type_list` is a set of edge types, separated with a comma and with a +colon in front of each type (e.g. `:KNOWS, :FOLLOWS`), or `*` for all edge types - `user_or_role` is the already created user or role in Memgraph Note that edge type permissions do not support MATCHING clauses: edges can only @@ -590,6 +590,53 @@ For example, if a user has Role A granting `READ` on `:Item` and Role B granting `:Item` nodes. However, if Role C grants `NOTHING` on `:Item`, the explicit deny overrides all grants, and the user will have no access to any `:Item` nodes. +##### When multiple rules match the same vertex + +When a vertex matches multiple label specifications, all matching rules are +applied and their permissions are combined: + +- The effective permissions for a vertex are the union (OR) of all permissions +from matching rules +- If any matching rule grants `NOTHING`, the vertex is denied (explicit deny +overrides all grants) +- Rules are matched based on their label specification and matching mode + +For example, given the following rules: + +```cypher +GRANT READ ON NODES CONTAINING LABELS :User MATCHING ANY TO charlie; +GRANT UPDATE ON NODES CONTAINING LABELS :Employee MATCHING ANY TO charlie; +``` + +A vertex with labels `:User:Employee` matches both rules. `charlie` will have both +`READ` and `UPDATE` permissions on this vertex, since permissions from all +matching rules are combined. + +However, if we add an explicit deny: + +```cypher +GRANT NOTHING ON NODES CONTAINING LABELS :Admin MATCHING ANY TO charlie; +``` + +A vertex with labels `:User:Employee:Admin` matches all three rules. `charlie` +will have `NOTHING` (explicit deny) on this vertex, since `NOTHING` takes +precedence over any granted permissions. + +The `MATCHING` mode also affects which rules apply: + +```cypher +GRANT READ ON NODES CONTAINING LABELS :User, :Employee MATCHING EXACTLY TO charlie; +GRANT UPDATE ON NODES CONTAINING LABELS :Employee MATCHING ANY TO charlie; +``` + +- A vertex with labels `:User:Employee` (only these two labels) matches the first +rule exactly, and the second rule (has `:Employee`). `charlie` has both `READ` +and `UPDATE` +- A vertex with labels `:User:Employee:Admin` matches only the second +rule (has `:Employee`, but not exactly `:User:Employee`). `charlie` has only +`UPDATE` +- A vertex with labels `:Employee` matches only the second rule. `charlie` has +only `UPDATE` #### Show privileges for label-based access control From 0232bb32e2ce6b602f8c22d669b90dfbb82ba931 Mon Sep 17 00:00:00 2001 From: Colin Barry Date: Fri, 7 Nov 2025 10:19:46 +0000 Subject: [PATCH 05/12] docs: Add example for global permissions being overriden --- .../role-based-access-control.mdx | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/pages/database-management/authentication-and-authorization/role-based-access-control.mdx b/pages/database-management/authentication-and-authorization/role-based-access-control.mdx index 9f558d11e..2cb25357c 100644 --- a/pages/database-management/authentication-and-authorization/role-based-access-control.mdx +++ b/pages/database-management/authentication-and-authorization/role-based-access-control.mdx @@ -638,6 +638,42 @@ rule (has `:Employee`, but not exactly `:User:Employee`). `charlie` has only - A vertex with labels `:Employee` matches only the second rule. `charlie` has only `UPDATE` +##### Global permissions and label-specific rules + +Global permissions (granted on `*`) act as a fallback when no specific label +specification matches a vertex. When a vertex matches a specific label rule, +that rule takes precedence over the global permission. + +For example: + +```cypher +GRANT READ, UPDATE ON NODES CONTAINING LABELS * TO charlie; +GRANT NOTHING ON NODES CONTAINING LABELS :Confidential MATCHING ANY TO charlie; +``` + +- A vertex with labels `:User` has no specific rule match, so the global `*` +permission applies. `charlie` has `READ` and `UPDATE` +- A vertex with labels `:Confidential` matches the specific rule. The specific +`NOTHING` rule overrides the global permission, so `charlie` has no access + +Another example: + +```cypher +GRANT READ ON NODES CONTAINING LABELS * TO charlie; +GRANT UPDATE ON NODES CONTAINING LABELS :Document MATCHING ANY TO charlie; +``` + +- A vertex with labels `:User` matches only the global rule. `charlie` has +`READ` +- A vertex with labels `:Document` matches the specific rule. `charlie` has +`UPDATE` from the specific rule, but the global `READ` is replaced by the +specific rule, so `charlie` has only `UPDATE` +- A vertex with labels `:Document:Draft` matches the specific rule (has +`:Document`). `charlie` has only `UPDATE` + +Key principle: Once any specific label rule matches a vertex, the global `*` +permission is not considered for that vertex. + #### Show privileges for label-based access control To check which privileges an existing user or role has in Memgraph, it is enough From b420b349eb98fc3ed0a28ade5b6e6d2258c0554e Mon Sep 17 00:00:00 2001 From: Colin Barry Date: Fri, 7 Nov 2025 10:46:40 +0000 Subject: [PATCH 06/12] docs: Tidy LBAC docs --- .../role-based-access-control.mdx | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/pages/database-management/authentication-and-authorization/role-based-access-control.mdx b/pages/database-management/authentication-and-authorization/role-based-access-control.mdx index 2cb25357c..c9c14950c 100644 --- a/pages/database-management/authentication-and-authorization/role-based-access-control.mdx +++ b/pages/database-management/authentication-and-authorization/role-based-access-control.mdx @@ -423,8 +423,9 @@ relationships **Breaking change in v3.7.0**: Label-based access control has significant changes: - Label-based permissions have changed from a fixed hierarchical model to -flexible discrete permission bits. The `CREATE_DELETE` permission has been split -into separate `CREATE` and `DELETE` permissions. +discrete permissions. The `CREATE_DELETE` permission has been split into +separate `CREATE` and `DELETE` permissions. `CREATE`/`DELETE` no longer implies +`UPDATE` and `READ`, and `UPDATE` no longer implies `READ`. - Fine-grained access control rules are now set on sets of labels, and these apply to nodes either `MATCHING ANY` of the given labels, or `MATCHING EXACTLY` @@ -446,8 +447,8 @@ with the legend: - `permission` is either `NOTHING`, or a comma-separated list containing one or more of: `CREATE`, `READ`, `UPDATE` or `DELETE` - `label_list` is a set of node labels, separated with a comma and with a colon -in front of each label (e.g. `:Person`), or `*` for specifying all labels in the -graph +in front of each label (e.g. `:Person`), or `*` for creating a global rule +matching all labels in the graph - `user_or_role` is the already created user or role in Memgraph - `MATCHING ANY` means that the rule will apply to any vertex having one or more of the specified labels, regardless of any additional labels that the vertex may @@ -455,6 +456,7 @@ have - `MATCHING EXACTLY` will mean that the rule will apply to any vertex having all of the labels specified, and no additional labels - If the `MATCHING` clause is omitted, `MATCHING ANY` is assumed by default +- `MATCHING` clauses cannot be used when creating global (`*`) rules For example, granting a `READ` permission on any vertices with labels `User` or `Product` to user `charlie` would be written as: @@ -514,7 +516,7 @@ Note that revoking all permissions for a label specification is not the same as `GRANT`ing `NOTHING`. The former removes already `GRANT`ed permissions for the label specification; the latter sets an explicit `DENY` on that label specification. This distinction is particularly important when it comes to -merging permissions. +[merging permissions](#merging-permissions). #### Relationship permissions @@ -571,7 +573,7 @@ As with node permissions, revoking all permissions is not the same as granting NOTHING. Revoking removes granted permissions, while NOTHING creates an explicit DENY rule. -#### Permission merging +#### Merging permissions When a user has multiple roles, or when a user has both role-based and user-specific permissions, individual permission bits (`CREATE`, `READ`, @@ -590,15 +592,15 @@ For example, if a user has Role A granting `READ` on `:Item` and Role B granting `:Item` nodes. However, if Role C grants `NOTHING` on `:Item`, the explicit deny overrides all grants, and the user will have no access to any `:Item` nodes. -##### When multiple rules match the same vertex +#### Combining matching rules When a vertex matches multiple label specifications, all matching rules are applied and their permissions are combined: - The effective permissions for a vertex are the union (OR) of all permissions from matching rules -- If any matching rule grants `NOTHING`, the vertex is denied (explicit deny -overrides all grants) +- If any matching rule grants `NOTHING`, the vertex is denied: explicit deny +overrides all grants - Rules are matched based on their label specification and matching mode For example, given the following rules: @@ -635,7 +637,7 @@ and `UPDATE` - A vertex with labels `:User:Employee:Admin` matches only the second rule (has `:Employee`, but not exactly `:User:Employee`). `charlie` has only `UPDATE` -- A vertex with labels `:Employee` matches only the second rule. `charlie` has +- A vertex with label `:Employee` matches only the second rule. `charlie` has only `UPDATE` ##### Global permissions and label-specific rules @@ -651,9 +653,9 @@ GRANT READ, UPDATE ON NODES CONTAINING LABELS * TO charlie; GRANT NOTHING ON NODES CONTAINING LABELS :Confidential MATCHING ANY TO charlie; ``` -- A vertex with labels `:User` has no specific rule match, so the global `*` +- A vertex with label `:User` has no specific rule match, so the global `*` permission applies. `charlie` has `READ` and `UPDATE` -- A vertex with labels `:Confidential` matches the specific rule. The specific +- A vertex with label `:Confidential` matches the specific rule. The specific `NOTHING` rule overrides the global permission, so `charlie` has no access Another example: @@ -663,9 +665,9 @@ GRANT READ ON NODES CONTAINING LABELS * TO charlie; GRANT UPDATE ON NODES CONTAINING LABELS :Document MATCHING ANY TO charlie; ``` -- A vertex with labels `:User` matches only the global rule. `charlie` has +- A vertex with label `:User` matches only the global rule. `charlie` has `READ` -- A vertex with labels `:Document` matches the specific rule. `charlie` has +- A vertex with label `:Document` matches the specific rule. `charlie` has `UPDATE` from the specific rule, but the global `READ` is replaced by the specific rule, so `charlie` has only `UPDATE` - A vertex with labels `:Document:Draft` matches the specific rule (has From 5399495211317f10729c6538107bcd47585acb04 Mon Sep 17 00:00:00 2001 From: Colin Barry Date: Fri, 7 Nov 2025 10:50:27 +0000 Subject: [PATCH 07/12] docs: Add link to combining rules --- .../role-based-access-control.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pages/database-management/authentication-and-authorization/role-based-access-control.mdx b/pages/database-management/authentication-and-authorization/role-based-access-control.mdx index c9c14950c..10b6c2688 100644 --- a/pages/database-management/authentication-and-authorization/role-based-access-control.mdx +++ b/pages/database-management/authentication-and-authorization/role-based-access-control.mdx @@ -516,7 +516,8 @@ Note that revoking all permissions for a label specification is not the same as `GRANT`ing `NOTHING`. The former removes already `GRANT`ed permissions for the label specification; the latter sets an explicit `DENY` on that label specification. This distinction is particularly important when it comes to -[merging permissions](#merging-permissions). +[merging permissions](#merging-permissions) and +[combining matching rules](#combining-matching-rules). #### Relationship permissions From c4fc43009afd8d7c2e75b0dfb66b3ff243282397 Mon Sep 17 00:00:00 2001 From: Colin Barry Date: Fri, 7 Nov 2025 15:02:47 +0000 Subject: [PATCH 08/12] docs: Add migration to v3.7 LBAC guide --- .../authentication-and-authorization/_meta.ts | 1 + .../mlbac-migration-guide.mdx | 166 ++++++++++++++++++ .../role-based-access-control.mdx | 2 +- 3 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx diff --git a/pages/database-management/authentication-and-authorization/_meta.ts b/pages/database-management/authentication-and-authorization/_meta.ts index 65a49ee06..ed83fc6c9 100644 --- a/pages/database-management/authentication-and-authorization/_meta.ts +++ b/pages/database-management/authentication-and-authorization/_meta.ts @@ -1,6 +1,7 @@ export default { "users": "Users", "role-based-access-control": "Role-based access control", + "mlbac-migration-guide": "Migrating to v3.7 LBAC", "multiple-roles": "Multiple roles per user and multi-tenant roles", "auth-system-integrations": "Auth system integrations", "impersonate-user": "Impersonate user", diff --git a/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx b/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx new file mode 100644 index 000000000..e8b9d670a --- /dev/null +++ b/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx @@ -0,0 +1,166 @@ +--- +title: "Migrating to v3.7 label-based access control" +description: "Guide for upgrading from v3.6 label-based access control to v3.7 multi-label based access control" +--- + +import { Callout } from 'nextra/components' + +# Migrating to v3.7 label-based access control + + +**Breaking change in v3.7.0**: [Label-based access control](/database-management/authentication-and-authorization/role-based-access-control#fine-grained-access-control) has significant +changes. If you use fine-grained access control, read this guide before +upgrading. + + +## What's changed? + +### Label matching semantics + +**Before (v3.6):** Rules matched exact label sets only. +- `GRANT READ ON LABELS :User` matched only `:User`, not `:User:Admin` + +**After (v3.7):** Rules use flexible matching modes. +- `GRANT READ ON NODES CONTAINING LABELS :User` now matches `:User`, `:User:Admin`, etc. +- `MATCHING ANY` (default): Matches vertices with one or more specified labels +- `MATCHING EXACTLY`: Matches vertices with exactly the specified labels + +### Permission model change + +**Before (v3.6):** Hierarchical permissions +- `NOTHING`, `READ`, `UPDATE`, `CREATE_DELETE` +- `UPDATE` implied `READ`; `CREATE_DELETE` implied everything + +**After (v3.7):** Discrete permissions +- `NOTHING`, `CREATE`, `READ`, `UPDATE`, `DELETE` +- Each permission is independent and must be granted explicitly. Any combination +of `CREATE`, `READ`, `UPDATE`, and `DELETE` can be granted. + +### Syntax changes + +| v3.6 | v3.7 | +|------|------| +| `GRANT READ ON LABELS :User, :Client TO alice` | `GRANT READ ON NODES CONTAINING LABELS :User, :Client TO alice` | +| `GRANT UPDATE ON LABELS :Doc TO bob` | `GRANT READ, UPDATE ON NODES CONTAINING LABELS :Doc TO bob` | +| `GRANT CREATE_DELETE ON EDGE_TYPES :KNOWS TO charlie` | `GRANT CREATE, DELETE ON EDGES OF TYPE :KNOWS TO charlie` | + +For more details, please read the guide to +[label-based access control](/database-management/authentication-and-authorization/role-based-access-control#fine-grained-access-control). + +## Before upgrading to v3.7 + +**1. Export current permissions** + +```cypher +SHOW USERS; +// For each user +SHOW PRIVILEGES FOR username; + +SHOW ROLES; +// For each role +SHOW PRIVILEGES FOR rolename; +``` + +Save the output: you'll need it to recreate per-label rules. + +**2. Back up auth storage** + +```bash +# Default location. Adjust if using custom data directory +cp -r /var/lib/memgraph/auth /backup/location/auth-backup +``` + +## What gets migrated automatically + +Global permissions only (grants on `*`) + +| v3.6 Permission | Migrates to v3.7 | +|-----------------|------------------------------| +| NOTHING | NOTHING | +| READ | READ | +| UPDATE | READ, UPDATE | +| CREATE_DELETE | CREATE, READ, UPDATE, DELETE | + +Example: +```cypher +// v3.6 +GRANT UPDATE ON LABELS * TO alice; + +// After automatic migration +GRANT READ, UPDATE ON NODES CONTAINING LABELS * TO alice; +``` + +## What you must recreate manually + + +**All per-label and per-edge type rules are dropped** during migration and must be manually recreated. +Specifically: +- Any `GRANT ... ON LABELS :Label` rules must be recreated +- Any `GRANT ... ON EDGE_TYPES :EdgeType` rules must be recreated + + +Review your pre-upgrade `SHOW PRIVILEGES` output to identify which users/roles +had per-label permissions. For each permission that you need to recreate: + +**1. Determine the equivalent v3.7 permission set:** +- If they had `READ`: `GRANT READ` +- If they had `UPDATE`: `GRANT READ, UPDATE` +- If they had `CREATE_DELETE`: `GRANT CREATE, READ, UPDATE, DELETE` + +**2. Choose matching mode:** + - `MATCHING EXACTLY` - vertex must have exactly the specified labels, no more, no less + - `MATCHING ANY` (default) - vertex must have one or more of the specified labels + +**3. Write the new GRANT statement:** +- Use `GRANT ... ON NODES CONTAINING LABELS ... [MATCHING ANY|MATCHING EXACTLY] TO user` for vertex label rules +- Use `GRANT ... ON EDGES OF TYPE ... TO user` for edge type rules + +**Example:** + +Your `SHOW PRIVILEGES` output shows alice had `READ` on `:User`, bob had `UPDATE` on `:Document`: + +```cypher +GRANT READ ON NODES CONTAINING LABELS :User MATCHING EXACTLY TO alice; +GRANT READ, UPDATE ON NODES CONTAINING LABELS :Document MATCHING EXACTLY TO bob; +``` +## After upgrading + +**1. Verify global permissions** + +```cypher +SHOW USERS; +// For each user +SHOW PRIVILEGES FOR username; + +SHOW ROLES; +// For each role +SHOW PRIVILEGES FOR rolename; +``` + +Check that global (`*`) permissions were migrated correctly. + +**2. Recreate per-label rules** + +Execute the GRANT statements you prepared to recreate all per-label and per-edge type rules. + +**3. Test access** + +Connect as each user and verify: +- Access to vertices with different label combinations works as expected +- Edge type access works + + +## Migration checklist + +- [ ] Export all permissions using `SHOW PRIVILEGES` +- [ ] Back up auth storage directory +- [ ] Upgrade to v3.7 +- [ ] Verify global `*` permissions migrated +- [ ] Recreate per-label rules +- [ ] Recreate per-edge type rules +- [ ] Test user access + +## See also + +- [Full RBAC documentation](/database-management/authentication-and-authorization/role-based-access-control) +- [All v3.7 changes](/release-notes) \ No newline at end of file diff --git a/pages/database-management/authentication-and-authorization/role-based-access-control.mdx b/pages/database-management/authentication-and-authorization/role-based-access-control.mdx index 10b6c2688..1a81c4fa2 100644 --- a/pages/database-management/authentication-and-authorization/role-based-access-control.mdx +++ b/pages/database-management/authentication-and-authorization/role-based-access-control.mdx @@ -431,7 +431,7 @@ separate `CREATE` and `DELETE` permissions. `CREATE`/`DELETE` no longer implies apply to nodes either `MATCHING ANY` of the given labels, or `MATCHING EXACTLY` the rule's label specification. -See the [migration guide](link-to-migration-guide) for details. +See the [migration guide](/database-management/authentication-and-authorization/mlbac-migration-guide) for details. #### Node permissions From 49b02145571a1103293ce1e69910a8617aa0023d Mon Sep 17 00:00:00 2001 From: Colin Barry Date: Fri, 7 Nov 2025 15:13:03 +0000 Subject: [PATCH 09/12] docs: Apply some minor formatting --- .../mlbac-migration-guide.mdx | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx b/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx index e8b9d670a..11cf0d10b 100644 --- a/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx +++ b/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx @@ -21,7 +21,8 @@ upgrading. - `GRANT READ ON LABELS :User` matched only `:User`, not `:User:Admin` **After (v3.7):** Rules use flexible matching modes. -- `GRANT READ ON NODES CONTAINING LABELS :User` now matches `:User`, `:User:Admin`, etc. +- `GRANT READ ON NODES CONTAINING LABELS :User` now matches `:User`, +`:User:Admin`, etc. - `MATCHING ANY` (default): Matches vertices with one or more specified labels - `MATCHING EXACTLY`: Matches vertices with exactly the specified labels @@ -33,7 +34,7 @@ upgrading. **After (v3.7):** Discrete permissions - `NOTHING`, `CREATE`, `READ`, `UPDATE`, `DELETE` -- Each permission is independent and must be granted explicitly. Any combination +- Each permission is independent and must be granted explicitly. Any combination of `CREATE`, `READ`, `UPDATE`, and `DELETE` can be granted. ### Syntax changes @@ -66,7 +67,7 @@ Save the output: you'll need it to recreate per-label rules. **2. Back up auth storage** ```bash -# Default location. Adjust if using custom data directory +# Default location. Adjust if using a custom data directory cp -r /var/lib/memgraph/auth /backup/location/auth-backup ``` @@ -93,7 +94,8 @@ GRANT READ, UPDATE ON NODES CONTAINING LABELS * TO alice; ## What you must recreate manually -**All per-label and per-edge type rules are dropped** during migration and must be manually recreated. +**All per-label and per-edge type rules are dropped** during migration and must +be manually recreated. Specifically: - Any `GRANT ... ON LABELS :Label` rules must be recreated - Any `GRANT ... ON EDGE_TYPES :EdgeType` rules must be recreated @@ -108,16 +110,19 @@ had per-label permissions. For each permission that you need to recreate: - If they had `CREATE_DELETE`: `GRANT CREATE, READ, UPDATE, DELETE` **2. Choose matching mode:** - - `MATCHING EXACTLY` - vertex must have exactly the specified labels, no more, no less + - `MATCHING EXACTLY` - vertex must have exactly the specified labels, no more, + no less - `MATCHING ANY` (default) - vertex must have one or more of the specified labels **3. Write the new GRANT statement:** -- Use `GRANT ... ON NODES CONTAINING LABELS ... [MATCHING ANY|MATCHING EXACTLY] TO user` for vertex label rules +- Use `GRANT ... ON NODES CONTAINING LABELS ... [MATCHING ANY|MATCHING EXACTLY] +TO user` for vertex label rules - Use `GRANT ... ON EDGES OF TYPE ... TO user` for edge type rules **Example:** -Your `SHOW PRIVILEGES` output shows alice had `READ` on `:User`, bob had `UPDATE` on `:Document`: +Your `SHOW PRIVILEGES` output shows `alice` had `READ` on `:User`, and `bob` had +`UPDATE` on `:Document`: ```cypher GRANT READ ON NODES CONTAINING LABELS :User MATCHING EXACTLY TO alice; @@ -141,7 +146,8 @@ Check that global (`*`) permissions were migrated correctly. **2. Recreate per-label rules** -Execute the GRANT statements you prepared to recreate all per-label and per-edge type rules. +Execute the `GRANT` statements you prepared to recreate all per-label and +per-edge type rules. **3. Test access** @@ -162,5 +168,5 @@ Connect as each user and verify: ## See also -- [Full RBAC documentation](/database-management/authentication-and-authorization/role-based-access-control) +- [Full RBAC documentation](/database-management/authentication-and-authorization/role-based-access-control) - [All v3.7 changes](/release-notes) \ No newline at end of file From b90af10e190646a5723686e0c257de0d10131ad6 Mon Sep 17 00:00:00 2001 From: Colin Barry Date: Mon, 10 Nov 2025 09:08:07 +0000 Subject: [PATCH 10/12] docs: Fix minor typos --- .../role-based-access-control.mdx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pages/database-management/authentication-and-authorization/role-based-access-control.mdx b/pages/database-management/authentication-and-authorization/role-based-access-control.mdx index 1a81c4fa2..3a8659222 100644 --- a/pages/database-management/authentication-and-authorization/role-based-access-control.mdx +++ b/pages/database-management/authentication-and-authorization/role-based-access-control.mdx @@ -154,7 +154,7 @@ of the following commands: | Privilege to [interact with a database](/database-management/multi-tenancy). | `DATABASE` | | Privilege to [access data](/querying/read-and-modify-data). | `MATCH` | | Privilege to [modify data](/querying/read-and-modify-data). | `MERGE`, `SET`| -| Privilege to [create](/querying/create-graph-objects) and [delete]](/querying/read-and-modify-data) data. | `CREATE`, `DELETE`, `REMOVE` | +| Privilege to [create](/querying/create-graph-objects) and [delete](/querying/read-and-modify-data) data. | `CREATE`, `DELETE`, `REMOVE` | | Privilege to [index data](/fundamentals/indexes). | `INDEX` | | Privilege to [obtain statistics and information](/database-management/server-stats) from Memgraph. | `STATS` | | Privilege to view and alter users, roles and privileges. | `AUTH` | @@ -540,7 +540,8 @@ colon in front of each type (e.g. `:KNOWS, :FOLLOWS`), or `*` for all edge types Note that edge type permissions do not support MATCHING clauses: edges can only have a single type, so matching modes are not applicable. -For example, granting `READ` permission on edge type `:CONNECTS` to user charlie: +For example, granting `READ` permission on edge type `:CONNECTS` to user +`charlie`: ```cypher GRANT READ ON EDGES OF TYPE :CONNECTS TO charlie; @@ -719,7 +720,7 @@ permissions) for the user or role in the specified database context. To grant all privileges to a superuser (admin): -``` +```cypher GRANT ALL PRIVILEGES TO admin; GRANT DATABASE * to admin; GRANT CREATE, READ, UPDATE, DELETE ON NODES CONTAINING LABELS * TO admin; @@ -728,7 +729,7 @@ GRANT CREATE, READ, UPDATE, DELETE ON EDGES OF TYPE * TO admin; To grant all read and write privileges: -``` +```cypher DENY ALL PRIVILEGES TO readWrite; GRANT CREATE, DELETE, MERGE, SET, REMOVE, INDEX, MATCH, STATS TO readWrite; GRANT CREATE, READ, UPDATE, DELETE ON NODES CONTAINING LABELS * TO readWrite; @@ -737,7 +738,7 @@ GRANT CREATE, READ, UPDATE, DELETE ON EDGES OF TYPE * TO readWrite; To grant read only privileges: -``` +```cypher DENY ALL PRIVILEGES TO readonly; GRANT MATCH, STATS TO readonly; GRANT READ ON NODES CONTAINING LABELS * TO readonly; From f6f165649b89efc51fa4153fffc08ff5304ca0c9 Mon Sep 17 00:00:00 2001 From: Colin Barry Date: Mon, 10 Nov 2025 09:10:50 +0000 Subject: [PATCH 11/12] docs: Add Enterprise to migration page --- .../authentication-and-authorization/mlbac-migration-guide.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx b/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx index 11cf0d10b..51a14b0b0 100644 --- a/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx +++ b/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx @@ -5,7 +5,7 @@ description: "Guide for upgrading from v3.6 label-based access control to v3.7 m import { Callout } from 'nextra/components' -# Migrating to v3.7 label-based access control +# Migrating to v3.7 label-based access controlEnterprise **Breaking change in v3.7.0**: [Label-based access control](/database-management/authentication-and-authorization/role-based-access-control#fine-grained-access-control) has significant From 99c68c836dc24d6cde40bd7e52afd4e63a0c5f65 Mon Sep 17 00:00:00 2001 From: Matea Pesic <80577904+matea16@users.noreply.github.com> Date: Tue, 11 Nov 2025 14:44:26 +0100 Subject: [PATCH 12/12] Apply suggestions from code review --- .../mlbac-migration-guide.mdx | 11 ++-- .../role-based-access-control.mdx | 50 +++++++++---------- 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx b/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx index 51a14b0b0..d81adaef9 100644 --- a/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx +++ b/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx @@ -1,11 +1,11 @@ --- -title: "Migrating to v3.7 label-based access control" +title: "Migrate to v3.7 label-based access control" description: "Guide for upgrading from v3.6 label-based access control to v3.7 multi-label based access control" --- import { Callout } from 'nextra/components' -# Migrating to v3.7 label-based access controlEnterprise +# Migrate to v3.7 label-based access control Enterprise **Breaking change in v3.7.0**: [Label-based access control](/database-management/authentication-and-authorization/role-based-access-control#fine-grained-access-control) has significant @@ -68,7 +68,7 @@ Save the output: you'll need it to recreate per-label rules. ```bash # Default location. Adjust if using a custom data directory -cp -r /var/lib/memgraph/auth /backup/location/auth-backup +cp -r /var/lib/memgraph/auth/backup/location/auth-backup ``` ## What gets migrated automatically @@ -166,7 +166,4 @@ Connect as each user and verify: - [ ] Recreate per-edge type rules - [ ] Test user access -## See also - -- [Full RBAC documentation](/database-management/authentication-and-authorization/role-based-access-control) -- [All v3.7 changes](/release-notes) \ No newline at end of file +For additional details, refer to the [RBAC documentation] and the complete [summary of changes](/release-notes#memgraph-v370---november-19th-2025) in version 3.7. \ No newline at end of file diff --git a/pages/database-management/authentication-and-authorization/role-based-access-control.mdx b/pages/database-management/authentication-and-authorization/role-based-access-control.mdx index 3a8659222..fd29341cb 100644 --- a/pages/database-management/authentication-and-authorization/role-based-access-control.mdx +++ b/pages/database-management/authentication-and-authorization/role-based-access-control.mdx @@ -450,15 +450,15 @@ with the legend: in front of each label (e.g. `:Person`), or `*` for creating a global rule matching all labels in the graph - `user_or_role` is the already created user or role in Memgraph -- `MATCHING ANY` means that the rule will apply to any vertex having one or more -of the specified labels, regardless of any additional labels that the vertex may +- `MATCHING ANY` means that the rule will apply to any node having one or more +of the specified labels, regardless of any additional labels that the node may have -- `MATCHING EXACTLY` will mean that the rule will apply to any vertex having +- `MATCHING EXACTLY` will mean that the rule will apply to any node having all of the labels specified, and no additional labels - If the `MATCHING` clause is omitted, `MATCHING ANY` is assumed by default - `MATCHING` clauses cannot be used when creating global (`*`) rules -For example, granting a `READ` permission on any vertices with labels `User` or +For example, granting a `READ` permission on any nodes with labels `User` or `Product` to user `charlie` would be written as: ```cypher @@ -496,8 +496,8 @@ GRANT READ ON NODES CONTAINING LABELS * TO charlie; ``` For denying visibility to a node, use the `NOTHING` permission. Granting -`NOTHING` creates an explicit DENY rule for the given label specification, -which overrides any existing permissions. +`NOTHING` creates an explicit **DENY** rule for the given label specification, +**which overrides any existing permissions**. ```cypher GRANT NOTHING ON NODES CONTAINING LABELS :User, :Person TO charlie; @@ -596,12 +596,12 @@ overrides all grants, and the user will have no access to any `:Item` nodes. #### Combining matching rules -When a vertex matches multiple label specifications, all matching rules are +When a node matches multiple label specifications, all matching rules are applied and their permissions are combined: -- The effective permissions for a vertex are the union (OR) of all permissions +- The effective permissions for a node are the union (OR) of all permissions from matching rules -- If any matching rule grants `NOTHING`, the vertex is denied: explicit deny +- If any matching rule grants `NOTHING`, the node is denied: explicit deny overrides all grants - Rules are matched based on their label specification and matching mode @@ -612,8 +612,8 @@ GRANT READ ON NODES CONTAINING LABELS :User MATCHING ANY TO charlie; GRANT UPDATE ON NODES CONTAINING LABELS :Employee MATCHING ANY TO charlie; ``` -A vertex with labels `:User:Employee` matches both rules. `charlie` will have both -`READ` and `UPDATE` permissions on this vertex, since permissions from all +A node with labels `:User:Employee` matches both rules. `charlie` will have both +`READ` and `UPDATE` permissions on this node, since permissions from all matching rules are combined. However, if we add an explicit deny: @@ -622,8 +622,8 @@ However, if we add an explicit deny: GRANT NOTHING ON NODES CONTAINING LABELS :Admin MATCHING ANY TO charlie; ``` -A vertex with labels `:User:Employee:Admin` matches all three rules. `charlie` -will have `NOTHING` (explicit deny) on this vertex, since `NOTHING` takes +A node with labels `:User:Employee:Admin` matches all three rules. `charlie` +will have `NOTHING` (explicit deny) on this node, since `NOTHING` takes precedence over any granted permissions. The `MATCHING` mode also affects which rules apply: @@ -633,19 +633,19 @@ GRANT READ ON NODES CONTAINING LABELS :User, :Employee MATCHING EXACTLY TO charl GRANT UPDATE ON NODES CONTAINING LABELS :Employee MATCHING ANY TO charlie; ``` -- A vertex with labels `:User:Employee` (only these two labels) matches the first +- A node with labels `:User:Employee` (only these two labels) matches the first rule exactly, and the second rule (has `:Employee`). `charlie` has both `READ` and `UPDATE` -- A vertex with labels `:User:Employee:Admin` matches only the second +- A node with labels `:User:Employee:Admin` matches only the second rule (has `:Employee`, but not exactly `:User:Employee`). `charlie` has only `UPDATE` -- A vertex with label `:Employee` matches only the second rule. `charlie` has +- A node with label `:Employee` matches only the second rule. `charlie` has only `UPDATE` -##### Global permissions and label-specific rules +{
Global permissions and label-specific rules
} Global permissions (granted on `*`) act as a fallback when no specific label -specification matches a vertex. When a vertex matches a specific label rule, +specification matches a node. When a node matches a specific label rule, that rule takes precedence over the global permission. For example: @@ -655,9 +655,9 @@ GRANT READ, UPDATE ON NODES CONTAINING LABELS * TO charlie; GRANT NOTHING ON NODES CONTAINING LABELS :Confidential MATCHING ANY TO charlie; ``` -- A vertex with label `:User` has no specific rule match, so the global `*` +- A node with label `:User` has no specific rule match, so the global `*` permission applies. `charlie` has `READ` and `UPDATE` -- A vertex with label `:Confidential` matches the specific rule. The specific +- A node with label `:Confidential` matches the specific rule. The specific `NOTHING` rule overrides the global permission, so `charlie` has no access Another example: @@ -667,16 +667,16 @@ GRANT READ ON NODES CONTAINING LABELS * TO charlie; GRANT UPDATE ON NODES CONTAINING LABELS :Document MATCHING ANY TO charlie; ``` -- A vertex with label `:User` matches only the global rule. `charlie` has +- A node with label `:User` matches only the global rule. `charlie` has `READ` -- A vertex with label `:Document` matches the specific rule. `charlie` has +- A node with label `:Document` matches the specific rule. `charlie` has `UPDATE` from the specific rule, but the global `READ` is replaced by the specific rule, so `charlie` has only `UPDATE` -- A vertex with labels `:Document:Draft` matches the specific rule (has +- A node with labels `:Document:Draft` matches the specific rule (has `:Document`). `charlie` has only `UPDATE` -Key principle: Once any specific label rule matches a vertex, the global `*` -permission is not considered for that vertex. +Key principle: Once any specific label rule matches a node, the global `*` +permission is not considered for that node. #### Show privileges for label-based access control