Auth system integrations Enterprise
Memgraph supports authentication and authorization using external auth modules. It includes built-in support for basic (username and password) authentication via LDAP, as well as single sign-on over the SAML and OIDC protocols.
When a user connects, Memgraph forwards the supplied credentials (username and password, or an auth scheme and response) to the external module. The module returns an authentication verdict and based on that, Memgraph either allows or denies access.
Note: As this is an Enterprise feature, once the Memgraph Enterprise license expires, newly created users will be granted all privileges. The existing users’ privileges will still apply but you won’t be able to manage them further.
Configuration
Roles
Before using any external authentication module, you must define the corresponding roles in Memgraph. External modules return the role or roles associated with a user and Memgraph matches these to existing roles.
As of v3.5, Memgraph supports assigning multiple roles per user, meaning an external auth module can return a single role or a list of roles.
Configuration flags
Use the following configuration flags to configure the external auth module authentication and authorization mechanisms used by Memgraph.
| Flag | Description |
|---|---|
--auth-module-mappings | Associates auth schemes to external modules. A mapping is structured as follows: <scheme>:<absolute path to module> and individual entries are separated with ;. If the mapping contains whitespace, enclose the flag value with quotation marks. |
--auth-module-executable | [DEPRECATED] Path to the executable that should be used for user authentication/authorization. Replaced by --auth-module-mappings=basic from Memgraph 2.18. |
--auth-module-timeout-ms | Specifies the maximum time that Memgraph will wait for a response from the external auth module. |
--auth-password-permit-null | Can be set to false to disable null passwords. |
--auth-password-strength-regex | The regular expression that should be used to match the entire entered password to ensure its strength. |
Auth schemes that have built-in Memgraph support have default module paths. To enable them, you only need to list the auth schemes themselves, e.g.
--auth-module-mappings=basic;saml-entra-id;oidc-oktaBuilt-in authentication schemes
basic- username and password authentication via external modulesaml-entra-idsaml-oktaoidc-entra-idoidc-okta
Environment variables
The built-in SSO modules (used with the saml-entra-id, saml-okta,
oidc-entra-id, and oidc-okta auth schemes) are further configured using
environment variables. See their respective sections below for more details.
Auth module architecture
Communication protocol
Memgraph communicates with external auth modules through inter-process pipes:
- Input (from Memgraph): file descriptor
1000 - Output (to Memgraph): file descriptor
1001
The standard streams (stdin and stdout) aren’t used because external
libraries often tend to write something to stdout which is difficult to
disable. By using separate file descriptors, stdout is left intact and can be
used freely for debugging purposes (along with stderr).
Protocol format
Each request and response is a single-line JSON object terminated by \n.
Auth request structure
| Field | Description |
|---|---|
username | User’s username (for basic scheme) |
password | User’s password (for basic scheme) |
scheme | Authentication method (for SSO schemes, e.g. oidc-entra-id) |
response | Authentication response (e.g. SAML or JWT token) |
Auth response structure
| Field | Type | Description |
|---|---|---|
authenticated | bool | Whether the user is allowed to connect |
role | string | Single role (backward compatibility) |
roles | array[string] | One or more roles (preferred format) |
username | string (optional) | The authenticated username |
errors | string (optional) | Error message in case authentication fails |
If the external module crashes during processing, Memgraph denies login and
automatically restarts the module for the next request. Crash logs are available
in Memgraph’s system logs (for example, via journalctl when running under
systemd).
Multiple roles support
As of v3.5 Memgraph supports multiple roles per user in auth module responses. Auth modules can return either a single role (backward compatible) or multiple roles (new format).
Single role
def authenticate(username, password):
return {
"authenticated": True,
"role": "moderator" # Single role as string
}Multiple roles
def authenticate(username, password):
return {
"authenticated": True,
"roles": ["admin", "user"] # Multiple roles as array
}Single role in array format
def authenticate(username, password):
return {
"authenticated": True,
"roles": ["admin"] # Single role in array
}Memgraph processes roles as follows:
- Use
rolesif present. - If
rolesis a list, all listed roles are applied. - If
rolesis a string, use it as a single role. - If no
rolesare found, fall back torole. - If no valid roles exist, authentication fails.
When a user has multiple roles, their permissions are combined using the following rules:
- Grants: If any role grants a permission, the user has that permission
- Denies: If any role denies a permission, the user is denied that permission
- Database access: If any role grants and no role denies access to a database, the user has access
- Fine-grained permissions: Combined using the same grant/deny logic
Module example
This very simple example auth module is written in Python, but any programming language can be used.
#!/usr/bin/python3
import json
import io
def authenticate(username, password):
# Example with multiple roles
if username == "admin_user" and password == "password":
return {"authenticated": True, "roles": ["admin", "user"]}
# Example with single role (backward compatible)
if username == "moderator_user" and password == "password":
return {"authenticated": True, "role": "moderator"}
return {"authenticated": False, "errors": "Invalid credentials"}
if __name__ == "__main__":
input_stream = io.FileIO(1000, mode="r")
output_stream = io.FileIO(1001, mode="w")
while True:
params = json.loads(input_stream.readline().decode("ascii"))
ret = authenticate(**params)
output_stream.write((json.dumps(ret) + "\n").encode("ascii"))In the example you can see how the communication protocol works and you can see
the function that is used for authentication (and authorization). When writing
your own modules, you have to reimplement the authenticate function according
to your needs.
Because the authentication (and authorization) function has a simple signature, it is easy (and recommended) to write unit (or integration) tests in separate files. For example:
#!/usr/bin/python3
import module
assert module.authenticate("admin_user", "password") == {"authenticated": True, "roles": ["admin", "user"]}
assert module.authenticate("moderator_user", "password") == {"authenticated": True, "role": "moderator"}Single sign-on
Single sign-on (SSO) lets you use an external ID to log in to Memgraph from Lab.
Memgraph provides built-in SSO modules that let you customize which identity
service fields define the username and roles of authenticated users.
Username configuration is provider- and protocol-specific, while role
configuration works universally through role mapping.
Role mapping
Use the MEMGRAPH_SSO_{provider}_{protocol}_ROLE_MAPPING environment variable
to define how identity service roles map to Memgraph roles.
Mappings follow this format:
{identity_service_role}:{Memgraph_role}, {another_Memgraph_role}; {next_mapping}Each mapping pair is separated with a semicolon ;.
One identity service role can map to one or multiple Memgraph roles.
Example mappings
entra.admin:memadmin; entra.user:memuserMaps:
entra.admin→memadminentra.user→memuser
entra.admin:memadmin; entra.user:memuser, memdevMaps:
entra.user→memuserandmemdev
When a user logs in and is assigned an identity service role that is mapped to an array of Memgraph roles, the user is assigned all of the mapped Memgraph roles.
For more information regarding how multi-role users are handled by Memgraph, please visit Multi-role users and multi-tenant roles.
Different services use different parameters for defining roles. Use
MEMGRAPH_SSO_{provider}_{protocol}_ROLE_FILED to specify the token parameter
that specifies the assigned roles.
For correct operation, the Memgraph roles defined in the mapping need to be created in the Memgraph DB beforehand. Additionally, you have to grant label-based permissions to the roles used in SSO.
SSO identity providers often return multiple roles for users. Memgraph now supports this natively - if your identity provider returns multiple roles, they will all be mapped to Memgraph roles and the user will have permissions from all assigned roles combined.
SAML
Memgraph supports SAML-based SSO with the following identity providers:
- Microsoft Entra ID
- Okta
Configuration
To enable SAML SSO using the built-in auth modules, set the
--auth-module-mappings with the saml-entra-id or saml-okta schemes, e.g.
--auth-module-mappings=saml-entra-id;saml-okta (or just one of them).
Environment variables
The following environment variables are used to configure the built-in SAML module:
Microsoft Entra ID
| Variable | Description |
|---|---|
MEMGRAPH_SSO_ENTRA_ID_SAML_CALLBACK_URL | Matches AUTH_SAML_ENTRA_ID_CALLBACK_URL used by Memgraph Lab. |
MEMGRAPH_SSO_ENTRA_ID_SAML_ASSERTION_AUDIENCE | The application audience; for single-tenant apps, use spn:{tenant id}. |
MEMGRAPH_SSO_ENTRA_ID_SAML_IDP_CERT | Path to the app’s SAML certificate. |
MEMGRAPH_SSO_ENTRA_ID_SAML_IDP_ID | Set to https://sts.windows.net/{tenant id}/. |
MEMGRAPH_SSO_ENTRA_ID_SAML_ASSERTIONS_ENCRYPTED | true if assertions are encrypted. |
MEMGRAPH_SSO_ENTRA_ID_SAML_SP_PRIVATE_KEY | Path to the private key for decrypting assertions (if used). |
MEMGRAPH_SSO_ENTRA_ID_SAML_WANT_ATTRIBUTE_STATEMENT | true if the SAML response must contain attributes. |
MEMGRAPH_SSO_ENTRA_ID_SAML_USE_NAME_ID | true to use the NameID attribute as the username. |
MEMGRAPH_SSO_ENTRA_ID_NAME_ID_ENCRYPTED | true if NameID is encrypted. |
MEMGRAPH_SSO_ENTRA_ID_SAML_USERNAME_ATTRIBUTE | Name of the SAML response attribute containing the username (if not using NameID). |
MEMGRAPH_SSO_ENTRA_ID_SAML_ROLE_MAPPING | The role mapping string. |
Okta
| Variable | Description |
|---|---|
MEMGRAPH_SSO_OKTA_SAML_CALLBACK_URL | Matches AUTH_SAML_OKTA_CALLBACK_URL used by Memgraph Lab. |
MEMGRAPH_SSO_OKTA_SAML_ASSERTION_AUDIENCE | The application audience. |
MEMGRAPH_SSO_OKTA_ID_SAML_IDP_CERT | Path to the app’s SAML certificate. |
MEMGRAPH_SSO_OKTA_SAML_IDP_ID | The Okta issuer URL. |
MEMGRAPH_SSO_OKTA_SAML_ASSERTIONS_ENCRYPTED | true if assertions are encrypted. |
MEMGRAPH_SSO_OKTA_SAML_SP_PRIVATE_KEY | Path to the private key for decrypting assertions (if used). |
MEMGRAPH_SSO_OKTA_SAML_WANT_ATTRIBUTE_STATEMENT | true if the SAML response must contain attributes. |
MEMGRAPH_SSO_OKTA_SAML_USE_NAME_ID | true to use the NameID attribute as the username. |
MEMGRAPH_SSO_OKTA_NAME_ID_ENCRYPTED | true if the NameID element is encrypted. |
MEMGRAPH_SSO_OKTA_SAML_USERNAME_ATTRIBUTE | Name of the SAML response attribute containing the username (if not using NameID). |
MEMGRAPH_SSO_OKTA_SAML_ROLE_ATTRIBUTE | Name of the SAML response attribute containing the user’s role(s). |
MEMGRAPH_SSO_OKTA_SAML_ROLE_MAPPING | The role mapping string. |
OpenID Connect
Memgraph supports authentication and authorization using OpenID Connect (OIDC) with OAuth 2.0 via built-in modules packaged with Memgraph Enterprise.
Supported identity providers
- Microsoft Entra ID
- Okta (custom authorization server)
Enabling OIDC
Use the --auth-module-mappings flag to enable OIDC providers:
--auth-module-mappings=oidc-okta;oidc-entra-idFor full SSO setup instructions, see this guide.
Module requirements
The module is written in Python 3 and requires the following libraries:
PyJWT- used to validate tokens.requests- used to retrieve public keys for validating tokens.cryptography- used to parse tokens.
These dependencies are preinstalled in the Memgraph Docker image.
The required packages are already installed in the docker image. If you are
using a native build you to install the packages manually on your machine. The
list of all required packages is located at
src/auth/reference_modules/requirements.txt.
To install, run:
pip3 install -r /path/to/memgraph/src/auth/reference_modules/requirements.txtNote: Ensure the
JWTPython package is not installed, as it conflicts withPyJWT. Runpip freezeto verify.
Module configuration
The module is located at /usr/lib/memgraph/auth_module/oidc.py.
This module has no configuration file and is fully configured via environment variables. You can use multiple SSO providers by setting variables for each one.
MS Entra ID
For using OIDC with Microsoft Entra ID you have to set the following environmental variables:
MEMGRAPH_SSO_ENTRA_ID_OIDC_TENANT_ID=
MEMGRAPH_SSO_ENTRA_ID_OIDC_CLIENT_ID=
MEMGRAPH_SSO_ENTRA_ID_OIDC_ROLE_MAPPING=
MEMGRAPH_SSO_ENTRA_ID_OIDC_USERNAME=- Tenant ID and client ID are available in your Azure app overview.
- See the SSO setup guide for details.
Role mapping uses the same syntax described in Role mapping.
The MEMGRAPH_SSO_ENTRA_ID_OIDC_USERNAME variable defines which token claim to
use as the username:
token-type:fieldtoken-type: eitheridoraccessfield: the token claim (e.g.,sub,preferred_username)
By default, it is set to id:sub as per the OIDC protocol it is
recommended to use the sub field from the id token as it is non-mutable and
globally unique for each application. For MS Entra ID one commonly used field is
access:preferred_username which is usually the email of the user.
For claim references, see:
Okta
For using OIDC with Okta you have to set the following environmental variables:
MEMGRAPH_SSO_OKTA_OIDC_ISSUER=
MEMGRAPH_SSO_OKTA_OIDC_CLIENT_ID=
MEMGRAPH_SSO_OKTA_OIDC_AUTHORIZATION_SERVER=api://default
MEMGRAPH_SSO_OKTA_OIDC_ROLE_MAPPING=
MEMGRAPH_SSO_OKTA_OIDC_USERNAME=Role mapping uses the same syntax described in Role mapping.
Issuer is https://{your-okta-domain}.okta.com/oauth2/default/. You can find
the client ID on the Admin panel -> Applications -> General. You can find the
authorization server on the Admin panel -> Security -> API -> Authorization
Servers -> Audience. By default, it is set to api://default.
Custom OIDC provider
This is currently only supported through the Neo4j drivers.
If you are using an OIDC provider which is not listed above you can use you the custom auth scheme. The only requirement is that your OIDC provider supports verifying the tokens through RSA algorithm (public & private key).
Setup the following environmental variables:
MEMGRAPH_SSO_CUSTOM_OIDC_PUBLIC_KEY_ENDPOINT=`URI where the public key for validating the tokens is exposed`
MEMGRAPH_SSO_CUSTOM_OIDC_ACCESS_TOKEN_AUDIENCE=`access token audience`
MEMGRAPH_SSO_CUSTOM_OIDC_ID_TOKEN_AUDIENCE=`id token audience`
MEMGRAPH_SSO_CUSTOM_OIDC_ROLE_FIELD=`access token field to be used in the role mapping`
MEMGRAPH_SSO_CUSTOM_OIDC_USERNAME=
MEMGRAPH_SSO_CUSTOM_OIDC_ROLE_MAPPING=Usernames are described below and role mappings are described in Role mapping.
You can determine token audiences by decoding tokens via tools like jwt.io and
inspecting the aud field. In many cases, both tokens use the same audience
(for example, Entra ID uses the client ID).
Connect via Neo4j drivers
When connecting through a Neo4j driver, you can provide:
- Both
access_tokenandid_token, or - Only the
access_token(if username uses an access token claim)
In general, all connection methods follow the same approach: setting only the scheme and credentials.
- Scheme: Use the scheme that applies to your setup (
oidc-entra-id,oidc-oktaorcustom) - Credentials: Provide them as a string in this format:
access_token=token-data;id_token=token-dataIf you don’t want to include the ID token, simply omit it:access_token=token-data
The OIDC module automatically determines whether to
validate the ID token based on your username configuration. If your username is
configured to use a field from the ID token (e.g., id:sub), the module will
require and validate the ID token. If your username uses a field from the access
token (e.g., access:preferred_username), the ID token validation is skipped.
Below is an example of connecting via the Neo4j Python driver.
from neo4j import GraphDatabase, Auth
driver = GraphDatabase.driver(MEMGRAPH_URI,
auth = Auth(
scheme="oidc-entra-id",
credentials=`access_token=token-data;id_token=token-data`,
realm=None,
principal=None
)
)Username configuration
The username variable tells the OIDC module what to use as the username in the following format:
token-type:fieldBy default: id:sub
id→ Use a field from the ID tokenaccess→ Use a field from the Access token
Token type can be id or access depending on
whether you want to use a field from the access or the ID token for the
username. See the following to learn more about
access and
id
tokens.
By default, it is set to id:sub as per the OIDC protocol it is recommended to
use the sub field from the id token as it is non-mutable and globally unique
for each application. For Okta one commonly used field is access:sub which is
usually the email of the user. You can also configure custom
claims.
Database configuration
OIDC is by default enabled using the Memgraph oidc.py module.
To use a custom auth module use the --auth-module-mappings
flag like the following:
--auth-module-mappings=oidc-entra-id:/path/to/oidc-entra-module;oidc-okta:/path/to/oidc-okta-moduledepending on the SSO provider you want to use.
Using OIDC SSO with the Neo4j Python driver
Connecting using SSO is supported with the Neo4j Python driver. For the instructions on how to connect, check the Python driver docs.
Basic authentication
When Memgraph is set up to use the external auth module for basic (username
- password) authentication (
--auth-module-mappings=basic), its internal users management is automatically disabled. Users are authenticated only using the module and existing local users are ignored.
LDAP authentication
Memgraph Enterprise includes a built-in LDAP authentication and authorization module. This module supports both authentication (LDAP bind) and authorization (LDAP search).
Mode of operation
When using LDAP, the module constructs a Distinguished Name (DN) for authentication based on the username and the following formula:
DN = prefix + username + suffixIn most cases:
prefix=cn=suffix=,dc=example,dc=com
For example, if the username is alice, the DN becomes:
cn=alice,dc=example,dc=comThis DN is used to perform the LDAP bind operation with the provided password.
After authentication, the module searches the role mapping tree to determine the
user’s role. Each role mapping object associates users (via the member
attribute) with roles (via the cn attribute). These attribute names and the
root DN can be customized in the module’s configuration file to match your LDAP
schema.
Note: In large directories with thousands of roles, the search process can take time, leading to longer login durations.
Module requirements
The module is written in Python 3 and it must be installed on the server. The
Python version should be at least 3.5. Also, you must have the following
Python 3 libraries installed:
ldap3- used to communicate with the LDAP server.PyYAML- used to parse the configuration file.
Module configuration
The module configuration file is located at:
/etc/memgraph/auth_module/ldap.yamlAn example configuration file with all settings documented is provided at:
/etc/memgraph/auth_module/ldap.example.yamlFor quick setup, you can copy the example configuration file into the module configuration file.
Database configuration
To enable LDAP authentication and authorization, start Memgraph with:
--auth-module-mappings=basicYou can also combine this with other configuration flags listed in Configuration flags as needed.
Example LDAP directory
Organizations typically use an LDAP server to hold and manage the permissions. Because LDAP servers are already set-up in most large organizations, it is convenient for the organization to allow all staff members to have access to the database using the already available centralized user management system.
For this guide let’s assume that we have an LDAP server that is serving the following data:
# Users root entry
dn: ou=people,dc=memgraph,dc=com
objectclass: organizationalUnit
objectclass: top
ou: people
# User dba
dn: cn=dba,ou=people,dc=memgraph,dc=com
cn: dba
objectclass: person
objectclass: top
sn: user
userpassword: dba
# User alice
dn: cn=alice,ou=people,dc=memgraph,dc=com
cn: alice
objectclass: person
objectclass: top
sn: user
userpassword: alice
# User carol
dn: cn=carol,ou=people,dc=memgraph,dc=com
cn: carol
objectclass: person
objectclass: top
sn: user
userpassword: carol
# User dave
dn: cn=dave,ou=people,dc=memgraph,dc=com
cn: dave
objectclass: person
objectclass: top
sn: user
userpassword: dave
# Roles root entry
dn: ou=roles,dc=memgraph,dc=com
objectclass: organizationalUnit
objectclass: top
ou: roles
# Role superuser
dn: cn=superuser,ou=roles,dc=memgraph,dc=com
cn: superuser
member: cn=dba,ou=people,dc=memgraph,dc=com
objectclass: groupOfNames
objectclass: top
# Role moderator
dn: cn=moderator,ou=roles,dc=memgraph,dc=com
cn: moderator
member: cn=alice,ou=people,dc=memgraph,dc=com
objectclass: groupOfNames
objectclass: top
# Role admin
dn: cn=admin,ou=roles,dc=memgraph,dc=com
cn: admin
member: cn=carol,ou=people,dc=memgraph,dc=com
member: cn=dave,ou=people,dc=memgraph,dc=com
objectclass: groupOfNames
objectclass: topTo summarize, the dataset contains the following data:
ou=people,dc=memgraph,dc=com- entry that holds all users.cn=dba,ou=people,dc=memgraph,dc=com- userdbathat will be used as the database administrator.cn=alice,ou=people,dc=memgraph,dc=com- regular useralice.cn=carol,ou=people,dc=memgraph,dc=com- regular usercarol.cn=dave,ou=people,dc=memgraph,dc=com- regular userdave.
ou=roles,dc=memgraph,dc=com- entry that holds all roles.cn=moderator,ou=roles,dc=memgraph,dc=com- rolemoderatorthat hasaliceas its member.cn=admin,ou=roles,dc=memgraph,dc=com- roleadminthat hascarolanddaveas its members.
Authentication workflow
Run Memgraph
Start Memgraph without local users in its authentication storage. See Getting started for running Memgraph, and refer to User privileges to understand how native authentication works.
Create an administrator
When using the external LDAP module, all users are handled by the auth module and no user information is stored locally in Memgraph. In order to allow user login, the corresponding roles need to be defined locally.
CREATE ROLE superuser;
GRANT ALL PRIVILEGES TO superuser;Once the role has been created and all privileges granted, it’s safe to disconnect from the database and proceed with the LDAP integration.
Enable LDAP integration
To enable LDAP integration specify the following flag:
--auth-module-mappings=basicAlso, add the following LDAP module configuration to
/etc/memgraph/auth_module/ldap.yaml:
server:
host: "<LDAP_SERVER_HOSTNAME>"
port: <LDAP_SERVER_PORT>
encryption: "disabled"
cert_file: ""
key_file: ""
ca_file: ""
validate_cert: false
users:
prefix: "cn="
suffix: ",ou=people,dc=memgraph,dc=com"
roles:
root_dn: ""
root_objectclass: ""
user_attribute: ""
role_attribute: ""Adjust the security settings according to your LDAP server security settings.
Once all the configuration options are set, restart the Memgraph database instance.
Verify the integration
Verify that you can log into the database using the username dba and password
dba. It will confirm that the LDAP authentication is successfully enabled.
Log in with other users
User alice should be able to log in with password alice.
The administrator dba should modify Alice’s role’s privileges to include the
MATCH privilege using the following query:
GRANT MATCH TO moderator;Once Alice logs in the second time, she should be able to execute the following query:
MATCH (n) RETURN n;If the dba runs the SHOW USERS; query, it won’t return any users, since all
users are managed by the auth module.
Users Bob, Carol and Dave will also be able to log in to the database using their LDAP password.
Authorization and role mapping
Enable role mapping
To enable role mapping for the described LDAP schema, modify the LDAP auth
module configuration file, specifically the section roles, by adding the
following content:
roles:
root_dn: "ou=roles,dc=memgraph,dc=com"
root_objectclass: "groupOfNames"
user_attribute: "member"
role_attribute: "cn"This configuration tells the LDAP module that:
- All role entries are located under
ou=roles,dc=memgraph,dc=com - Each entry uses
groupOfNamesas its object class - User DNs are specified in the
memberattribute - Role names are taken from the
cnattribute
When a user logs in to the database, the LDAP auth module will go through all
role mapping entries and will try to find out which role mapping entry has the
user as its member.
For example, when alice logs in, the module checks:
cn=admin,ou=roles,dc=memgraph,dc=comcn=moderator,ou=roles,dc=memgraph,dc=com
Since alice is listed as a member of the moderator entry, she receives the
moderator role in Memgraph.
Adjust permissions
Although authentication and role mapping are handled by LDAP, permissions are still managed directly in Memgraph.
The database administrator (user dba) now has to explicitly create the role
the users have so they will be able to log into the database:
CREATE ROLE moderator;In this setup:
alicecan log in because themoderatorrole exists.carolanddavecannot log in until theadminrole is created.