diff --git a/pages/memgraph-lab/configuration.mdx b/pages/memgraph-lab/configuration.mdx index dd3049df8..9d1280b87 100644 --- a/pages/memgraph-lab/configuration.mdx +++ b/pages/memgraph-lab/configuration.mdx @@ -75,97 +75,99 @@ valid Memgraph Enterprise license are available only in a Docker environment. ## List of environment variables -| Variable | Description | Type | Default | -|------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|--------------------| -| `AUTH_NATIVE_IS_DISABLED` | Enable or disable native authentication (username, password) | `boolean` | `false` | -| `AUTH_SSO_STATE_SECRET` | Secret key used to encrypt shared state during the SSO flow; if not set, Lab generates a random one at startup | `string` | | -| `AUTH_SSO_STATE_EXPIRY_SEC` | Duration (in seconds) for which the SSO state remains valid | `number` | `300` | -| `AUTH_OIDC_ENTRA_ID_IS_ENABLED` | Enable or disable Entra ID SSO authentication via OIDC | `boolean` | `false` | -| `AUTH_OIDC_ENTRA_ID_DISPLAY_NAME` | Entra ID OIDC display name "Sign in with ``" | `string` | `"Entra ID"` | -| `AUTH_OIDC_ENTRA_ID_AUTHORIZATION_URL` | Entra ID OIDC authorization URL | `string` | | -| `AUTH_OIDC_ENTRA_ID_TOKEN_URL` | Entra ID OIDC token URL | `string` | | -| `AUTH_OIDC_ENTRA_ID_USER_INFO_URL` | Entra ID OIDC user info URL | `string` | | -| `AUTH_OIDC_ENTRA_ID_CLIENT_ID` | Entra ID OIDC client ID | `string` | | -| `AUTH_OIDC_ENTRA_ID_CLIENT_SECRET` | Entra ID OIDC client secret | `string` | | -| `AUTH_OIDC_ENTRA_ID_CALLBACK_URL` | Entra ID OIDC callback URL | `string` | | -| `AUTH_OIDC_ENTRA_ID_SCOPE` | Entra ID OIDC scope | `string` | `"openid profile"` | -| `AUTH_OIDC_ENTRA_ID_PKCE_IS_ENABLED` | Enables PKCE flow for Entra ID OIDC integration | `boolean` | `false` | -| `AUTH_OIDC_OKTA_IS_ENABLED` | Enable or disable Okta SSO authentication via OIDC | `boolean` | `false` | -| `AUTH_OIDC_OKTA_DISPLAY_NAME` | Okta OIDC display name "Sign in with ``" | `string` | `"Okta"` | -| `AUTH_OIDC_OKTA_AUTHORIZATION_URL` | Okta OIDC authorization URL | `string` | | -| `AUTH_OIDC_OKTA_TOKEN_URL` | Okta OIDC token URL | `string` | | -| `AUTH_OIDC_OKTA_USER_INFO_URL` | Okta OIDC user info URL | `string` | | -| `AUTH_OIDC_OKTA_CLIENT_ID` | Okta OIDC client ID | `string` | | -| `AUTH_OIDC_OKTA_CLIENT_SECRET` | Okta OIDC client secret | `string` | | -| `AUTH_OIDC_OKTA_CALLBACK_URL` | Okta OIDC callback URL | `string` | | -| `AUTH_OIDC_OKTA_SCOPE` | Okta OIDC scope | `string` | `"openid profile"` | -| `AUTH_OIDC_OKTA_PKCE_IS_ENABLED` | Enables PKCE flow for Okta OIDC integration | `boolean` | `false` | -| `AUTH_OIDC_CUSTOM_IS_ENABLED` | Enable or disable custom SSO authentication via OIDC | `boolean` | `false` | -| `AUTH_OIDC_CUSTOM_DISPLAY_NAME` | Custom OIDC display name "Sign in with ``" | `string` | `"SSO"` | -| `AUTH_OIDC_CUSTOM_AUTHORIZATION_URL` | Custom OIDC authorization URL | `string` | | -| `AUTH_OIDC_CUSTOM_TOKEN_URL` | Custom OIDC token URL | `string` | | -| `AUTH_OIDC_CUSTOM_USER_INFO_URL` | Custom OIDC user info URL | `string` | | -| `AUTH_OIDC_CUSTOM_CLIENT_ID` | Custom OIDC client ID | `string` | | -| `AUTH_OIDC_CUSTOM_CLIENT_SECRET` | Custom OIDC client secret | `string` | | -| `AUTH_OIDC_CUSTOM_CALLBACK_URL` | Custom OIDC callback URL | `string` | | -| `AUTH_OIDC_CUSTOM_SCOPE` | Custom OIDC scope | `string` | `"openid profile"` | -| `AUTH_OIDC_CUSTOM_PKCE_IS_ENABLED` | Enables PKCE flow for custom OIDC integration | `boolean` | `false` | -| `AUTH_SAML_ENTRA_ID_IS_ENABLED` | Enable or disable Entra ID SSO authentication via SAML | `boolean` | `false` | -| `AUTH_SAML_ENTRA_ID_DISPLAY_NAME` | Entra ID SAML display name "Sign in with ``" | `string` | `"Entra ID"` | -| `AUTH_SAML_ENTRA_ID_ENTRY_POINT` | Entra ID SAML entry point | `string` | | -| `AUTH_SAML_ENTRA_ID_CALLBACK_URL` | Entra ID SAML callback URL | `string` | | -| `AUTH_SAML_ENTRA_ID_APP_ID` | Entra ID SAML application ID | `string` | | -| `AUTH_SAML_ENTRA_ID_SIGNATURE_ALGORITHM` | Entra ID SAML signature algorithm | `string` | `"sha256"` | -| `AUTH_SAML_OKTA_IS_ENABLED` | Enable or disable Okta SSO authentication via SAML | `boolean` | `false` | -| `AUTH_SAML_OKTA_DISPLAY_NAME` | Okta SAML display name "Sign in with ``" | `string` | `"Okta"` | -| `AUTH_SAML_OKTA_ENTRY_POINT` | Okta SAML entry point | `string` | | -| `AUTH_SAML_OKTA_CALLBACK_URL` | Okta SAML callback URL | `string` | | -| `AUTH_SAML_OKTA_ISSUER` | Okta SAML issuer | `string` | | -| `AUTH_SAML_OKTA_SIGNATURE_ALGORITHM` | Okta SAML signature algorithm | `string` | `"sha256"` | -| `AUTH_SAML_CUSTOM_IS_ENABLED` | Enable or disable Okta SSO authentication via SAML | `boolean` | `false` | -| `AUTH_SAML_CUSTOM_DISPLAY_NAME` | Custom SAML display name "Sign in with ``" | `string` | `"SSO"` | -| `AUTH_SAML_CUSTOM_ENTRY_POINT` | Custom SAML entry point | `string` | | -| `AUTH_SAML_CUSTOM_CALLBACK_URL` | Custom SAML callback URL | `string` | | -| `AUTH_SAML_CUSTOM_ISSUER` | Custom SAML issuer | `string` | | -| `AUTH_SAML_CUSTOM_SIGNATURE_ALGORITHM` | Custom SAML signature algorithm | `string` | `"sha256"` | -| `BASE_PATH` | Set a custom base path for the Lab application (especially beneficial when using a reverse proxy) | `string` | `/` | -| `CONFIG_URI` | Defines the location of the custom configuration file. | `string` | | -| `ENTERPRISE_LICENSE_ORG_NAME` | Enterprise license organization name. Refer to [documentation](/database-management/enabling-memgraph-enterprise) for details on obtaining and configuring the license | `string` | | -| `ENTERPRISE_LICENSE_KEY` | Enterprise license key. Refer to [documentation](/database-management/enabling-memgraph-enterprise) for details on obtaining and configuring the license | `string` | | -| `KEEP_ALIVE_TIMEOUT_MS` | Max time in milliseconds during which Lab will hold the connection | `integer` | `65000` | -| `LOG_LEVEL` | Set the log level: `debug`, `info`, `warn`, `error`. | `string` | `"info"` | -| `LOG_IS_ENABLED` | Enable or disable logging | `boolean` | `true` | -| `LOG_IS_PRETTY_PRINT` | Pretty print logs and error stacktraces in multi-line JSON format | `boolean` | `true` | -| `LOG_CONTEXT_IS_ENABLED` | Enable or disable logging of context information (e.g., identifiers, input data, output data) | `boolean` | `false` | -| `LOG_STACKTRACE_IS_ENABLED` | Enable or disable error stacktraces in the logs | `boolean` | `false` | -| `MODULE_CONTENT_MAX_LEN` | Max length of a query module content | `integer` | `50000` | -| `MODULE_NAME_MAX_LEN` | Max length of the query module name | `integer` | `1000` | -| `MODULE_VALIDATION_IS_ENABLED` | State of module validation | `boolean` | `false` | -| `NODE_LABEL_MAX_LEN` | Max length of the node label | `integer` | `1000` | -| `NODE_LABEL_VALIDATION_IS_ENABLED` | State of node label validation | `boolean` | `false` | -| `NODE_PROPERTY_MAX_LEN` | Max length of the node property | `integer` | `1000` | -| `NODE_PROPERTY_VALIDATION_IS_ENABLED` | State of node property validation | `boolean` | `false` | -| `QUERY_MAX_LEN` | Max length of a Cypher query | `integer` | `5000` | -| `QUERY_VALIDATION_IS_ENABLED` | State of query validation | `boolean` | `false` | -| `QUICK_CONNECT_IS_DISABLED` | State of quick connect feature | `boolean` | `false` | -| `QUICK_CONNECT_MG_HOST` | Host address for quick connect | `string` | `"127.0.0.1"` | -| `QUICK_CONNECT_MG_PORT` | Port for quick connect | `integer` | `7687` | -| `QUICK_CONNECT_MG_IS_ENCRYPTED` | Turn SSL on/off for quick connect | `boolean` | `false` | -| `PORT` | Lab app default listening port | `integer` | `3000` | -| `REQUEST_BODY_LIMIT_MB` | Limit for request body size in MB | `integer` | `20` | -| `SSL_IS_ENABLED` | Enable or disable SSL | `boolean` | `false` | -| `SSL_CERT_PATH` | Path to SSL certificate to be used | `string` | `./ssl/cert.pem` | -| `SSL_KEY_PATH` | Path to SSL key to be used | `string` | `./ssl/key.pem` | -| `SSL_PASSPHRASE` | Passphrase for the SSL key, required if the private key was generated with encryption (without the `-nodes` flag) | `string` | | -| `STORAGE_MG_HOST` | `(Enterprise only)` Memgraph host for the Lab remote storage | `string` | | -| `STORAGE_MG_PORT` | `(Enterprise only)` Memgraph port for the Lab remote storage | `number` | | -| `STORAGE_MG_IS_ENCRYPTED` | `(Enterprise only)` Memgraph SSL on/off for the Lab remote storage | `boolean` | | -| `STORAGE_MG_DATABASE_NAME` | `(Enterprise only)` Memgraph database name for the Lab remote storage | `string` | | -| `STORAGE_MG_USERNAME` | `(Enterprise only)` Memgraph username for the Lab remote storage | `string` | | -| `STORAGE_MG_PASSWORD` | `(Enterprise only)` Memgraph password for the Lab remote storage | `string` | | -| `STORAGE_MG_CONNECT_TIMEOUT_MS` | `(Enterprise only)` Connection timeout in milliseconds for remote storage | `integer` | `10000` | -| `STORAGE_MG_CONNECT_RETRY_MAX_COUNT` | `(Enterprise only)` The maximum number of retries allowed for a successful connection during Lab startup | `integer` | `5` | -| `STREAM_NAME_MAX_LEN` | Max length of the stream name | `integer` | `500` | -| `STREAM_VALIDATION_IS_ENABLED` | State of stream validation | `boolean` | `false` | +| Variable | Description | Type | Default | +|------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|-----------------------------------| +| `AUTH_NATIVE_IS_DISABLED` | Enable or disable native authentication (username, password) | `boolean` | `false` | +| `AUTH_SSO_STATE_SECRET` | Secret key used to encrypt shared state during the SSO flow; if not set, Lab generates a random one at startup | `string` | | +| `AUTH_SSO_STATE_EXPIRY_SEC` | Duration (in seconds) for which the SSO state remains valid | `number` | `300` | +| `AUTH_OIDC_ENTRA_ID_IS_ENABLED` | Enable or disable Entra ID SSO authentication via OIDC | `boolean` | `false` | +| `AUTH_OIDC_ENTRA_ID_DISPLAY_NAME` | Entra ID OIDC display name "Sign in with ``" | `string` | `"Entra ID"` | +| `AUTH_OIDC_ENTRA_ID_AUTHORIZATION_URL` | Entra ID OIDC authorization URL | `string` | | +| `AUTH_OIDC_ENTRA_ID_TOKEN_URL` | Entra ID OIDC token URL | `string` | | +| `AUTH_OIDC_ENTRA_ID_USER_INFO_URL` | Entra ID OIDC user info URL | `string` | | +| `AUTH_OIDC_ENTRA_ID_CLIENT_ID` | Entra ID OIDC client ID | `string` | | +| `AUTH_OIDC_ENTRA_ID_CLIENT_SECRET` | Entra ID OIDC client secret | `string` | | +| `AUTH_OIDC_ENTRA_ID_CALLBACK_URL` | Entra ID OIDC callback URL | `string` | | +| `AUTH_OIDC_ENTRA_ID_SCOPE` | Entra ID OIDC scope | `string` | `"openid profile offline_access"` | +| `AUTH_OIDC_ENTRA_ID_PKCE_IS_ENABLED` | Enables PKCE flow for Entra ID OIDC integration | `boolean` | `false` | +| `AUTH_OIDC_OKTA_IS_ENABLED` | Enable or disable Okta SSO authentication via OIDC | `boolean` | `false` | +| `AUTH_OIDC_OKTA_DISPLAY_NAME` | Okta OIDC display name "Sign in with ``" | `string` | `"Okta"` | +| `AUTH_OIDC_OKTA_AUTHORIZATION_URL` | Okta OIDC authorization URL | `string` | | +| `AUTH_OIDC_OKTA_TOKEN_URL` | Okta OIDC token URL | `string` | | +| `AUTH_OIDC_OKTA_USER_INFO_URL` | Okta OIDC user info URL | `string` | | +| `AUTH_OIDC_OKTA_CLIENT_ID` | Okta OIDC client ID | `string` | | +| `AUTH_OIDC_OKTA_CLIENT_SECRET` | Okta OIDC client secret | `string` | | +| `AUTH_OIDC_OKTA_CALLBACK_URL` | Okta OIDC callback URL | `string` | | +| `AUTH_OIDC_OKTA_SCOPE` | Okta OIDC scope | `string` | `"openid profile offline_access"` | +| `AUTH_OIDC_OKTA_PKCE_IS_ENABLED` | Enables PKCE flow for Okta OIDC integration | `boolean` | `false` | +| `AUTH_OIDC_CUSTOM_IS_ENABLED` | Enable or disable custom SSO authentication via OIDC | `boolean` | `false` | +| `AUTH_OIDC_CUSTOM_DISPLAY_NAME` | Custom OIDC display name "Sign in with ``" | `string` | `"SSO"` | +| `AUTH_OIDC_CUSTOM_AUTHORIZATION_URL` | Custom OIDC authorization URL | `string` | | +| `AUTH_OIDC_CUSTOM_TOKEN_URL` | Custom OIDC token URL | `string` | | +| `AUTH_OIDC_CUSTOM_USER_INFO_URL` | Custom OIDC user info URL | `string` | | +| `AUTH_OIDC_CUSTOM_CLIENT_ID` | Custom OIDC client ID | `string` | | +| `AUTH_OIDC_CUSTOM_CLIENT_SECRET` | Custom OIDC client secret | `string` | | +| `AUTH_OIDC_CUSTOM_CALLBACK_URL` | Custom OIDC callback URL | `string` | | +| `AUTH_OIDC_CUSTOM_SCOPE` | Custom OIDC scope | `string` | `"openid profile offline_access"` | +| `AUTH_OIDC_CUSTOM_PKCE_IS_ENABLED` | Enables PKCE flow for custom OIDC integration | `boolean` | `false` | +| `AUTH_SAML_ENTRA_ID_IS_ENABLED` | Enable or disable Entra ID SSO authentication via SAML | `boolean` | `false` | +| `AUTH_SAML_ENTRA_ID_DISPLAY_NAME` | Entra ID SAML display name "Sign in with ``" | `string` | `"Entra ID"` | +| `AUTH_SAML_ENTRA_ID_ENTRY_POINT` | Entra ID SAML entry point | `string` | | +| `AUTH_SAML_ENTRA_ID_CALLBACK_URL` | Entra ID SAML callback URL | `string` | | +| `AUTH_SAML_ENTRA_ID_APP_ID` | Entra ID SAML application ID | `string` | | +| `AUTH_SAML_ENTRA_ID_SIGNATURE_ALGORITHM` | Entra ID SAML signature algorithm | `string` | `"sha256"` | +| `AUTH_SAML_OKTA_IS_ENABLED` | Enable or disable Okta SSO authentication via SAML | `boolean` | `false` | +| `AUTH_SAML_OKTA_DISPLAY_NAME` | Okta SAML display name "Sign in with ``" | `string` | `"Okta"` | +| `AUTH_SAML_OKTA_ENTRY_POINT` | Okta SAML entry point | `string` | | +| `AUTH_SAML_OKTA_CALLBACK_URL` | Okta SAML callback URL | `string` | | +| `AUTH_SAML_OKTA_ISSUER` | Okta SAML issuer | `string` | | +| `AUTH_SAML_OKTA_SIGNATURE_ALGORITHM` | Okta SAML signature algorithm | `string` | `"sha256"` | +| `AUTH_SAML_CUSTOM_IS_ENABLED` | Enable or disable Okta SSO authentication via SAML | `boolean` | `false` | +| `AUTH_SAML_CUSTOM_DISPLAY_NAME` | Custom SAML display name "Sign in with ``" | `string` | `"SSO"` | +| `AUTH_SAML_CUSTOM_ENTRY_POINT` | Custom SAML entry point | `string` | | +| `AUTH_SAML_CUSTOM_CALLBACK_URL` | Custom SAML callback URL | `string` | | +| `AUTH_SAML_CUSTOM_ISSUER` | Custom SAML issuer | `string` | | +| `AUTH_SAML_CUSTOM_SIGNATURE_ALGORITHM` | Custom SAML signature algorithm | `string` | `"sha256"` | +| `BASE_PATH` | Set a custom base path for the Lab application (especially beneficial when using a reverse proxy) | `string` | `/` | +| `CONFIG_URI` | Defines the location of the custom configuration file. | `string` | | +| `ENTERPRISE_LICENSE_ORG_NAME` | Enterprise license organization name. Refer to [documentation](/database-management/enabling-memgraph-enterprise) for details on obtaining and configuring the license | `string` | | +| `ENTERPRISE_LICENSE_KEY` | Enterprise license key. Refer to [documentation](/database-management/enabling-memgraph-enterprise) for details on obtaining and configuring the license | `string` | | +| `KEEP_ALIVE_TIMEOUT_MS` | Max time in milliseconds during which Lab will hold the connection | `integer` | `65000` | +| `LOG_LEVEL` | Set the log level: `debug`, `info`, `warn`, `error`. | `string` | `"info"` | +| `LOG_IS_ENABLED` | Enable or disable logging | `boolean` | `true` | +| `LOG_IS_PRETTY_PRINT` | Pretty print logs and error stacktraces in multi-line JSON format | `boolean` | `true` | +| `LOG_CONTEXT_IS_ENABLED` | Enable or disable logging of context information (e.g., identifiers, input data, output data) | `boolean` | `false` | +| `LOG_STACKTRACE_IS_ENABLED` | Enable or disable error stacktraces in the logs | `boolean` | `false` | +| `MODULE_CONTENT_MAX_LEN` | Max length of a query module content | `integer` | `50000` | +| `MODULE_NAME_MAX_LEN` | Max length of the query module name | `integer` | `1000` | +| `MODULE_VALIDATION_IS_ENABLED` | State of module validation | `boolean` | `false` | +| `NODE_LABEL_MAX_LEN` | Max length of the node label | `integer` | `1000` | +| `NODE_LABEL_VALIDATION_IS_ENABLED` | State of node label validation | `boolean` | `false` | +| `NODE_PROPERTY_MAX_LEN` | Max length of the node property | `integer` | `1000` | +| `NODE_PROPERTY_VALIDATION_IS_ENABLED` | State of node property validation | `boolean` | `false` | +| `QUERY_MAX_LEN` | Max length of a Cypher query | `integer` | `5000` | +| `QUERY_VALIDATION_IS_ENABLED` | State of query validation | `boolean` | `false` | +| `QUICK_CONNECT_IS_DISABLED` | State of quick connect feature | `boolean` | `false` | +| `QUICK_CONNECT_MG_HOST` | Host address for quick connect | `string` | `"127.0.0.1"` | +| `QUICK_CONNECT_MG_PORT` | Port for quick connect | `integer` | `7687` | +| `QUICK_CONNECT_MG_IS_ENCRYPTED` | Turn SSL on/off for quick connect | `boolean` | `false` | +| `PORT` | Lab app default listening port | `integer` | `3000` | +| `REQUEST_BODY_LIMIT_MB` | Limit for request body size in MB | `integer` | `20` | +| `SESSION_MAX_AGE_SEC` | Maximum lifetime of a session, regardless of user activity. | `integer` | `86400` | +| `SESSION_MAX_IDLE_TIMEOUT_SEC` | Maximum idle time before the user is logged out. Disabled by default. Minimum allowed value is 60 seconds. | `integer` | | +| `SSL_IS_ENABLED` | Enable or disable SSL | `boolean` | `false` | +| `SSL_CERT_PATH` | Path to SSL certificate to be used | `string` | `./ssl/cert.pem` | +| `SSL_KEY_PATH` | Path to SSL key to be used | `string` | `./ssl/key.pem` | +| `SSL_PASSPHRASE` | Passphrase for the SSL key, required if the private key was generated with encryption (without the `-nodes` flag) | `string` | | +| `STORAGE_MG_HOST` | `(Enterprise only)` Memgraph host for the Lab remote storage | `string` | | +| `STORAGE_MG_PORT` | `(Enterprise only)` Memgraph port for the Lab remote storage | `number` | | +| `STORAGE_MG_IS_ENCRYPTED` | `(Enterprise only)` Memgraph SSL on/off for the Lab remote storage | `boolean` | | +| `STORAGE_MG_DATABASE_NAME` | `(Enterprise only)` Memgraph database name for the Lab remote storage | `string` | | +| `STORAGE_MG_USERNAME` | `(Enterprise only)` Memgraph username for the Lab remote storage | `string` | | +| `STORAGE_MG_PASSWORD` | `(Enterprise only)` Memgraph password for the Lab remote storage | `string` | | +| `STORAGE_MG_CONNECT_TIMEOUT_MS` | `(Enterprise only)` Connection timeout in milliseconds for remote storage | `integer` | `10000` | +| `STORAGE_MG_CONNECT_RETRY_MAX_COUNT` | `(Enterprise only)` The maximum number of retries allowed for a successful connection during Lab startup | `integer` | `5` | +| `STREAM_NAME_MAX_LEN` | Max length of the stream name | `integer` | `500` | +| `STREAM_VALIDATION_IS_ENABLED` | State of stream validation | `boolean` | `false` | \ No newline at end of file diff --git a/pages/memgraph-lab/features.mdx b/pages/memgraph-lab/features.mdx index 52f2187e9..9904dabff 100644 --- a/pages/memgraph-lab/features.mdx +++ b/pages/memgraph-lab/features.mdx @@ -42,6 +42,7 @@ different environments: | [Layout](/memgraph-lab/features/layout) | Adjust graph visualizations dynamically for better readability and insights. | ✅ | ✅ | ✅ | | [Logs](/memgraph-lab/features/logs) | Monitor internal processes and troubleshoot issues with real-time access to query logs. | ✅ | ✅ | ✅ | | [Monitoring](/memgraph-lab/features/monitoring) | Real-time monitoring of system, memory, and queries. | 🔒 | 🔒 | 🔒 | +| [Multi-tenancy](/memgraph-lab/features/multi-tenancy) | Switch between different databases within Memgraph Lab. | 🔒 | 🔒 | 🔒 | | [Query modules](/memgraph-lab/features/query-modules) | Extend functionality with custom Cypher procedures and algorithms. | ✅ | ✅ | ✅ | | [Run history](/memgraph-lab/features/run-history) | Access and re-run previously executed queries. | ✅ | ✅ | ✅ | | [Sharing features](/memgraph-lab/features/sharing-features) | Share queries and styles with your team. | ❌ | ❌ | ✅ | diff --git a/pages/memgraph-lab/features/_meta.ts b/pages/memgraph-lab/features/_meta.ts index 3c808ccab..2e424e726 100644 --- a/pages/memgraph-lab/features/_meta.ts +++ b/pages/memgraph-lab/features/_meta.ts @@ -7,6 +7,7 @@ export default { "graph-style-script": "Graph Style Script (GSS)", "layout": "Layout", "logs": "Logs", + "multi-tenancy": "Multi-tenancy", "monitoring": "Monitoring", "run-history": "Run history", "sharing-features": "Sharing features", diff --git a/pages/memgraph-lab/features/custom-configuration.mdx b/pages/memgraph-lab/features/custom-configuration.mdx index 29e89d675..b0fcd578a 100644 --- a/pages/memgraph-lab/features/custom-configuration.mdx +++ b/pages/memgraph-lab/features/custom-configuration.mdx @@ -9,7 +9,7 @@ import {CommunityLinks} from '/components/social-card/CommunityLinks' # Custom configuration Lab offers a way to customize certain behaviors of the application through a -**configuration file**. +**configuration file**. This functionality is only available when Lab is running inside a Docker container with the environment variable `CONFIG_URI` set. @@ -28,15 +28,20 @@ You can currently configure the following segments: 2. [Sidebar navigation](#sidebar): - Hide specific tabs in the sidebar, such as **Streams**, **Datasets**, **Import**, **Export**, etc. -3. [Predefined datasets](#predefined-datasets): +3. [Predefined datasets](#predefined-datasets): - Hide selected predefined datasets from the **Datasets** section. - Mark a predefined dataset as **Featured**, which makes it more prominent in the UI. 4. [Graph node actions](#graph-node-actions): - - Hide default node actions: **Expand**, **Collapse**, **Hide**. + - Hide default node actions: **Expand edges**, **Collapse edges**, **Hide node**. - Add new custom graph node actions by defining a CYPHER query (**Enterprise feature**). -5. [GSS Overrides](#system-default-gss-enterprise) (**Enterprise feature**) +5. [Graph relationship actions](#graph-relationship-actions): + - Hide default relationship actions: **Expand parallel edges**, **Collapse parallel edges**, + **Hide edge**. + - Add new custom graph relationship actions by defining a CYPHER query (**Enterprise + feature**). +6. [GSS Overrides](#system-default-gss-enterprise) (**Enterprise feature**) - Override system default **GSS styles** and customize per theme if needed. @@ -45,7 +50,7 @@ You can currently configure the following segments: The configuration file must be written in YAML format. There are two supported methods for supplying the file to Lab: -{

