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 is connecting, Memgraph will forward the user’s supplied credentials (username and password, or scheme and auth response) to the external auth module and retrieve its verdict. Based on this verdict, Memgraph will either allow the user to connect or, in case of failure, close the connection.

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.

Configuration

Roles

User roles must be defined in Memgraph before using auth modules because these modules return the role associated with the user.

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.

The schemes with built-in support are:

  • basic (username + password authentication with external module)
  • saml-entra-id
  • saml-okta
  • oidc-entra-id
  • oidc-okta

Environment variables

The built-in auth modules (used with the saml-entra-id, saml-okta, oidc-entra-id, and oidc-okta auth schemes) are further configured using environment variables. See the individual SSO module sections for more detail.

Auth module architecture

Communication

Memgraph uses inter-process pipes to communicate with the module. The module will receive auth requests on file descriptor 1000 and has to return auth responses to 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).

The protocol used between Memgraph and the module is as follows:

  • Each auth request is sent as a JSON encoded object in a single line that is terminated by a \n.
  • Each auth response must be sent as a JSON encoded object in a single line that is terminated by a \n.
  • Auth requests are objects that contain the following fields:
    • basic auth scheme:
    • username - the user's username
    • password - the user's password
    • other auth schemes:
    • scheme - the string representing the auth method, e.g. oidc-entra-id
    • response - the authentication response (e.g. SAML response or JWT)
  • Auth responses must be objects that contain the following fields:
    • authenticated - a bool indicating whether the user is allowed to log in to the database
    • role - a string indicating which role the user should have (must be supplied)
    • errors (optional) - if authenticated is false, Memgraph will put up a warning with the error message returned by the module

If the external auth module crashes during the processing of an auth request, Memgraph won't allow the user to log in to the database and will automatically restart the auth module for the next auth request. All crash logs will be seen in Memgraph's output (typically in systemd logs using journalctl).

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):
    return {"authenticated": True, "role": "moderator"}
 
 
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("sponge", "bob") == {"authenticated": True, "role": "analyst"}
assert module.authenticate("CHUCK", "NORRIS") == {"authenticated": True, "role": "admin"}

Single sign-on

Single sign-on (SSO) lets you use an external ID to log in to Memgraph from Lab.

The built-in SSO modules let you customize which data from the identity service supplies the username and password. Username configuration is service- and protocol-specific, whereas role configuration works universally via remapping.

The MEMGRAPH_SSO_{provider}_{protocol}_ROLE_MAPPING flags define how the identity service roles correspond to Memgraph’s.

The role mapping is defined as a string where individual mappings are separated by a semicolon ;. Each mapping is structured as follows: {identity service role}:{Memgraph role}.

For example, the entra.admin:memadmin; entra.user:memuser mapping defines that the identity service roles entra.admin and entra.user respectively map to Memgraph’s memadmin and memuser 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.

SAML

Memgraph has built-in support for single sign-on (SSO) over the SAML protocol with the Microsoft Entra ID and Okta identity providers.

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).

The following environment variables are used to configure the built-in SAML module:

Entra ID
  • MEMGRAPH_SSO_ENTRA_ID_SAML_CALLBACK_URL: the same as AUTH_SAML_ENTRA_ID_CALLBACK_URL for Memgraph Lab
  • MEMGRAPH_SSO_ENTRA_ID_SAML_ASSERTION_AUDIENCE: the application audience (opens in a new tab); for single-tenant apps, equal to spn:{tenant id}
  • MEMGRAPH_SSO_ENTRA_ID_SAML_IDP_CERT: the path to the application’s SAML certificate (opens in a new tab)
  • MEMGRAPH_SSO_ENTRA_ID_SAML_IDP_ID: equal to https://sts.windows.net/{tenant id}/
  • MEMGRAPH_SSO_ENTRA_ID_SAML_ASSERTIONS_ENCRYPTED: set to true if Entra ID is configured to encrypt assertions in the SAML response
  • MEMGRAPH_SSO_ENTRA_ID_SAML_SP_PRIVATE_KEY: if using a private key to decrypt assertions, set this flag’s value to the path to the key
  • MEMGRAPH_SSO_ENTRA_ID_SAML_WANT_ATTRIBUTE_STATEMENT: set to true if the Entra ID SAML response is required to contain attributes
  • MEMGRAPH_SSO_ENTRA_ID_SAML_USE_NAME_ID: set to true in order to supply the username from the SAML NameID attribute
  • MEMGRAPH_SSO_ENTRA_ID_NAME_ID_ENCRYPTED: set to true if Entra ID is configured to encrypt the NameID element
  • MEMGRAPH_SSO_ENTRA_ID_SAML_USERNAME_ATTRIBUTE: if not using NameID, set the name of the SAML response attribute that contains the username
  • MEMGRAPH_SSO_ENTRA_ID_SAML_ROLE_MAPPING: the role mapping
