diff --git a/pages/database-management/multi-tenancy.mdx b/pages/database-management/multi-tenancy.mdx index 49129b3ba..1d43c2747 100644 --- a/pages/database-management/multi-tenancy.mdx +++ b/pages/database-management/multi-tenancy.mdx @@ -7,411 +7,20 @@ import { Callout } from 'nextra/components' # Multi-tenancy Enterprise -Multi-tenant support in Memgraph enables users to manage multiple isolated -databases within a single instance. The primary objective is to facilitate -efficient resource isolation, maintain data integrity, and manage access for -different clients. +## [How multi-tenancy works](/database-management/multi-tenancy/how-multi-tenancy-works) +Learn how multi-tenancy works in Memgraph, including difference between the default database vs. +isolated databases, configuration, and backwards compatibility. -In the current version, all isolated databases share the underlying resources so -there is no provision to restrict CPU or RAM usage for a specific database. -Instead, global limitations are imposed on Memgraph as a whole. +## [Setup multi-tenancy](/database-management/multi-tenancy/setup-multi-tenancy) +Learn how to set up multi-tenancy in Memgraph, including user main database, configuration +flags, and connecting to databases. -## Default database +## [Best practices](/database-management/multi-tenancy/best-practices) +Learn best practices for multi-tenancy in Memgraph, including default database recommendations, +user privileges, and audit logs. -A default database named `memgraph` is automatically created during startup. New -users are granted access only to this default database. The default -database name cannot be altered. +## [Reference commands](/database-management/multi-tenancy/reference-commands) +Complete reference for all multi-tenancy Cypher commands in Memgraph. -### Default database best practices - -In multi-tenant environments, we recommend treating the default "memgraph" -database as an administrative/system database rather than storing application -data in it. This approach provides better security and isolation, especially -given recent changes to authentication and authorization requirements. - -#### Why treat memgraph as an admin database? - -As of Memgraph v3.5, users have to have both the `AUTH` privilege and access to -the default "memgraph" database to execute authentication and authorization -queries. Additionally, replication queries (such as `REGISTER REPLICA`, `SHOW -REPLICAS`, etc.) and multi-database queries (such as `SHOW DATABASES`, `CREATE -DATABASE`, etc.) also now target the "memgraph" database and require access to -it. This requirement affects multi-tenant environments where users might have -access to other databases but not the default one. - -#### Recommended setup - -1. **Restrict memgraph database access**: Only grant access to the "memgraph" - database to privileged users who need to perform system administration tasks -2. **Use tenant-specific databases**: Store all application data in dedicated - tenant databases -3. **Separate concerns**: Keep user management, role management, system - administration, replication management, and multi-database management - separate from application data - -#### Example configuration - -```cypher --- Create admin role with full system privileges -CREATE ROLE system_admin; -GRANT ALL PRIVILEGES TO system_admin; -GRANT DATABASE memgraph TO system_admin; - --- Create tenant-specific roles (no access to memgraph database) -CREATE ROLE tenant1_admin; -CREATE ROLE tenant1_user; -CREATE ROLE tenant2_admin; -CREATE ROLE tenant2_user; - --- Grant appropriate permissions to tenant roles -GRANT MATCH, CREATE, MERGE, SET, DELETE, INDEX 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, 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, 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, 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; -GRANT DATABASE tenant2_db TO tenant2_admin, tenant2_user; - --- Create users -CREATE USER system_admin_user IDENTIFIED BY 'admin_password'; -CREATE USER tenant1_admin_user IDENTIFIED BY 't1_admin_pass'; -CREATE USER tenant1_regular_user IDENTIFIED BY 't1_user_pass'; -CREATE USER tenant2_admin_user IDENTIFIED BY 't2_admin_pass'; -CREATE USER tenant2_regular_user IDENTIFIED BY 't2_user_pass'; - --- Assign roles -SET ROLE FOR system_admin_user TO system_admin; -SET ROLE FOR tenant1_admin_user TO tenant1_admin; -SET ROLE FOR tenant1_regular_user TO tenant1_user; -SET ROLE FOR tenant2_admin_user TO tenant2_admin; -SET ROLE FOR tenant2_regular_user TO tenant2_user; -``` - -In this configuration: -- `system_admin_user` can perform all authentication/authorization, replication, - and multi-database operations and has access to the "memgraph" database -- Tenant users can only access their respective tenant databases -- Application data is completely isolated in tenant-specific databases -- The "memgraph" database serves purely as an administrative database - -## Isolated databases - -Isolated databases within Memgraph function as distinct single-database Memgraph -instances. Queries executed on a specific database should operate as if it were -the sole database in the system, preventing cross-database contamination. Users -interact with individual databases, and cross-database queries are prohibited. - -Every database has its own database UUID, which can be read by running the `SHOW -STORAGE INFO` query on a particular database. - -## Database configuration and data directory - -At present, all isolated databases share identical configurations. There is no -provision to specify a per-database configuration. - -The sole distinction lies in the location of the data directory. The designated -data directory serves as the root and retains data associated with the default -database. Other databases are housed in new directories within -`data_directory/databases/*db_name*`. - -The default `memgraph` database also includes a directory -`data_directory/databases/memgraph`, which contains symbolic links leading back -to the root. Some links are proactively generated and their status may vary -based on configuration. - -## User interface - -### Cypher queries for multi-tenancy - -Users interact with multi-tenant features through specialized Cypher queries: - -1. `CREATE DATABASE name`: Creates a new database. -2. `DROP DATABASE name [FORCE]`: Deletes a specified database. -3. `RENAME DATABASE old_name TO new_name`: Renames a database. -4. `SHOW DATABASE`: Shows the current used database. It will return `NULL` if no - database is currently in use. You can also use `SHOW CURRENT DATABASE` for - the same functionality. This command does not require any special privileges. - -5. `SHOW DATABASES`: Shows only the existing set of multitenant databases. -6. `USE DATABASE name`: Switches focus to a specific database (disabled during - transactions). -7. `GRANT DATABASE name TO user`: Grants a user access to a specified database. -8. `DENY DATABASE name FROM user`: Denies a user's access to a specified - database. -9. `REVOKE DATABASE name FROM user`: Removes database from user's authentication - context. -10. `SET MAIN DATABASE name FOR user`: Sets a user's default (landing) database. -11. `SHOW DATABASE PRIVILEGES FOR user`: Lists a user's database access rights. - -### DROP DATABASE with FORCE - -The `DROP DATABASE` command removes an existing database. You can optionally -include the `FORCE` parameter to delete a database even when it has active -connections or transactions. - -{