File protocol

} +{

File protocol

} You can mount a configuration file inside the Lab Docker container and reference it using the environment variable `CONFIG_URI`. Example: @@ -71,7 +76,7 @@ docker run \ ```
-{

HTTP(S) protocol

} +{

HTTP(S) protocol

} If the configuration file is hosted externally and the Lab container can access it via HTTP or HTTPS, you can provide the URI like so: @@ -178,7 +183,7 @@ However, you can lock specific settings to prevent users from changing them. To lock a setting, simply add `isLocked: true` to the relevant parameter. By default, all settings are unlocked. -{

Complete settings configuration example

} +{

Complete settings configuration example

} Here is a complete example of the settings configuration: @@ -215,7 +220,7 @@ settings: value: true ``` -{

Partial settings configuration example

} +{

Partial settings configuration example

} You don’t need to define every parameter—only specify the ones you wish to change or override. For example: @@ -251,7 +256,7 @@ features: isHidden: true ``` -{

Complete list of features you can hide

} +{

Complete list of features you can hide

} Below is a complete list of features that you can hide from the sidebar: @@ -290,7 +295,7 @@ features: Lab includes 36 predefined datasets by default. Using the configuration file, you can customize how these datasets appear in the UI: -{

Hiding datasets

} +{

Hiding datasets

} You can hide any predefined dataset by referencing its unique ID in the configuration file. @@ -387,7 +392,7 @@ features: isHidden: true ``` -{

Featuring datasets

} +{

Featuring datasets

} You can also change whether a predefined dataset is featured on the datasets page. Featured datasets are given more visibility and space in the UI. @@ -421,13 +426,14 @@ features: In Lab's graph view, when you click on a node, a sidebar appears with available node actions. By default, the following actions are provided: -- **Expand**: Fetches relationships and neighboring nodes from the selected node + +- **Expand edges**: Fetches relationships and neighboring nodes from the selected node and adds them to the graph view. -- **Collapse**: Hides relationships and nodes that are only connected to the +- **Collapse edges**: Hides relationships and nodes that are only connected to the selected node. -- **Hide**: Hides the selected node from the graph view. +- **Hide node**: Hides the selected node from the graph view. -{