Okta
  • MEMGRAPH_SSO_OKTA_SAML_CALLBACK_URL: the same as AUTH_SAML_OKTA_CALLBACK_URL for Memgraph Lab
  • MEMGRAPH_SSO_OKTA_SAML_ASSERTION_AUDIENCE: the application audience (opens in a new tab)
  • MEMGRAPH_SSO_OKTA_ID_SAML_IDP_CERT: the path to the application’s SAML certificate (opens in a new tab)
  • MEMGRAPH_SSO_OKTA_SAML_IDP_ID: the Okta issuer URL (opens in a new tab)
  • MEMGRAPH_SSO_OKTA_SAML_ASSERTIONS_ENCRYPTED: set to true if Okta is configured to encrypt assertions in the SAML response
  • MEMGRAPH_SSO_OKTA_SAML_SP_PRIVATE_KEY: if using a private key to decrypt assertions, set this flag’s value to the path to the key
  • MEMGRAPH_SSO_OKTA_SAML_WANT_ATTRIBUTE_STATEMENT: set to true if the Okta SAML response is required to contain attributes
  • MEMGRAPH_SSO_OKTA_SAML_USE_NAME_ID: set to true in order to supply the username from the SAML NameID attribute
  • MEMGRAPH_SSO_OKTA_NAME_ID_ENCRYPTED: set to true if Okta is configured to encrypt the NameID element
  • MEMGRAPH_SSO_OKTA_SAML_USERNAME_ATTRIBUTE: if not using NameID, set the name of the SAML response attribute that contains the username
  • MEMGRAPH_SSO_OKTA_SAML_ROLE_ATTRIBUTE: set the name of the SAML response attribute that contains the user role
  • MEMGRAPH_SSO_OKTA_SAML_ROLE_MAPPING: the role mapping

OpenID Connect (OIDC)

Memgraph also supports authentication and authorization using OIDC (OIDC + OAuth 2.0) protocol with a built-in auth module that is packaged with Memgraph Enterprise.

The module currently supports the following SSO providers:

  • Microsoft Entra ID
  • Okta using a custom authorization server

To use the built-in auth module run Memgraph with the --auth-module-mappings flag with the name of each provider and protocol you want to use separated with a semicolon (;). For example, to use OIDC with both Entra ID and Okta run Memgraph with --auth-module-mappings=oidc-okta;oidc-entra-id.

For SSO provider setup see this.

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.

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. You can install them by running pip3 install -r /path/to/requirements.txt. If you are running a native build make sure that you don't have the Python JWT library installed (you can check that with pip freeze) as PyJWT and JWT have some conflicts.

Module configuration

The module is located at /usr/lib/memgraph/auth_module/oidc.py. The module has no configuration file. You have to run Memgraph with some environmental variables. To use multiple SSO providers you have to set the environmental variables associated with that provider.

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=

You can find the tenant and client ID in the app overview in Azure. For a more detailed explanation see this.

Role mapping is described here.

The username variable tells the OIDC module what to use as the username. It has the format token-type:field. 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 (opens in a new tab) and id (opens in a new tab) 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 MS Entra ID one commonly used field is access:preferred_username which is usually the email of the user. For a list of all default claims look at this (opens in a new tab) and this (opens in a new tab). You can also configure custom claims.

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 is described here.

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.

Username

The username variable tells the OIDC module what to use as the username. It has the format token-type:field. 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 (opens in a new tab) and id (opens in a new tab) 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 (opens in a new tab).

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.

Basic (username + password) auth

When Memgraph is set up to use the external auth module for basic authentication (--auth-module-mappings=basic), its internal users are automatically disabled. Users are authenticated only using the module and existing local users are ignored.

LDAP

Memgraph also supports authentication and authorization using LDAP with a built-in auth module that is packaged with Memgraph Enterprise.

The module supports the authentication and authorization (LDAP bind and search requests) operation mode.

Mode of operation

When using LDAP authentication the module builds the DN used for authentication using the user specified username and the following formula:

DN = prefix + username + suffix

In most common situations the prefix will be cn= and the suffix will be ,dc=example,dc=com. With an example username alice that would yield a DN equal to cn=alice,dc=example,dc=com which will then be used for the LDAP bind operation with the user specified password.

After the user is authenticated, the module searches through the role mapping root DN object that contains role mappings. A role mapping object that has the current bound user as its member attribute is used as the user's role. The role that is mapped to the user is the CN attribute of the role mapping object. The attribute that contains the user DN in the mapping object, as well as the attribute that contains the role name, can be changed in the module configuration file to accommodate your LDAP schema.

When searching for a role in directories that have thousands of roles, the search process could take some time, causing long login times.

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 initial example configuration file that has all settings documented and explained is located 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

In order to enable the use of the LDAP authentication and authorization module you have to set the following flag: --auth-module-mappings=basic.

Other flags that change the behavior of the database to module integration can be specified according to your needs.

Example

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

Run Memgraph

Firs, prepare Memgraph for the integration with LDAP. Run a Memgraph instance without any users in its local authentication storage. For more details on how the native authentication storage works in Memgraph check user privileges.

Create an administrator

When using the 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.

Check 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 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

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 mapping entries are children of the ou=roles,dc=memgraph,dc=com entry, that the children have user DNs specified in their member attribute and that the cn attribute should be used to determine the role name.

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.

So now when Alice logs in, the LDAP auth module will go through the following entries: cn=admin,ou=roles,dc=memgraph,dc=com and cn=moderator,ou=roles,dc=memgraph,dc=com. Because Alice is a member of the moderator role mapping, the LDAP auth module will assign role moderator to Alice.

Adjust permissions

Permissions for users and roles are still managed through Memgraph, they can't be managed through the LDAP server.

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 scenario Alice and Bob will be able to log in. Alice will be allowed to log in because her role (moderator) already exists. Carol and Dave won't be allowed to log in because their role (administrator) doesn't exist.