Syntax

} - -```cypher -DROP DATABASE database_name [FORCE]; -``` - -{

Behavior

} - -- **Without `FORCE`**: The command will fail if the database is currently in use - by any active connections or transactions. -- **With `FORCE`**: The database will be immediately hidden from new connections, - but actual deletion is deferred until it's safe to proceed. All active - transactions using the database will be terminated. - -{

Use cases for FORCE

} - -- **Emergency cleanup**: Remove a database stuck in an inconsistent or - long-running state. -- **Administrative maintenance**: Perform system maintenance requiring immediate - database removal. -- **Development environments**: Quickly reset test environments that might still - have active connections. - -{

Privileges required

} - -Using the `FORCE` option requires: -- `MULTI_DATABASE_EDIT` privilege -- Access to the `memgraph` database -- `TRANSACTION_MANAGEMENT` privilege (to terminate active transactions) - -{

Important considerations

} - -- All active transactions on the target database will be forcibly terminated. -- The database becomes immediately unavailable to new connections. -- Actual deletion may be deferred until existing connections are properly closed. -- **This operation cannot be undone.** - -### RENAME DATABASE - -The `RENAME DATABASE` command allows you to rename an existing database to a new -name. This simplifies administrative workflows by eliminating the need to create -a new database, recover from a snapshot, and drop the old database. - -{

