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.

FlagDescription
--auth-module-mappingsAssociates 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-msSpecifies the maximum time that Memgraph will wait for a response from the external auth module.
--auth-password-permit-nullCan be set to false to disable null passwords.
--auth-password-strength-regexThe 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-okta

Built-in authentication schemes

  • basic - username and password authentication via external module
  • saml-entra-id
  • saml-okta
  • oidc-entra-id
  • oidc-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

FieldDescription
usernameUser’s username (for basic scheme)
passwordUser’s password (for basic scheme)
schemeAuthentication method (for SSO schemes, e.g. oidc-entra-id)
responseAuthentication response (e.g. SAML or JWT token)

Auth response structure

FieldTypeDescription
authenticatedboolWhether the user is allowed to connect
rolestringSingle role (backward compatibility)
rolesarray[string]One or more roles (preferred format)
usernamestring (optional)The authenticated username
errorsstring (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:

  1. Use roles if present.
  2. If roles is a list, all listed roles are applied.
  3. If roles is a string, use it as a single role.
  4. If no roles are found, fall back to role.
  5. 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:memuser

Maps:

  • entra.adminmemadmin
  • entra.usermemuser
entra.admin:memadmin; entra.user:memuser, memdev

Maps:

  • entra.usermemuser and memdev

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
VariableDescription
MEMGRAPH_SSO_ENTRA_ID_SAML_CALLBACK_URLMatches AUTH_SAML_ENTRA_ID_CALLBACK_URL used by Memgraph Lab.
MEMGRAPH_SSO_ENTRA_ID_SAML_ASSERTION_AUDIENCEThe application audience; for single-tenant apps, use spn:{tenant id}.
MEMGRAPH_SSO_ENTRA_ID_SAML_IDP_CERTPath to the app’s SAML certificate.
MEMGRAPH_SSO_ENTRA_ID_SAML_IDP_IDSet to https://sts.windows.net/{tenant id}/.
MEMGRAPH_SSO_ENTRA_ID_SAML_ASSERTIONS_ENCRYPTEDtrue if assertions are encrypted.
MEMGRAPH_SSO_ENTRA_ID_SAML_SP_PRIVATE_KEYPath to the private key for decrypting assertions (if used).
MEMGRAPH_SSO_ENTRA_ID_SAML_WANT_ATTRIBUTE_STATEMENTtrue if the SAML response must contain attributes.
MEMGRAPH_SSO_ENTRA_ID_SAML_USE_NAME_IDtrue to use the NameID attribute as the username.
MEMGRAPH_SSO_ENTRA_ID_NAME_ID_ENCRYPTEDtrue if NameID is encrypted.
MEMGRAPH_SSO_ENTRA_ID_SAML_USERNAME_ATTRIBUTEName of the SAML response attribute containing the username (if not using NameID).
MEMGRAPH_SSO_ENTRA_ID_SAML_ROLE_MAPPINGThe role mapping string.
Okta
VariableDescription
MEMGRAPH_SSO_OKTA_SAML_CALLBACK_URLMatches AUTH_SAML_OKTA_CALLBACK_URL used by Memgraph Lab.
MEMGRAPH_SSO_OKTA_SAML_ASSERTION_AUDIENCEThe application audience.
MEMGRAPH_SSO_OKTA_ID_SAML_IDP_CERTPath to the app’s SAML certificate.
MEMGRAPH_SSO_OKTA_SAML_IDP_IDThe Okta issuer URL.
MEMGRAPH_SSO_OKTA_SAML_ASSERTIONS_ENCRYPTEDtrue if assertions are encrypted.
MEMGRAPH_SSO_OKTA_SAML_SP_PRIVATE_KEYPath to the private key for decrypting assertions (if used).
MEMGRAPH_SSO_OKTA_SAML_WANT_ATTRIBUTE_STATEMENTtrue if the SAML response must contain attributes.
MEMGRAPH_SSO_OKTA_SAML_USE_NAME_IDtrue to use the NameID attribute as the username.
MEMGRAPH_SSO_OKTA_NAME_ID_ENCRYPTEDtrue if the NameID element is encrypted.
MEMGRAPH_SSO_OKTA_SAML_USERNAME_ATTRIBUTEName of the SAML response attribute containing the username (if not using NameID).
MEMGRAPH_SSO_OKTA_SAML_ROLE_ATTRIBUTEName of the SAML response attribute containing the user’s role(s).
MEMGRAPH_SSO_OKTA_SAML_ROLE_MAPPINGThe 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-id

For 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.txt

Note: Ensure the JWT Python package is not installed, as it conflicts with PyJWT. Run pip freeze to 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:field
  • token-type: either id or access
  • field: 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_token and id_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-okta or custom)
  • Credentials: Provide them as a string in this format: access_token=token-data;id_token=token-data If 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:field

By default: id:sub

  • id → Use a field from the ID token
  • access → 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-module

depending 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 + suffix

In most cases:

  • prefix = cn=
  • suffix = ,dc=example,dc=com

For example, if the username is alice, the DN becomes:

cn=alice,dc=example,dc=com

This 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.yaml

An example configuration file with all settings documented is provided at:

/etc/memgraph/auth_module/ldap.example.yaml

For 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=basic

You 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: top

To 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 - user dba that will be used as the database administrator.
    • cn=alice,ou=people,dc=memgraph,dc=com - regular user alice.
    • cn=carol,ou=people,dc=memgraph,dc=com - regular user carol.
    • cn=dave,ou=people,dc=memgraph,dc=com - regular user dave.
  • ou=roles,dc=memgraph,dc=com - entry that holds all roles.
    • cn=moderator,ou=roles,dc=memgraph,dc=com - role moderator that has alice as its member.
    • cn=admin,ou=roles,dc=memgraph,dc=com - role admin that has carol and dave as 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=basic

Also, 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 groupOfNames as its object class
  • User DNs are specified in the member attribute
  • Role names are taken from the cn attribute

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=com
  • cn=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:

  • alice can log in because the moderator role exists.
  • carol and dave cannot log in until the admin role is created.