From 86569b708fc891c7ac2db81750102e3e1e64ef35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josip=20Mr=C4=91en?= Date: Wed, 19 Nov 2025 11:02:11 +0100 Subject: [PATCH 1/6] Add updated docs --- .../mlbac-migration-guide.mdx | 103 ++++++++++-------- 1 file changed, 60 insertions(+), 43 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 d81adaef9..1ed419e4b 100644 --- a/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx +++ b/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx @@ -4,33 +4,47 @@ description: "Guide for upgrading from v3.6 label-based access control to v3.7 m --- import { Callout } from 'nextra/components' +import { Steps } from 'nextra/components' # 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 -changes. If you use fine-grained access control, read this guide before -upgrading. +**Breaking change in v3.7.0**: [Label-based access control](/database-management/authentication-and-authorization/role-based-access-control#fine-grained-access-control) +has been upgraded with significant changes. If you use fine-grained access control, read this guide before upgrading. +## Motivation for the breaking change +Current label-based access control implementation was good for a number of use cases, but there are certain things that it could not do: +- it had **hierarchical access rights** ➡ If a user had `CREATE_DELETE` permission, he would be given full manipulation access to the node. + Sometimes, you only want to grant `CREATE` separately, without `DELETE`. +- permission lists of for the nodes were not expressive ➡ An example could be that a data science team wants to manipulate all the nodes that have `:DataScience` + label in it. They would also need to be granted additional labels in order to see their nodes, just because the rule was to have permission for EVERY label in the node. + This per se is not troubling if you have one team. **If you have multiple teams**, their permission intersection is zero, meaning they can't have shared visibility ownership + of a node. + ## What's changed? -### Label matching semantics +### Node label matching semantics + +**Before (v3.6):** +Rules matched exact label sets only. By executing the following query: +- `GRANT READ ON LABELS :User` -**Before (v3.6):** Rules matched exact label sets only. -- `GRANT READ ON LABELS :User` matched only `:User`, not `:User:Admin` +the permission would be granted only to nodes which matched exactly the `:User` label. If any other label was present to which you don't have permission, +e.g. (`:User:Admin`), you would be denied access. **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 +- `GRANT READ ON NODES CONTAINING LABELS :User` ➡ if a node contains the label `:User`, grant `READ` on that node +- `GRANT READ ON NODES CONTAINING LABELS :User MATCHING ANY` ➡ same behaviour as above +- `GRANT READ ON NODES CONTAINING LABELS :User MATCHING EXACTLY` ➡ Grants `READ` if the node has exactly the set of labels (`:User` and no more, no less) ### Permission model change **Before (v3.6):** Hierarchical permissions -- `NOTHING`, `READ`, `UPDATE`, `CREATE_DELETE` -- `UPDATE` implied `READ`; `CREATE_DELETE` implied everything +- `NOTHING` ➡ user doesn't have any grants +- `READ` ➡ user can read a node or a relationship +- `UPDATE` ➡ user can read and update a node or a relationship +- `CREATE_DELETE` ➡ user has the full CRUD access on a node or a relationship **After (v3.7):** Discrete permissions - `NOTHING`, `CREATE`, `READ`, `UPDATE`, `DELETE` @@ -39,18 +53,21 @@ 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` | +| v3.6 | v3.7 | Description | +|-------------------------------------------------------|---------------------------------------------------------------------|---------------------------------------------------------| +| `GRANT READ ON LABELS :User, :Client TO alice` | `GRANT READ ON NODES CONTAINING LABELS :User, :Client TO alice` | Added `CONTAINING` keyword. | +| `GRANT UPDATE ON LABELS :Doc TO bob` | `GRANT READ, UPDATE ON NODES CONTAINING LABELS :Doc TO bob` | Separated access rights with discrete permissions. | +| `GRANT CREATE_DELETE ON EDGE_TYPES :KNOWS TO charlie` | `GRANT CREATE, DELETE ON EDGES OF TYPE :KNOWS TO charlie` | Added `OF TYPE` for readability. | +| Not possible in this version | `GRANT READ ON NODES CONTAINING LABELS :User MATCHING ANY TO alice` | Added more expressiveness. | 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** + + +### Export current permissions ```cypher SHOW USERS; @@ -64,13 +81,15 @@ SHOW PRIVILEGES FOR rolename; Save the output: you'll need it to recreate per-label rules. -**2. Back up auth storage** +### Back up auth storage ```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 Global permissions only (grants on `*`) @@ -104,17 +123,18 @@ Specifically: 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` + + +### 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 +### 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:** +### 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 @@ -128,9 +148,14 @@ Your `SHOW PRIVILEGES` output shows `alice` had `READ` on `:User`, and `bob` had 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** + + +## Verify behaviour + + + +### Verify global permissions ```cypher SHOW USERS; @@ -144,26 +169,18 @@ SHOW PRIVILEGES FOR rolename; Check that global (`*`) permissions were migrated correctly. -**2. Recreate per-label rules** +### Recreate per-label rules Execute the `GRANT` statements you prepared to recreate all per-label and per-edge type rules. -**3. Test access** +### 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 - -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 +### Changelog +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. From 8964f94cd830532b17aa677910cd8bc30abf90cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josip=20Mr=C4=91en?= Date: Wed, 19 Nov 2025 11:09:29 +0100 Subject: [PATCH 2/6] Update example --- .../mlbac-migration-guide.mdx | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 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 1ed419e4b..95924a662 100644 --- a/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx +++ b/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx @@ -56,7 +56,7 @@ of `CREATE`, `READ`, `UPDATE`, and `DELETE` can be granted. | v3.6 | v3.7 | Description | |-------------------------------------------------------|---------------------------------------------------------------------|---------------------------------------------------------| | `GRANT READ ON LABELS :User, :Client TO alice` | `GRANT READ ON NODES CONTAINING LABELS :User, :Client TO alice` | Added `CONTAINING` keyword. | -| `GRANT UPDATE ON LABELS :Doc TO bob` | `GRANT READ, UPDATE ON NODES CONTAINING LABELS :Doc TO bob` | Separated access rights with discrete permissions. | +| `GRANT UPDATE ON LABELS :Document TO bob` | `GRANT READ, UPDATE ON NODES CONTAINING LABELS :Document TO bob` | Separated access rights with discrete permissions. | | `GRANT CREATE_DELETE ON EDGE_TYPES :KNOWS TO charlie` | `GRANT CREATE, DELETE ON EDGES OF TYPE :KNOWS TO charlie` | Added `OF TYPE` for readability. | | Not possible in this version | `GRANT READ ON NODES CONTAINING LABELS :User MATCHING ANY TO alice` | Added more expressiveness. | @@ -141,12 +141,23 @@ TO user` for vertex label rules **Example:** -Your `SHOW PRIVILEGES` output shows `alice` had `READ` on `:User`, and `bob` had -`UPDATE` on `:Document`: +Your `SHOW PRIVILEGES` output shows: +- `alice` had `READ` on `:User` node +- `bob` had `UPDATE` on `:Document` node +- `charlie` has `CREATE_DELETE` on `:User` node and `CREATE_DELETE` on `:KNOWS` relationship +- `dave` has `READ` on `:Transportation` and `:Airplane` +- `eve` has `READ` on `:Transportation`, `:Airplane`, `:Bus`, `:Car` ➡ she can see all transportations ```cypher GRANT READ ON NODES CONTAINING LABELS :User MATCHING EXACTLY TO alice; + GRANT READ, UPDATE ON NODES CONTAINING LABELS :Document MATCHING EXACTLY TO bob; + +GRANT CREATE, READ, UPDATE, DELETE ON NODES CONTAINING LABELS :User MATCHING EXACTLY TO alice; +GRANT CREATE, READ, UPDATE, DELETE ON EDGES OF TYPE :KNOWS TO charlie` + +GRANT READ ON NODES CONTAINING LABELS :Transportation, :Airplane MATCHING EXACTLY TO dave; +GRANT READ ON NODES CONTAINING LABELS :Transportation MATCHING ANY TO eve; ``` From 143997ae48de9d48f82090b73959b43e72038ac0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josip=20Mr=C4=91en?= Date: Wed, 19 Nov 2025 11:12:07 +0100 Subject: [PATCH 3/6] Added example scenario --- .../mlbac-migration-guide.mdx | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 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 95924a662..dc3c81fe4 100644 --- a/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx +++ b/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx @@ -85,7 +85,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 ``` @@ -139,27 +139,6 @@ had per-label permissions. For each permission that you need to recreate: 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` node -- `bob` had `UPDATE` on `:Document` node -- `charlie` has `CREATE_DELETE` on `:User` node and `CREATE_DELETE` on `:KNOWS` relationship -- `dave` has `READ` on `:Transportation` and `:Airplane` -- `eve` has `READ` on `:Transportation`, `:Airplane`, `:Bus`, `:Car` ➡ she can see all transportations - -```cypher -GRANT READ ON NODES CONTAINING LABELS :User MATCHING EXACTLY TO alice; - -GRANT READ, UPDATE ON NODES CONTAINING LABELS :Document MATCHING EXACTLY TO bob; - -GRANT CREATE, READ, UPDATE, DELETE ON NODES CONTAINING LABELS :User MATCHING EXACTLY TO alice; -GRANT CREATE, READ, UPDATE, DELETE ON EDGES OF TYPE :KNOWS TO charlie` - -GRANT READ ON NODES CONTAINING LABELS :Transportation, :Airplane MATCHING EXACTLY TO dave; -GRANT READ ON NODES CONTAINING LABELS :Transportation MATCHING ANY TO eve; -``` - ## Verify behaviour @@ -193,5 +172,27 @@ Connect as each user and verify: +## Example scenario + +Your `SHOW PRIVILEGES` output shows: +- `alice` has `READ` on `:User` node +- `bob` has `UPDATE` on `:Document` node +- `charlie` has `CREATE_DELETE` on `:User` node and `CREATE_DELETE` on `:KNOWS` relationship +- `dave` has `READ` on `:Transportation` and `:Airplane` +- `eve` has `READ` on `:Transportation`, `:Airplane`, `:Bus`, `:Car` ➡ she can see all transportations + +Based on this information, the new rewritten authorization queries should be: +```cypher +GRANT READ ON NODES CONTAINING LABELS :User MATCHING EXACTLY TO alice; + +GRANT READ, UPDATE ON NODES CONTAINING LABELS :Document MATCHING EXACTLY TO bob; + +GRANT CREATE, READ, UPDATE, DELETE ON NODES CONTAINING LABELS :User MATCHING EXACTLY TO alice; +GRANT CREATE, READ, UPDATE, DELETE ON EDGES OF TYPE :KNOWS TO charlie` + +GRANT READ ON NODES CONTAINING LABELS :Transportation, :Airplane MATCHING EXACTLY TO dave; +GRANT READ ON NODES CONTAINING LABELS :Transportation MATCHING ANY TO eve; +``` + ### Changelog 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. From 439f5f0dc5cfbb046a5a2f88907c44ef2b7133c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josip=20Mr=C4=91en?= Date: Wed, 19 Nov 2025 11:13:40 +0100 Subject: [PATCH 4/6] Add disclaimer --- .../authentication-and-authorization/mlbac-migration-guide.mdx | 2 ++ 1 file changed, 2 insertions(+) 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 dc3c81fe4..cf57ade50 100644 --- a/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx +++ b/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx @@ -118,6 +118,8 @@ be manually recreated. Specifically: - Any `GRANT ... ON LABELS :Label` rules must be recreated - Any `GRANT ... ON EDGE_TYPES :EdgeType` rules must be recreated + +**This also applies to init scripts and any configuration queries which were using label-based access controls.** Review your pre-upgrade `SHOW PRIVILEGES` output to identify which users/roles From 8da2be85d9dc8653c7eb3cf06ff5da04d8b03cd8 Mon Sep 17 00:00:00 2001 From: Matea Pesic <80577904+matea16@users.noreply.github.com> Date: Wed, 19 Nov 2025 12:14:57 +0100 Subject: [PATCH 5/6] Apply suggestions from code review --- .../mlbac-migration-guide.mdx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 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 cf57ade50..cfc9a8333 100644 --- a/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx +++ b/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx @@ -15,9 +15,9 @@ has been upgraded with significant changes. If you use fine-grained access contr ## Motivation for the breaking change Current label-based access control implementation was good for a number of use cases, but there are certain things that it could not do: -- it had **hierarchical access rights** ➡ If a user had `CREATE_DELETE` permission, he would be given full manipulation access to the node. +- It had **hierarchical access rights** ➡ If a user had `CREATE_DELETE` permission, he would be given full manipulation access to the node. Sometimes, you only want to grant `CREATE` separately, without `DELETE`. -- permission lists of for the nodes were not expressive ➡ An example could be that a data science team wants to manipulate all the nodes that have `:DataScience` +- Permission lists of for the nodes were not expressive ➡ An example could be that a data science team wants to manipulate all the nodes that have `:DataScience` label in it. They would also need to be granted additional labels in order to see their nodes, just because the rule was to have permission for EVERY label in the node. This per se is not troubling if you have one team. **If you have multiple teams**, their permission intersection is zero, meaning they can't have shared visibility ownership of a node. @@ -28,7 +28,8 @@ Current label-based access control implementation was good for a number of use c **Before (v3.6):** Rules matched exact label sets only. By executing the following query: -- `GRANT READ ON LABELS :User` +```cypher +GRANT READ ON LABELS :User the permission would be granted only to nodes which matched exactly the `:User` label. If any other label was present to which you don't have permission, e.g. (`:User:Admin`), you would be denied access. @@ -189,12 +190,12 @@ GRANT READ ON NODES CONTAINING LABELS :User MATCHING EXACTLY TO alice; GRANT READ, UPDATE ON NODES CONTAINING LABELS :Document MATCHING EXACTLY TO bob; -GRANT CREATE, READ, UPDATE, DELETE ON NODES CONTAINING LABELS :User MATCHING EXACTLY TO alice; -GRANT CREATE, READ, UPDATE, DELETE ON EDGES OF TYPE :KNOWS TO charlie` +GRANT CREATE, READ, UPDATE, DELETE ON NODES CONTAINING LABELS :User MATCHING EXACTLY TO charlie; +GRANT CREATE, READ, UPDATE, DELETE ON EDGES OF TYPE :KNOWS TO charlie; GRANT READ ON NODES CONTAINING LABELS :Transportation, :Airplane MATCHING EXACTLY TO dave; GRANT READ ON NODES CONTAINING LABELS :Transportation MATCHING ANY TO eve; ``` ### Changelog -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. +For additional details, refer to the [RBAC documentation](/database-management/authentication-and-authorization/role-based-access-control) and the complete [summary of changes](/release-notes#memgraph-v370---november-19th-2025) in version 3.7. From cbbd757749519a0bd0a7f8026e13ec55d9247cb7 Mon Sep 17 00:00:00 2001 From: matea16 Date: Wed, 19 Nov 2025 13:46:08 +0100 Subject: [PATCH 6/6] fix typo --- .../authentication-and-authorization/mlbac-migration-guide.mdx | 1 + 1 file changed, 1 insertion(+) 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 cfc9a8333..597c67ff4 100644 --- a/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx +++ b/pages/database-management/authentication-and-authorization/mlbac-migration-guide.mdx @@ -30,6 +30,7 @@ Current label-based access control implementation was good for a number of use c Rules matched exact label sets only. By executing the following query: ```cypher GRANT READ ON LABELS :User +``` the permission would be granted only to nodes which matched exactly the `:User` label. If any other label was present to which you don't have permission, e.g. (`:User:Admin`), you would be denied access.