Syntax

} - -```cypher -RENAME DATABASE old_name TO new_name; -``` - -{

Behavior

} - -- The database is **renamed immediately** without requiring unique access. -- If you are currently using the database being renamed, the current database - context is automatically updated to the new name. -- All existing data, indexes, constraints, and other database objects are - preserved. - - -Current implementation of `RENAME` does not update auth data. User/role database -access and database-specific roles information is not updated. This can lead to -unindented access to databases. - - - -{

Important considerations

} - -- The `RENAME DATABASE` command requires the `MULTI_DATABASE_EDIT` privilege and - access to the `memgraph` database. -- The new database name must not already exist. -- The old database name must exist. -- This operation cannot be undone once completed. -- All active connections to the database will continue to work seamlessly with - the new name. - - -### User's main database - -Administrators assign default databases to users, ensuring a seamless and secure -connection experience. Users cannot connect to Memgraph if they lack access -rights to their default database. This situation may arise from database -deletion or revoked access rights. - -### User privileges and database access - -Authentication and authorization data are shared across databases, providing a -unified source of truth. A single user can access multiple databases with a -global set of privileges, but currently, per-database privileges cannot be -granted. - - - -User-role mappings are simple maps located in the user. Deleting or renaming the database will not update this information. The admin needs to make sure the correct access is maintained at all times. - - - -Access to all databases can be granted or revoked using wildcards: -`GRANT DATABASE * TO user;`, `DENY DATABASE * FROM user;` or -`REVOKE DATABASE * FROM user;`. - -### Multi-database queries and the memgraph database - -As of Memgraph v3.5 multi-database queries (such as `SHOW DATABASES`, `CREATE -DATABASE`, `DROP DATABASE`, `RENAME DATABASE`, etc.) target the "memgraph" -database and require access to it. - -To execute these queries, users must have: -- The appropriate privileges (`MULTI_DATABASE_USE`, `MULTI_DATABASE_EDIT`) -- **AND** access to the default "memgraph" database - -### Multi-tenant query syntax changes - -As of Memgraph v3.5 the syntax for certain queries in multi-tenant environments -have changed. The `SHOW ROLE` and `SHOW PRIVILEGES` commands now require -specifying the database context in some cases. - -**SHOW ROLE FOR USER**: This command does not require database specification and -will show all roles assigned to the user across all databases. - -**SHOW PRIVILEGES FOR USER**: This command requires database specification in -multi-tenant environments. - -**SHOW PRIVILEGES FOR ROLE**: This command does not require database -specification and will show all privileges for the role. - -In multi-tenant environments, you must specify which database context to use -when showing privileges for users: - -1. **Show roles for the user's main database:** -```cypher -SHOW ROLE FOR user_name ON MAIN; -``` - -2. **Show roles for the current database:** -```cypher -SHOW ROLE FOR user_name ON CURRENT; -``` - -3. **Show roles for a specific database:** -```cypher -SHOW ROLE FOR user_name ON DATABASE database_name; -``` - -#### SHOW PRIVILEGES syntax in multi-tenant environments - -Similarly, the `SHOW PRIVILEGES` command requires database context specification: - -1. **Show privileges for the user's main database:** -```cypher -SHOW PRIVILEGES FOR user_or_role ON MAIN; -``` - -2. **Show privileges for the current database:** -```cypher -SHOW PRIVILEGES FOR user_or_role ON CURRENT; -``` - -3. **Show privileges for a specific database:** -```cypher -SHOW PRIVILEGES FOR user_or_role ON DATABASE database_name; -``` - -These commands return the aggregated roles and privileges for the user in the -specified database context. The `ON MAIN` option shows information for the -user's main database, `ON CURRENT` shows information for whatever database is -currently active, and `ON DATABASE` shows information for the explicitly -specified database. - -#### Impact on multi-tenant environments - -In multi-tenant environments where users might not have access to the "memgraph" -database, multi-database management operations will fail. This reinforces the -recommendation to treat the "memgraph" database as an administrative/system -database. - -#### Example: Admin user with multi-database privileges - -```cypher --- Create admin role with multi-database privileges -CREATE ROLE multi_db_admin; -GRANT MULTI_DATABASE_USE, MULTI_DATABASE_EDIT TO multi_db_admin; -GRANT DATABASE memgraph TO multi_db_admin; - --- Create user with multi-database admin role -CREATE USER db_admin IDENTIFIED BY 'admin_password'; -SET ROLE FOR db_admin TO multi_db_admin; -``` - -In this setup, `db_admin` can: -- Execute all multi-database queries (`SHOW DATABASES`, `CREATE DATABASE`, `DROP - DATABASE`, `RENAME DATABASE`, etc.) -- Access the "memgraph" database for administrative operations -- Manage the multi-tenant database configuration - -#### Best practice - -For multi-database management, ensure that users who need to perform -multi-database operations have both the appropriate multi-database privileges -and access to the "memgraph" database. This aligns with the overall -recommendation to treat the "memgraph" database as an administrative database in -multi-tenant environments. - -### Additional multi-tenant privileges - -Administrators manage multi-tenant privileges with: - -- `MULTI_DATABASE_USE`: Enables database switching and listing. -- `MULTI_DATABASE_EDIT`: Permits database creation and deletion. - -### Configuration flags - -The `data-recovery-on-startup` flag replaces `storage-recover-on-startup`, -facilitating recovery of individual databases and their contents during startup. - -### Connecting to a database - -The user can interact with multi-tenant databases in two ways: - -1. Through Cypher queries. -2. When using Neo4j drivers, by defining the `database` field. - The `USE DATABASE` query is disabled when the database field is defined. - All queries run against the specified database only. - -When connecting to Memgraph without defining a particular landing database, -you will be connected to the default database set for the user. In case the user -does not have a default (main) database, a database-less connection will be -established. During this connection, the user can execute queries that do not -manipulate any data. User can still use multi-tenant queries and define a -database to use via the appropriate Cypher query. - -Example using Neo4j Python driver: - -```python -import neo4j - -driver = neo4j.GraphDatabase.driver("bolt://localhost:7687", auth=("user", "pass")) - -with driver.session() as session: - session.run(...) # Executes on the default database - session.run("USE DATABASE db1") - session.run(...) # Executes on db1 - -with driver.session(database="db2") as session: - session.run(...) # Executes on db2 - session.run("USE DATABASE db1") # Error: database switching disabled -``` - -### Audit Logs - -Audit logs now encompass the active database name, positioned immediately after -the username field. - -## Backwards compatibility - -The multi-tenant feature ensures backwards compatibility, facilitating smooth -version upgrades and downgrades without disrupting user experience. During an -upgrade, previous data is migrated to the default database, while downgrading -retains data solely in the default database. +## [FAQ](/database-management/multi-tenancy/faq) +Frequently asked questions about multi-tenancy in Memgraph. diff --git a/pages/database-management/multi-tenancy/_meta.ts b/pages/database-management/multi-tenancy/_meta.ts new file mode 100644 index 000000000..77748527d --- /dev/null +++ b/pages/database-management/multi-tenancy/_meta.ts @@ -0,0 +1,7 @@ +export default { + "how-multi-tenancy-works": "How multi-tenancy works", + "setup-examples": "Setup examples", + "best-practices": "Best practices", + "reference-commands": "Reference commands", + "faq": "FAQ" +} diff --git a/pages/database-management/multi-tenancy/best-practices.mdx b/pages/database-management/multi-tenancy/best-practices.mdx new file mode 100644 index 000000000..285ce9439 --- /dev/null +++ b/pages/database-management/multi-tenancy/best-practices.mdx @@ -0,0 +1,58 @@ +--- +title: Best practices +description: Learn best practices for multi-tenancy in Memgraph, including default database recommendations, user privileges, and audit logs. +--- + +import { Callout } from 'nextra/components' + +# Best practices + +## Default database best practices + +In multi-tenant environments, we recommend treating the default `memgraph` +database as an administrative/system database rather than storing application +data in it. This approach provides better security and isolation, especially +given the access requirements for system operations (see [How multi-tenancy works](/database-management/multi-tenancy/how-multi-tenancy-works#access-requirements-and-privileges)). + +## Which command line flags should I set? + +#### data recovery on startup + +The flag `--data-recovery-on-startup=true` is enforced by default. It ensures every database is recovered +from durability files during startup. + +## Connecting to a database + +The user can interact with multi-tenant databases in two ways: + +1. Through Cypher queries (e.g. `USE DATABASE my_database` when you're already in a session). +2. When using Neo4j drivers, by defining the `database` field. + The `USE DATABASE` query is disabled when the database field is defined. + All queries run against the specified database only. + +When connecting to Memgraph without defining a particular landing database, +you will be connected to the default database set for the user. In case the user +does not have a default (main) database, a database-less connection will be +established. During this connection, the user can execute queries that do not +manipulate any data. User can still use multi-tenant queries and define a +database to use via the appropriate Cypher query. + +Example using Neo4j Python driver: + +```python +import neo4j + +driver = neo4j.GraphDatabase.driver("bolt://localhost:7687", auth=("user", "pass")) + +# Immediately run against database db2 +with driver.session(database="db2") as session: + session.run(...) # Executes on db2 + session.run("USE DATABASE db1") # Error: database switching disabled + +# Position into the default memgraph database, then switch inside the session +with driver.session() as session: + session.run(...) # Executes on the default database + session.run("USE DATABASE db1") + session.run(...) # Executes on db1 + +``` diff --git a/pages/database-management/multi-tenancy/faq.mdx b/pages/database-management/multi-tenancy/faq.mdx new file mode 100644 index 000000000..702ff0a48 --- /dev/null +++ b/pages/database-management/multi-tenancy/faq.mdx @@ -0,0 +1,39 @@ +--- +title: Multi-tenancy FAQ +description: Frequently asked questions about multi-tenancy in Memgraph. +--- + +# Multi-tenancy FAQ + +## Capabilities + +### Is there any limit to how many tenants Memgraph can have? +No, there are no limits to the number of tenants you can create in Memgraph, except for the aggregated size of +the whole graph since Memgraph is in-memory. The total memory available to your Memgraph instance will determine +the combined size of all tenant databases. + +### Is there any way for a query to access another tenant? +No, this is the benefit of multi-tenancy which completely logically isolates the tenants. In the implementation, +those are completely different systems with their own respective graphs. Cross-database queries are prohibited, +ensuring complete data isolation between tenants. + +### Is audit log integrated with multi-tenancy? +Audit logs encompass the active database name, positioned immediately after +the username field. + +### How are system resources shared across tenants? +Currently, multi-tenancy doesn't have any strict requirements for tenants. Meaning, all the system CPU +and RAM resources are shared equally based on demand. Memgraph additionally supports +[user profiles](/database-management/authentication-and-authorization/user-profiles) which +can prohibit *noisy neighbour* behaviour on an arbitrary tenant. It is important to monitor +your data growth closely across tenants in order to take necessary actions if a tenant becomes too big. +If you have a specific on-demand feature, let us know by contacting our sales team. + +## Troubleshooting + +### How can I troubleshoot if I misconfigured something with multi-tenancy? +We suggest you always troubleshoot multi-tenancy using the admin user which has all the privileges. +This way you're able to show the relevant information: +- `SHOW DATABASE PRIVILEGES FOR user` - see which databases user has access to +- `SHOW ROLES FOR user` - see which roles are enforced on the user +- `SHOW PRIVILEGES FOR user ON DATABASE x`- see which privileges the user has on the database diff --git a/pages/database-management/multi-tenancy/how-multi-tenancy-works.mdx b/pages/database-management/multi-tenancy/how-multi-tenancy-works.mdx new file mode 100644 index 000000000..0e6a0fbde --- /dev/null +++ b/pages/database-management/multi-tenancy/how-multi-tenancy-works.mdx @@ -0,0 +1,113 @@ +--- +title: How multi-tenancy works +description: Learn how multi-tenancy works in Memgraph, including default database, isolated databases, configuration, and backwards compatibility. +--- + +import { Callout } from 'nextra/components' + +# How multi-tenancy works +Multi-tenant support in Memgraph enables users to manage multiple isolated +databases within a single instance. The primary objective is to facilitate +efficient resource isolation, maintain data integrity, and manage access for +different clients. + +Memgraph for tenant uses the term `database`. Tenant here is a synonym, and multi-tenancy +refers to having multiple databases inside one Memgraph instance. The instance is what in +relational databases would refer to RDBMS (the Memgraph process, graph management system, which +manages all the databases). + +## Databases specification + +### Default database + +A default database named `memgraph` is automatically created during startup. This database +is also the default database for those who don't use multi-tenancy, or use Memgraph Community +Edition. + +New users are granted access only to this default database (they can connect to this database). +The default database name cannot be altered. + +### Access requirements and privileges + +All multi-tenant operations require: +- Access to the default `memgraph` database +- The appropriate privileges, depending on the actual query + + +Additionally, replication, authentication, and authorization queries conform to the same principle. + +For multi-database operations specifically, the privileges are the following: +- `MULTI_DATABASE_USE` privilege - for switching and listing databases +- `MULTI_DATABASE_EDIT` privilege - for creating, deleting, and renaming databases +- Access to the `memgraph` database + +Without access to the `memgraph` database, these operations will fail. + +### Isolated databases + +Isolated databases within Memgraph function as distinct single-database Memgraph +instances. Queries executed on a specific database should operate as if it were +the sole database in the system, preventing cross-database contamination. Users +interact with individual databases, and cross-database queries are prohibited. + + +Cross-database queries are not yet implemented. If you require this feature in Memgraph, +please open a Github issue, or contact our sales team! + + +Every database has its own database UUID, which can be read by running the `SHOW +STORAGE INFO` query on a particular database. + +## Main database for user + +Administrators assign default databases to users, ensuring a seamless and secure +connection experience. Users cannot connect to Memgraph if they lack access +rights to their default database. This situation may arise from database +deletion or revoked access rights. + +## Data storage separation between databases + +The distinction of databases lies in the location of the data directory. The designated +data directory serves as the root and retains data associated with the default +database. Other databases are housed in new directories within +`data_directory/databases/*db_name*`. + +The default `memgraph` database also includes a directory +`data_directory/databases/memgraph`, which contains symbolic links leading back +to the root. Some links are proactively generated and their status may vary +based on configuration. + +## Users, roles, and privileges in the multi-tenant context + +Privileges can be granted in two ways: +- **Directly to users**: Privileges are granted directly to a user account (e.g. `GRANT MATCH TO marko`) +- **Via roles**: Privileges are granted to a role, and then the role is assigned to users + (e.g. `GRANT MATCH TO markos_role`) + +### How privileges apply to databases + +Privileges granted to a user or role apply to **all databases** that the user or role has access to. +This means: + +- If you grant privileges to a role and grant that role access to multiple databases, users with + that role will have those privileges for all of those databases +- If you grant privileges directly to a user and grant that user access to multiple databases, + the user will have those privileges for all of those databases + + +For clean architecture, it is recommended to grant **one and only one database per role**. +This ensures clear separation of concerns and makes privilege management more straightforward. + + +## Backwards compatibility + +The multi-tenant feature ensures backwards compatibility, facilitating smooth +version upgrades and downgrades without disrupting user experience. During an +upgrade, previous data is migrated to the default database, while downgrading +retains data solely in the default database. + +## Sharing of resources between tenants + +In the current version, all isolated databases share the underlying resources so +there is no provision to restrict CPU or RAM usage for a specific database. +Instead, global limitations are imposed on Memgraph as a whole. diff --git a/pages/database-management/multi-tenancy/reference-commands.mdx b/pages/database-management/multi-tenancy/reference-commands.mdx new file mode 100644 index 000000000..96f805f41 --- /dev/null +++ b/pages/database-management/multi-tenancy/reference-commands.mdx @@ -0,0 +1,391 @@ +--- +title: Reference commands +description: Complete reference for all multi-tenancy Cypher commands in Memgraph. +--- + +import { Callout } from 'nextra/components' + +# Multi-tenancy reference queries + + +This reference guide is tightly tied with +**[authentication and authorization guide with multi-tenancy](/database-management/authentication-and-authorization/multiple-roles)**. +Please make sure to read this guide as well. + + +## Multi-database queries + +### CREATE DATABASE + +Command used for creating a new database. + +```cypher +CREATE DATABASE databaseName; +``` + +**Parameters:** +- `databaseName` (symbolic name) - name of the database to be created + +**Behaviour:** +- A new isolated storage will be created. This enables logical separation between graphs. +- Database will be associated with its own database UUID which can be seen with `SHOW STORAGE INFO;` + +**Implications:** +- You can't name your database `memgraph`, or with any other name that's already existing. + +**Privileges required:** +- `MULTI_DATABASE_EDIT` privilege +- Access to the `memgraph` database +- `TRANSACTION_MANAGEMENT` privilege (if you're using `FORCE`, to terminate active transactions) + +**Example:** +```cypher +CREATE DATABASE my_database; +``` + +### DROP DATABASE + +Command used for dropping an existing database. + +```cypher +DROP DATABASE databaseName [FORCE]; +``` + +**Parameters:** +- `databaseName` (symbolic name) - name of the database to be dropped +- `FORCE` (optional parameter) - parameter to delete a database even when it has active + connections or transactions. + +**Behaviour:** +- **Without `FORCE`**: The command will fail if the database is currently in use + by any active connections or transactions. +- **With `FORCE`**: The database will be immediately hidden from new connections, + but actual deletion is deferred until it's safe to proceed. All active + transactions using the database will be terminated. + +**Implications:** +Use cases for `FORCE` dropping the database: +- **Emergency cleanup**: Remove a database stuck in an inconsistent or long-running state. +- **Administrative maintenance**: Perform system maintenance requiring immediate database removal. +- **Development environments**: Quickly reset test environments that might still have active connections. +Additional implications with `FORCE`: +- All active transactions on the target database will be forcibly terminated. +- The database becomes immediately unavailable to new connections. +- Actual deletion may be deferred until existing connections are properly closed. +- **This operation cannot be undone.** + +**Privileges required:** +- `MULTI_DATABASE_EDIT` privilege +- Access to the `memgraph` database +- `TRANSACTION_MANAGEMENT` privilege (if you're using `FORCE`, to terminate active transactions) + +**Example:** +```cypher +DROP DATABASE my_database; +``` + +### RENAME DATABASE + +The `RENAME DATABASE` command allows you to rename an existing database to a new +name. This simplifies administrative workflows by eliminating the need to create +a new database, recover from a snapshot, and drop the old database. + +```cypher +RENAME DATABASE old_name TO new_name; +``` + +**Parameters:** +- `old_name` (symbolic name) - name of the database to be rename +- `new_name` (symbolic name) - new name of the database that will be used + +**Behaviour:** +- The database is **renamed immediately** without requiring unique access. +- If you are currently using the database being renamed, the current database + context is automatically updated to the new name. +- All existing data, indexes, constraints, and other database objects are + preserved. + + +Current implementation of `RENAME` does not update auth data. User/role database +access and database-specific roles information is not updated. This can lead to +unindented access to databases. + + +**Implications:** +- The `RENAME DATABASE` command requires the `MULTI_DATABASE_EDIT` privilege and + access to the `memgraph` database. +- The new database name must not already exist. +- The old database name must exist. +- This operation cannot be undone once completed. +- All active connections to the database will continue to work seamlessly with + the new name. + + **Privileges required:** +- `MULTI_DATABASE_EDIT` privilege +- Access to the `memgraph` database +- `TRANSACTION_MANAGEMENT` privilege (if you're using `FORCE`, to terminate active transactions) + +**Example:** +```cypher +RENAME DATABASE my_database TO my_new_database; +``` + +### SHOW DATABASE + +Command used for showing the current database the user is in. + +```cypher +SHOW DATABASE; +``` + +or + +```cypher +SHOW CURRENT DATABASE; +``` + +**Privileges required:** +- `MULTI_DATABASE_USE` privilege +- Access to the `memgraph` database +- `TRANSACTION_MANAGEMENT` privilege (if you're using `FORCE`, to terminate active transactions) + +### SHOW DATABASES + +Command used for showing the existing set of multitenant databases. + +```cypher +SHOW DATABASES; +``` + +**Privileges required:** +- `MULTI_DATABASE_USE` privilege +- Access to the `memgraph` database +- `TRANSACTION_MANAGEMENT` privilege (if you're using `FORCE`, to terminate active transactions) + +### USE DATABASE + +Used for positioning the user from one database into another. + +```cypher +USE DATABASE databaseName; +``` + +**Parameters:** +- `databaseName` (symbolic name) - name of the database the user wants to use + +**Behaviour:** +- Command will exit the current database/tenant and position itself looking into the tenant from the query + +**Implications:** +- If the database doesn't exist, the command will result in an exception. +- If the user has not been granted with the database, this command will result in an exception. + +**Privileges required:** +- `MULTI_DATABASE_USE` privilege +- Access to the `memgraph` database +- `TRANSACTION_MANAGEMENT` privilege (if you're using `FORCE`, to terminate active transactions) + +**Example:** +```cypher +USE DATABASE my_database; +``` + +## Working with databases and user permissions + +### GRANT DATABASE TO USER + +Grants a user access to a specified database. + +```cypher +GRANT DATABASE databaseName TO user_or_role; +``` + +**Parameters:** +- `databaseName` (symbolic name) - name of the database the user will be granted access with (or `*` for granting all databases) +- `user_or_role` (symbolic name) - name of the user or role which will receive the grant + +**Behaviour:** +- After the command has been executed, the user or role will be granted access to the database. + +**Example:** +```cypher +-- Granting a specific database to the user +GRANT DATABASE my_database TO marko; + +-- Granting every database to the user +GRANT DATABASE * TO josip; +``` + + +### DENY DATABASE FROM USER + +Denies a user's access to a specified database. + +```cypher +DENY DATABASE databaseName FROM user_or_role; +``` + +**Parameters:** +- `databaseName` (symbolic name) - name of the database to deny the access to the user +- `user_or_role` (symbolic name) - name of the user or role which will be denied the access + +**Behaviour:** +- After the command has been executed, the user or role will be denied access to the database. + +**Example:** +```cypher +DENY DATABASE my_database FROM marko; +``` + +### REVOKE DATABASE FROM USER + +Removes database from user's authentication context. + +```cypher +REVOKE DATABASE databaseName FROM user_or_role; +``` + +**Parameters:** +- `databaseName` (symbolic name) - name of the database to revoke from user's authentication context +- `user_or_role` (symbolic name) - name of the user or role to revoke the context from + +**Behaviour:** +- After the command has been executed, the user's authentication context will have no information about + whether he is granted or denied the access to the database. +- This scenario is identical to the initial empty authentication state when you haven't configured any + access to the users. You can proceed with the `GRANT` or `DENY` commands to manipulate the user's privileges. + +**Example:** +```cypher +REVOKE DATABASE my_database FROM marko; +``` + +### SET MAIN DATABASE FOR USER + +Sets a user's default (landing) database when connecting to a database session. + +```cypher +SET MAIN DATABASE databaseName FOR user_or_role; +``` + +**Parameters:** +- `databaseName` (symbolic name) - name of the database which will become the default for the user +- `user_or_role` (symbolic name) - name of the user or role to set the default database to + +**Behaviour:** +- After the command has been executed, the user will on log in be placed in that main database. + +**Implications:** +- Database needs to be granted to the user in order to successfully set it as main. +- If the command is not executed, by default everyone will land into the system's default `memgraph` database. + +**Example:** +```cypher +SET MAIN DATABASE databaseName FOR marko; +``` + + +At the moment, Memgraph doesn't have a command for showing the users main database. If the command +for setting the main database executed successfully, it will become the users main database. + + +## Display of privileges for users and roles + +### SHOW DATABASE PRIVILEGES FOR USER + +Lists a user's database access rights (granted and denied). + +```cypher +SHOW DATABASE PRIVILEGES FOR user_or_role; +``` + +**Parameters:** +- `user_or_role` (symbolic name) - name of the user or role to check the database privileges + +**Behaviour:** +- The command will show 2 columns: `grants` and `denies` with the list of databases in each one. + +**Implications:** +- A user has access to the database if he has an explicit grant and no denies to the database. +- If the user has `*` in the grants, it is granted every database (if there are no explicit denies). +- The first user ever created in Memgraph gets all the privileges, and therefore gets the grant of every database in Memgraph +- All subsequent users get no privileges, but have access to the default Memgraph database. +- For the user, an aggregate view for database privileges is shown for his direct database privileges + privileges granted from + its respective roles + +**Example:** +```cypher +-- Example output for the admin user which has access to all the databases +SHOW DATABASE PRIVILEGES FOR admin; ++--------+--------+ +| grants | denies | ++--------+--------+ +| "*" | [] | ++--------+--------+ + +-- Example output for the non admin user which by default gets granted only the memgraph database to connect +SHOW DATABASE PRIVILEGES FOR marko; ++--------------+--------+ +| grants | denies | ++--------------+--------+ +| ["memgraph"] | [] | ++--------------+--------+ +``` + +### SHOW ROLE FOR USER + +The command will output roles for the user across all databases. + +**Implications:** +- If database is not specified, it will show the aggregate roles for the user. +- If database is specified, it will show the roles for the respective databases. + +**Example:** +```cypher +SHOW ROLE FOR marko; +``` + +**Example:** +```cypher +-- on the user's main database +SHOW ROLE FOR user_or_role ON MAIN; + +-- on the user's database inside the session +SHOW ROLE FOR user_or_role ON CURRENT; + +-- on an arbitrary database +SHOW ROLE FOR user_or_role ON DATABASE my_database; +``` + +### SHOW PRIVILEGES FOR USER_OR_ROLE ON DATABASE + +Shows user or role privileges on a desired database. + +**Implications:** +- In a multi-tenant environment, the database needs to be specified. +- Database specified is either: `MAIN`, `CURRENT` or any other valid database name. +- In case of the user, an aggregated view for both user's specific privileges, and all + his role privileges on the database is shown. + +**Example:** +```cypher +-- on the user's main database +SHOW PRIVILEGES FOR marko ON MAIN; + +-- on the user's database inside the session +SHOW PRIVILEGES FOR marko ON CURRENT; + +-- on an arbitrary database +SHOW PRIVILEGES FOR marko ON DATABASE my_database; +``` + + +A given set of privileges is available to all the granted databases for a user or role. + + +## Multi-tenant privileges + +Administrators manage multi-tenant privileges with: + +- `MULTI_DATABASE_USE`: Enables database switching and listing. +- `MULTI_DATABASE_EDIT`: Permits database creation and deletion. diff --git a/pages/database-management/multi-tenancy/setup-examples.mdx b/pages/database-management/multi-tenancy/setup-examples.mdx new file mode 100644 index 000000000..cba46e2b8 --- /dev/null +++ b/pages/database-management/multi-tenancy/setup-examples.mdx @@ -0,0 +1,114 @@ +--- +title: Setup examples +description: Learn how to set up multi-tenancy in Memgraph, using different example scenarios. +--- + +import { Callout } from 'nextra/components' + +## Setup examples + +### Basic user with multi-database privileges + +Here, we will see a basic scenario where a user can run multi-database queries with minimal privileges. +To enable the user with such capabilities, we need to ensure the following rules apply: +- user is granted the default `memgraph` database, as all system queries are executed against it +- user has the appropriate set of privileges to execute the commands + (`MULTI_DATABASE_USE` and `MULTI_DATABASE_EDIT`) + +```cypher +-- Create role with multi-database privileges +CREATE ROLE multi_db_role; +GRANT MULTI_DATABASE_USE, MULTI_DATABASE_EDIT TO multi_db_role; +GRANT DATABASE memgraph TO multi_db_role; + +-- Create user with multi-database admin role +CREATE USER db_user IDENTIFIED BY 'test'; +SET ROLE FOR db_user TO multi_db_role; +``` + +In this setup, `db_user` can: +- Execute all multi-database queries (`SHOW DATABASES`, `CREATE DATABASE`, `DROP + DATABASE`, `RENAME DATABASE`, etc.) +- Access the `memgraph` database for administrative operations +- Manage the multi-tenant database configuration + +### Configuring admin and non-admin users + +We suggest using these advices when configuring admin and non-admin users in a multi-tenant +environment: + +1. **Restrict memgraph database access**: Only grant access to the `memgraph` + database to privileged users who need to perform system administration tasks. +2. **Use tenant-specific databases**: Store all application data in dedicated + tenant databases. +3. **Separate concerns**: Keep user management, role management, system + administration, replication management, and multi-database management + separate from application data. + +The following is an example scenario with a multi-tenant environment, using admin and +non-admin users which facilitates these rules. + +In this configuration: +- `system_admin_user` can perform all authentication/authorization, replication, + and multi-database operations and has access to the "memgraph" database. +- because `system-admin_user` is the first user being created, it implicitly gets all the privileges + for creating graph objects. We will here though showcase only granting system based privileges (for + execution of system queries). +- Tenant users can only access their respective tenant databases. +- Application data is completely isolated in tenant-specific databases +- The `memgraph` database serves purely as an administrative database + +```cypher +-- Create admin role with full system privileges +CREATE ROLE system_admin_role; +GRANT ALL PRIVILEGES TO system_admin_role; +GRANT DATABASE memgraph TO system_admin_role; + +-- Create tenant-specific roles (no access to memgraph database) +CREATE ROLE tenant1_admin; +CREATE ROLE tenant1_non_admin; +CREATE ROLE tenant2_admin; +CREATE ROLE tenant2_non_admin; + +-- Grant appropriate permissions to tenant roles +GRANT MATCH, CREATE, MERGE, SET, DELETE, INDEX TO tenant1_admin; +GRANT CREATE, READ, UPDATE, DELETE ON NODES CONTAINING LABELS * TO tenant1_admin; +GRANT CREATE, READ, UPDATE, DELETE ON EDGES OF TYPE * TO tenant1_admin; + +GRANT MATCH, CREATE, MERGE, SET, DELETE TO tenant1_non_admin; +GRANT CREATE, READ, UPDATE, DELETE ON NODES CONTAINING LABELS * TO tenant1_non_admin; +GRANT CREATE, READ, UPDATE, DELETE ON EDGES OF TYPE * TO tenant1_non_admin; + +GRANT MATCH, CREATE, MERGE, SET, DELETE, INDEX TO tenant2_admin; +GRANT CREATE, READ, UPDATE, DELETE ON NODES CONTAINING LABELS * TO tenant2_admin; +GRANT CREATE, READ, UPDATE, DELETE ON EDGES OF TYPE * TO tenant2_admin; + +GRANT MATCH, CREATE, MERGE, SET, DELETE TO tenant2_non_admin; +GRANT CREATE, READ, UPDATE, DELETE ON NODES CONTAINING LABELS * TO tenant2_non_admin; +GRANT CREATE, READ, UPDATE, DELETE ON EDGES OF TYPE * TO tenant2_non_admin; + +-- Grant access only to tenant databases +GRANT DATABASE tenant1_db TO tenant1_admin, tenant1_non_admin; +GRANT DATABASE tenant2_db TO tenant2_admin, tenant2_non_admin; + +-- Create users +-- This is the first user being created, so he will implicitly get all the privileges +-- This is a design decision +CREATE USER system_admin_user IDENTIFIED BY 'test'; + +-- These users don't have any privileges so we need to grant them roles +CREATE USER tenant1_admin_user IDENTIFIED BY 'test'; +CREATE USER tenant1_non_admin_user IDENTIFIED BY 'test'; +CREATE USER tenant2_admin_user IDENTIFIED BY 'test'; +CREATE USER tenant2_non_admin_user IDENTIFIED BY 'test'; + +-- Assign roles +-- User already has all the permissions, but for staying consistent we will grant the role nevertheless +SET ROLE FOR system_admin_user TO system_admin; + +-- Set the roles for other users, so they can get privileges +SET ROLE FOR tenant1_admin_user TO tenant1_admin; +SET ROLE FOR tenant1_non_admin_user TO tenant1_non_admin; +SET ROLE FOR tenant2_admin_user TO tenant2_admin; +SET ROLE FOR tenant2_non_admin_user TO tenant2_non_admin; +```