Hiding default actions

} +{

Hiding default actions

} You can hide any of these default actions using the configuration file. Each action is referenced by its ID. For example, to hide all three default actions: @@ -443,7 +449,7 @@ action is referenced by its ID. For example, to hide all three default actions: isHidden: true ``` -To hide only the "Hide" action: +To hide only the "Hide node" action: ```yaml - name: graph.nodes.system.configure @@ -452,7 +458,7 @@ To hide only the "Hide" action: isHidden: true ``` -{

Adding custom node actions (Enterprise)

} +{

Adding custom node actions (Enterprise)

} You can also define custom node actions that appear in the sidebar when a node is selected in the graph view. This feature requires an Enterprise license. @@ -487,9 +493,98 @@ Here’s an example of two custom actions: ``` You can use the following parameters in your Cypher queries: + - `$selectedNodeId` — The ID of the node that was clicked. -- `$nodeIds` — A list of IDs of all nodes currently in the graph - view (including hidden ones). +- `$nodeIds` — A list of IDs of all nodes currently visible in + the graph view. +- `$edgeIds` — A list of IDs of all relationships currently + visible in the graph view. + +Each action must have a `label` field, which will be displayed +on the UI button. + + +**Important**: Lab does not validate Cypher queries during configuration +loading. Ensure your query is valid and returns the correct data structures +(nodes, relationships, and/or paths). + + + +This feature requires an Enterprise license. + + +### Graph relationship actions + +In Lab's graph view, when you click on a relationship, a sidebar appears with available +relationship actions. By default, the following actions are provided: + +- **Expand parallel edges**: Fetches relationships that share the same starting and ending + nodes as the selected relationship and adds them to the graph view. +- **Collapse parallel edges**: Hides relationships that share the same starting and ending + nodes as the selected relationship. +- **Hide edge**: Hides the selected relationship from the graph view. + +{

Hiding default actions

} + +You can hide any of these default actions using the configuration file. Each +action is referenced by its ID. For example, to hide all three default actions: + +```yaml +- name: graph.edges.system.configure + items: + - id: expand + isHidden: true + - id: collapse + isHidden: true + - id: hide + isHidden: true +``` + +To hide only the "Hide edge" action: + +```yaml +- name: graph.edges.system.configure + items: + - id: hide + isHidden: true +``` + +{

Adding custom relationship actions (Enterprise)

} + +You can also define custom relationship actions that appear in the sidebar when a +relationship is selected in the graph view. This feature requires an Enterprise license. + +Each custom action executes a Cypher query and should return nodes, +relationships, and/or paths - only these types of objects can be added to the +graph view. + +Here’s an example of a custom actions: + +- `Expand nodes` - Fetches nodes and relationships connected to the start and end + nodes of the selected relationship. + +```yaml +- name: graph.edges.user.configure + items: + - label: Expand nodes + query: + code: + value: | + MATCH (n)-[e]-(m) + WHERE id(e) = $selectedEdgeId + WITH id(n) as start, id(m) as end + MATCH (n)-[r]-(m) + WHERE id(n) = start OR id(m) = end + RETURN n, r, m; +``` + +You can use the following parameters in your Cypher queries: + +- `$selectedEdgeId` — The ID of the relationship that was clicked. +- `$nodeIds` — A list of IDs of all nodes currently visible in + the graph view. +- `$edgeIds` — A list of IDs of all relationships currently + visible in the graph view. Each action must have a `label` field, which will be displayed on the UI button. @@ -525,7 +620,7 @@ case. This feature requires an Enterprise license. -{

General override example

} +{

General override example

} To override the system default GSS for all themes: @@ -551,7 +646,7 @@ features: ``` -{

Theme-specific GSS override

} +{

Theme-specific GSS override

} To apply different GSS for light and dark themes, use the `theme` field with values `light` or `dark`: @@ -789,6 +884,15 @@ features: - id: hide isHidden: false +- name: graph.edges.system.configure + items: + - id: expand + isHidden: false + - id: collapse + isHidden: false + - id: hide + isHidden: false + # Enterprise feature - name: graph.nodes.user.configure items: @@ -807,6 +911,20 @@ features: WHERE id(n) = $selectedNodeId RETURN p; +# Enterprise feature +- name: graph.edges.user.configure + items: + - label: Expand nodes + query: + code: + value: | + MATCH (n)-[e]-(m) + WHERE id(e) = $selectedEdgeId + WITH id(n) as start, id(m) as end + MATCH (n)-[r]-(m) + WHERE id(n) = start OR id(m) = end + RETURN n, r, m; + # Enterprise feature - name: gss.system.configure items: diff --git a/pages/memgraph-lab/features/graphchat.mdx b/pages/memgraph-lab/features/graphchat.mdx index 78c137395..012c4e220 100644 --- a/pages/memgraph-lab/features/graphchat.mdx +++ b/pages/memgraph-lab/features/graphchat.mdx @@ -1,6 +1,6 @@ --- title: GraphChat -description: GraphChat is a feature within Memgraph Lab that allows users to query the Memgraph database using the English language instead of Cypher queries. +description: GraphChat is a feature within Memgraph Lab that allows users to query the Memgraph database using natural language instead of Cypher queries. --- import { Callout } from 'nextra/components' @@ -12,10 +12,9 @@ import {CommunityLinks} from '/components/social-card/CommunityLinks' designed to transform how users interact with graph databases. It is designed for non-technical users while still catering to advanced developers. -By using Large Language Models (LLMs), such as OpenAI’s GPT-4, it picks one of +By using Large Language Models (LLMs), such as OpenAI's GPT-4, it picks one of the available tools to query your graph, retrieve storage info, and run built-in -algorithms like PageRank, delivering precise and actionable results. - +algorithms like PageRank, delivering precise and actionable results. ![graphchat](/pages/data-visualization/graphchat.png) @@ -39,10 +38,10 @@ inspecting metadata. You can review, adjust, or expand any answer to inspect the LLM's reasoning process and control the prompt context. -From Memgraph 2.16, GraphChat doesn't require MAGE installed. For schema -information, GraphChat uses [`SHOW SCHEMA INFO` -query](/querying/schema#run-time-schema-tracking), if available. If the `SHOW -SCHEMA INFO` query is not enabled it will try using the [schema-related +From Memgraph 2.16, GraphChat doesn't require MAGE to be installed. For schema +information, GraphChat uses the [`SHOW SCHEMA INFO` +query](/querying/schema#run-time-schema-tracking) if available. If the `SHOW +SCHEMA INFO` query is not enabled, it will try using the [schema-related procedures](/querying/schema#schema-related-procedures). If none of the above works, it will run Cypher queries. @@ -51,26 +50,26 @@ works, it will run Cypher queries. Before using GraphChat, you must have data stored in Memgraph and you need to configure at least one LLM connection. Each connection is defined by: -- [**Provider**](#providers) -- **Connection name** -- **Endpoint** -- Optional **custom headers** for authentication -- A [**model configuration**](#model-configuration) to control how the model responds +- [**Provider configuration**](#providers) +- [**Model configuration**](#model-configuration) - controls how the model responds -### Providers +### Providers GraphChat supports connections to the following **providers**: - [Ollama](#ollama) - Requires a locally deployed Ollama model -- [OpenAI](#openai) - Requires a ChatGPT-4 account +- [OpenAI](#openai) - [Azure OpenAI](#azure-openai) - Requires an Azure OpenAI Service account -- DeepSeek - Requires a DeepSeek account +- [DeepSeek](#deepseek) +- [Anthropic](#anthropic) +- [Gemini](#gemini) #### Ollama -For local LLM model setup, you can use Ollama: +For local LLM model setup, you can use Ollama by setting up: -- Provide the local endpoint URL, such as `http://localhost:11434`. +- Local endpoint URL, such as `http://localhost:11434`. +- Optional custom headers with each request. @@ -95,18 +94,53 @@ Memgraph Lab. #### OpenAI -Use OpenAI’s models for processing natural language queries. Set up a connection to OpenAI by providing a valid OpenAI key. +Use OpenAI's models for processing natural language queries. Set up a connection to +OpenAI with: + +- Valid OpenAI API key. +- Optional proxy endpoint. +- Optional custom headers with each request. #### Azure OpenAI -Set up a connection to Azure OpenAI by providing: +Once you have a model deployment created and ready on Azure OpenAI, you can +set up an LLM connection to Azure OpenAI by providing: + +- Azure OpenAI service version. +- Azure OpenAI API key. +- Deployment endpoint. +- Deployment name. +- API mode which can be `Responses` (new API) or `Chat completions` (old API). When you + deploy a model to Azure OpenAI, you can see next to your model if it supports + **Responses** or **Chat completions** API. +- Optional proxy endpoint. +- Optional custom headers with each request. + +![azure-model-selection](/pages/data-visualization/features/graphchat/azure-model-selection.png) + +#### DeepSeek + +Set up a connection to DeepSeek with: -- `azureOpenApiVersion`: Your Azure OpenAI service version. [Find the list of versions here](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#chat-completions). -- `azureOpenApiApiKey`: Your Azure OpenAI API key -- `azureOpenApiInstanceName`: Your Azure OpenAI instance name -- `azureOpenApiDeploymentName`: Your Azure OpenAI deployment name. +- Valid DeepSeek API key. +- Optional proxy endpoint. +- Optional custom headers with each request. -Additional Azure OpenAI integration details can be found in the [Azure OpenAI documentation](https://js.langchain.com/docs/integrations/text_embedding/azure_openai). +#### Anthropic + +Set up a connection to Anthropic models with: + +- Valid Anthropic API key. +- Optional proxy endpoint. +- Optional custom headers with each request. + +#### Gemini + +Set up a connection to Google Gemini models with: + +- Valid Gemini API key. +- Optional proxy endpoint. +- Optional custom headers with each request. ### Model configuration @@ -155,14 +189,14 @@ To adjust this: * Exclude specific exchanges using the **thumbs down** icon. * Update the **max previous exchanges** parameter in the model configuration. - -**Coming soon**: You’ll be able to manually select or deselect specific previous + +**Coming soon**: You'll be able to manually select or deselect specific previous exchanges directly from the conversation view for even more customization. To generate responses, GraphChat leverages [prompt context](#prompt-context) and [built-in tools](#built-in-tools). [Exploring exchanges](#explore-exchanges) -gives you deeper insight into the LLM’s reasoning process. +gives you deeper insight into the LLM's reasoning process. ### Prompt context diff --git a/pages/memgraph-lab/features/multi-tenancy.mdx b/pages/memgraph-lab/features/multi-tenancy.mdx new file mode 100644 index 000000000..920ae1146 --- /dev/null +++ b/pages/memgraph-lab/features/multi-tenancy.mdx @@ -0,0 +1,99 @@ +--- +title: Multi-tenancy +description: A feature that enables switching between different databases or running queries on different databases within the same Lab session. +--- + +import {CommunityLinks} from '/components/social-card/CommunityLinks' +import { Callout } from 'nextra/components' + +# Multi-tenancy Enterprise + +[Multi-tenant support](/database-management/multi-tenancy) 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. + + + +**Enterprise**: To enable the database switch feature, you need to +[enable the Memgraph Enterprise license](/database-management/enabling-memgraph-enterprise). + + + +When multi-tenancy is enabled on Memgraph, you can utilize it in Lab +in several different ways: + +* **Initial connection** - Define the database name you want to connect to +* **Switch databases** - See all available databases and switch between them while + connected to Memgraph +* **Run queries on different databases** which is really handy when you want to + compare results within the same Lab session + +## Initial connection + +When connecting to Memgraph, you can define a database name to which you want to +connect. If you omit the database name, you will be connected to the default +database assigned to your user. + +![lab-multi-tenancy-login](/pages/data-visualization/features/multi-tenancy/lab-multi-tenancy-login.png) + +If multi-tenancy is not configured on the Memgraph side, the database name is not used +when establishing a connection. + +## Switch databases + +When you have multiple databases, you can see all available databases by clicking +on your connection in the upper left corner of the Lab status bar. You can switch +your connection to another database from that view, and any query running from that +point on will be executed on the newly switched database. + +![lab-multi-tenancy-switch](/pages/data-visualization/features/multi-tenancy/lab-multi-tenancy-switch.png) + +## Queries on different databases within the same session + +As seen in the previous section, you can switch databases through the UI, and that +change is applied to the current active connection. + +If you were to use a Cypher command from query execution: + +```cypher +USE DATABASE another_db; +``` + +You would see that nothing happens visually. You are still going to be on the actual database. +When using query execution to switch databases with the `USE DATABASE` Cypher command, Lab +actually does a temporary switch to the named database and then returns back to the one +defined by the connection. + +This can still be handy, especially if you want to compare results from different databases. +For example, let's say we have three databases: `memgraph` (default), `production`, and +`staging`. + +If you were to run the following queries in query execution: + +```cypher +// current database is "memgraph" +MATCH (n) RETURN count(n); // data query 1) runs on database "memgraph" + +USE DATABASE staging; // temporarily switches to database "staging" +MATCH (n) RETURN count(n); // data query 2) runs on database "staging" +CREATE INDEX ON :Node; // data query 3) runs on database "staging" + +USE DATABASE production; // temporarily switches to database "production" +MATCH (n) RETURN count(n); // data query 4) runs on database "production" +MATCH ()-[e]->() RETURN count(e); // data query 5) runs on database "production" + +// switches back to database "memgraph" +``` + +![lab-multi-tenancy-queries](/pages/data-visualization/features/multi-tenancy/lab-multi-tenancy-queries.png) + +It would execute 5 queries on three different databases: + +- First query would return the number of nodes from database "memgraph" +- Second query would return the number of nodes from database "staging" +- Third query would create an index in database "staging" +- Fourth query would return the number of nodes from database "production" +- Fifth query would return the number of relationships from database "production" + + diff --git a/pages/memgraph-lab/features/single-sign-on.mdx b/pages/memgraph-lab/features/single-sign-on.mdx index aa3ed4af6..17cfb6ec6 100644 --- a/pages/memgraph-lab/features/single-sign-on.mdx +++ b/pages/memgraph-lab/features/single-sign-on.mdx @@ -57,7 +57,7 @@ AUTH_OIDC_ENTRA_ID_CLIENT_ID= AUTH_OIDC_ENTRA_ID_CLIENT_SECRET= AUTH_OIDC_ENTRA_ID_CALLBACK_URL=http:///auth/providers/oidc-entra-id/callback AUTH_OIDC_ENTRA_ID_PKCE_IS_ENABLED=true -AUTH_OIDC_ENTRA_ID_SCOPE='$YOUR_CLIENT_ID/.default openid' +AUTH_OIDC_ENTRA_ID_SCOPE='$YOUR_CLIENT_ID/.default openid offline_access' ``` The empty values can be found on the Azure dashboard under the created app registration. @@ -86,7 +86,7 @@ AUTH_OIDC_OKTA_CLIENT_ID= AUTH_OIDC_OKTA_CLIENT_SECRET= AUTH_OIDC_OKTA_CALLBACK_URL=http:///auth/providers/oidc-okta/callback AUTH_OIDC_OKTA_PKCE_IS_ENABLED=true -AUTH_OIDC_OKTA_SCOPE=openid +AUTH_OIDC_OKTA_SCOPE='openid offline_access' ``` The empty values can be found on the Okta admin panel dashboard under the created app. @@ -122,7 +122,7 @@ AUTH_OIDC_CUSTOM_CLIENT_ID= AUTH_OIDC_CUSTOM_CLIENT_SECRET= AUTH_OIDC_CUSTOM_CALLBACK_URL=http:///auth/providers/oidc-custom/callback AUTH_OIDC_CUSTOM_PKCE_IS_ENABLED=true -AUTH_OIDC_CUSTOM_SCOPE=openid +AUTH_OIDC_CUSTOM_SCOPE='openid offline_access' ``` ### PKCE Support in OIDC SSO @@ -150,6 +150,24 @@ it's also possible to omit the client ID when PKCE is enabled. To allow this, configure your Azure Entra ID application to use the "Mobile and Desktop Applications" platform. +### Session expiry in OIDC SSO + +In OIDC, a user's Lab session remains active as long as the current +access token and ID token have not expired. Lab will automatically +refresh the session by using a refresh token to obtain new access +and ID tokens before they expire. + +To receive a refresh token from your identity provider, ensure the +OIDC scope includes `offline_access` for the specific provider: + +- `AUTH_OIDC_ENTRA_ID_SCOPE` +- `AUTH_OIDC_OKTA_SCOPE` +- `AUTH_OIDC_CUSTOM_SCOPE` + +Without `offline_access` in the scope, Lab won't receive a refresh +token and cannot renew tokens, so the user's session will end when +the access/ID tokens expire. + ## SAML You can integrate Single sign-on (SSO) using SAML protocol for diff --git a/pages/memgraph-lab/querying.mdx b/pages/memgraph-lab/querying.mdx index 755d340c5..73f7183de 100644 --- a/pages/memgraph-lab/querying.mdx +++ b/pages/memgraph-lab/querying.mdx @@ -316,17 +316,17 @@ The query summary shows important information involving: the number of hops traversed, the number of nodes and relationships created or delete, the number of labels added or removed, and the number of properties set. - **Query performance breakdown (ms)**: For complex queries, Memgraph Lab -provides an execution plan that breaks down how the query was processed by the -database. This is the visual representation of the execution times from the -Query status bar. Having this kind of query performance breakdown can help users -optimize performance by identifying potential bottlenecks. -- **Server** - Information about the server address and Bolt protocol version - used by the server. + provides an execution plan that breaks down how the query was processed by the + database. This is the visual representation of the execution times from the + Query status bar. Having this kind of query performance breakdown can help users + optimize performance by identifying potential bottlenecks. +- **Server** - Information about the server address, Bolt protocol version + used by the server, and the database name upon which the query was running + (useful in [multi-tenant environments](/memgraph-lab/features/multi-tenancy)). - **Notifications** - If there are potential issues with the query, such as -missing indexes or inefficient query patterns, Memgraph Lab will provide -notifications and recommendations for optimization. For detailed guidelines on -query optimization, read the [querying best -practices](/querying/best-practices). + missing indexes or inefficient query patterns, Memgraph Lab will provide + notifications and recommendations for optimization. For detailed guidelines on + query optimization, read the [querying best practices](/querying/best-practices). - **Query plan and profile** - Analyze how a query is executed by showing detailed information about the [query plan](/querying/query-plan) in a simple diagram. Additionally, profile the query to understand the impact of each diff --git a/pages/release-notes.mdx b/pages/release-notes.mdx index e145daa64..1b29383a0 100644 --- a/pages/release-notes.mdx +++ b/pages/release-notes.mdx @@ -72,6 +72,8 @@ updated. ### Lab v3.5.0 - August 27th, 2025 + + ## Previous releases ### Memgraph v3.4.0 - July 10th, 2025 diff --git a/public/pages/data-visualization/features/graphchat/azure-model-selection.png b/public/pages/data-visualization/features/graphchat/azure-model-selection.png new file mode 100644 index 000000000..24d812eb4 Binary files /dev/null and b/public/pages/data-visualization/features/graphchat/azure-model-selection.png differ diff --git a/public/pages/data-visualization/features/multi-tenancy/lab-multi-tenancy-login.png b/public/pages/data-visualization/features/multi-tenancy/lab-multi-tenancy-login.png new file mode 100644 index 000000000..96506be8b Binary files /dev/null and b/public/pages/data-visualization/features/multi-tenancy/lab-multi-tenancy-login.png differ diff --git a/public/pages/data-visualization/features/multi-tenancy/lab-multi-tenancy-queries.png b/public/pages/data-visualization/features/multi-tenancy/lab-multi-tenancy-queries.png new file mode 100644 index 000000000..15a71b397 Binary files /dev/null and b/public/pages/data-visualization/features/multi-tenancy/lab-multi-tenancy-queries.png differ diff --git a/public/pages/data-visualization/features/multi-tenancy/lab-multi-tenancy-switch.png b/public/pages/data-visualization/features/multi-tenancy/lab-multi-tenancy-switch.png new file mode 100644 index 000000000..33db8c1bc Binary files /dev/null and b/public/pages/data-visualization/features/multi-tenancy/lab-multi-tenancy-switch.png differ