# Auth system integrations <sup style={{ fontSize: '0.6em', color: '#888' }}>Enterprise</sup>

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 `;`. SSO schemes with [default module paths](#sso-schemes-with-default-module-paths) can omit the path. If the mapping contains whitespace, enclose the flag value with quotation marks. Replaces `--auth-module-executable`, which no longer works (see [deprecated features](https://memgraph.com/docs/database-management/upgrades/deprecated-features)).
 `--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.

The following SSO schemes have default module paths that point to the built-in
modules shipped with the Memgraph Docker image. When using the Docker image, you
can enable them by listing just the scheme names (without a path), e.g.

```
--auth-module-mappings=saml-entra-id;oidc-okta
```

#### SSO schemes with default module paths
* `saml-entra-id`
* `saml-okta`
* `oidc-entra-id`
* `oidc-okta`
* `oidc-custom`
* `kerberos`

If you are not using the Memgraph Docker image, or if you want to use your own
custom module, you must provide the full path: `<scheme>:<absolute path to module>`, e.g.
`--auth-module-mappings=saml-entra-id:/path/to/your/saml.py`.

For the `basic` scheme (external authentication via LDAP), you always need to
provide the path, e.g.
`--auth-module-mappings=basic:/usr/lib/memgraph/auth_module/ldap.py`.

### Environment variables

The built-in SSO modules (used with the `saml-entra-id`, `saml-okta`,
`oidc-entra-id`, `oidc-okta`, and `kerberos` auth schemes) are further
configured using **environment variables**. See their respective sections
below for more details.

> **Note:** Unlike the SSO modules, which can be configured entirely via
**environment variables**, the LDAP module requires a configuration file
(`/etc/memgraph/auth/ldap.yaml`). This means that in simple deployments (e.g.,
Docker) configuration is less flexible and cannot yet be passed purely via
environment variables.

### Docker deployment note

When deploying Memgraph with **any external authentication module** (for
example, LDAP, SAML, OIDC, or a custom auth module), you must ensure that all
required **roles exist in the database before enabling authentication**.  

External modules return one or more roles for each authenticated user, and
Memgraph matches these roles to existing roles defined in the database. If a
role does not exist at startup, affected users will not be able to log in.

In containerized environments such as **Docker**, this initialization step can
be automated using the `--init-file` flag, which runs a Cypher script before the
database starts. This approach avoids having to manually stop and restart
containers to create roles later.

A recommended workflow:

#### Create a local directory for your Docker setup

```
my_auth_init/
├── Dockerfile
└── roles.cypherl
```

#### Define roles in `roles.cypherl`

```cypher
CREATE ROLE superuser;
GRANT ALL PRIVILEGES TO superuser;
CREATE ROLE moderator;
```

#### Create the Dockerfile

```dockerfile
FROM memgraph/memgraph:latest

USER root
COPY roles.cypherl /usr/lib/memgraph/roles.cypherl
USER memgraph
```

#### Build the Docker image

```
docker build -t memgraph-auth .
```

#### Run Memgraph with authentication enabled and the init file executed on startup

```
docker run -it -p 7687:7687 -p 7444:7444 \
  memgraph-auth \
  --init-file=/usr/lib/memgraph/roles.cypherl \
  --auth-module-mappings=basic:/usr/lib/memgraph/auth_module/ldap.py
```

> Replace the module mapping with your chosen authentication scheme, e.g.
> oidc-okta, saml-entra-id, etc.

This approach ensures that all roles are created before the external
authentication module is activated, allowing users to log in seamlessly across
all supported authentication methods.

This workflow only applies to standalone Memgraph instances. On [data instances
running in HA
mode](https://memgraph.com/docs/clustering/high-availability/how-high-availability-works#data-instance-implementation)
(i.e. when `--management-port` is set), `--init-file` is **not supported** and
the instance will fail to start if the flag is provided. There you must use the
manual procedure instead: start the data instance **without**
`--auth-module-mappings`, log in, create the roles and grant their privileges,
then restart with the flag set.

> **Info**
>
> From Memgraph 3.13, [high availability
> coordinators](https://memgraph.com/docs/clustering/high-availability/coordinator-authentication) also
> support SSO, using these same modules, schemes and `MEMGRAPH_SSO_*` environment
> variables. Coordinators **do not** need this stop-and-restart cycle: basic
> authentication stays open until a role holding `COORDINATOR_WRITE` exists, so
> you can start them with `--auth-module-mappings` from the beginning and create
> the roles over Bolt on the running cluster.
>
> Note that a `neo4j://` routing connection authenticates against a coordinator
> *and* a data instance with the same credentials, so the **same role names must
> exist on both**.

## 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`.

> **Warning**
>
> **As of Memgraph v3.8**, each request includes a unique **message ID** (`memgraph_call_id`). The auth module **must** read this value and **copy it into the response** unchanged. Memgraph uses it to match responses to requests and ignore stale data if the pipe is left in an unknown state (e.g. after a read/write failure). Custom auth modules must be updated for this protocol; otherwise authentication will fail.

**Auth request structure**

| Field      | Description                                                   |
| ---------- | ------------------------------------------------------------- |
| `memgraph_call_id` | Unique message ID. The module **must** copy this value into the response. |
| `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                                |
| --------------- | ------------------- | ------------------------------------------ |
| `memgraph_call_id` | (same as request)   | **Required.** Copy the `memgraph_call_id` from the request so Memgraph can match the response to the request. |
| `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

```python
def authenticate(username, password):
    return {
        "authenticated": True,
        "role": "moderator"  # Single role as string
    }
```

#### Multiple roles

```python
def authenticate(username, password):
    return {
        "authenticated": True,
        "roles": ["admin", "user"]  # Multiple roles as array
    }
```

#### Single role in array format

```python
def authenticate(username, password):
    return {
        "authenticated": True,
        "roles": ["admin"]  # Single role in array
    }
```

**Note:** As of v3.8, every response must also include the `memgraph_call_id` from the request (see [Communication protocol](#communication-protocol) above). The snippets above show only the role-related fields.

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.

```python
#!/usr/bin/python3
import json
import io


def authenticate(memgraph_call_id, username, password):
    # Always copy the message id from the request into the response (required as of v3.8)
    def response(authenticated, **kwargs):
        return {"memgraph_call_id": memgraph_call_id, "authenticated": authenticated, **kwargs}

    # Example with multiple roles
    if username == "admin_user" and password == "password":
        return response(True, roles=["admin", "user"])

    # Example with single role (backward compatible)
    if username == "moderator_user" and password == "password":
        return response(True, role="moderator")

    return response(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:

```python
#!/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](https://memgraph.com/docs/data-visualization/user-manual/single-sign-on).

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

```bash
entra.admin:memadmin; entra.user:memuser
```

Maps:
- `entra.admin` → `memadmin`
- `entra.user` → `memuser`

```
entra.admin:memadmin; entra.user:memuser, memdev
```

Maps:
- `entra.user` → `memuser` 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](https://memgraph.com/docs/database-management/authentication-and-authorization/multiple-roles).

Different services use different parameters for defining roles. Use
`MEMGRAPH_SSO_{provider}_{protocol}_ROLE_FIELD` to specify the token parameter
that specifies the assigned roles.

> **Info**
>
> 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](https://memgraph.com/docs/database-management/authentication-and-authorization/role-based-access-control#label-based-access-control)
> to the roles used in SSO.

> **Info**
>
> 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](https://memgraph.com/docs/data-visualization/user-manual/single-sign-on#set-up-lab-integration).                                                         |
| `MEMGRAPH_SSO_ENTRA_ID_SAML_ASSERTION_AUDIENCE`       | The [application audience](https://learn.microsoft.com/en-us/entra/identity-platform/msal-client-application-configuration#application-audience); for single-tenant apps, use `spn:{tenant id}`. |
| `MEMGRAPH_SSO_ENTRA_ID_SAML_IDP_CERT`                 | Path to the app’s [SAML certificate](https://learn.microsoft.com/en-us/entra/identity-platform/howto-create-service-principal-portal#set-up-authentication).                                     |
| `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](#role-mapping) string.                                                                                                                                                        |

##### Okta

| Variable                                          | Description                                                                                                                                      |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `MEMGRAPH_SSO_OKTA_SAML_CALLBACK_URL`             | Matches `AUTH_SAML_OKTA_CALLBACK_URL` used by [Memgraph Lab](https://memgraph.com/docs/data-visualization/user-manual/single-sign-on#set-up-lab-integration-1).           |
| `MEMGRAPH_SSO_OKTA_SAML_ASSERTION_AUDIENCE`       | The [application audience](https://help.okta.com/oag/en-us/content/topics/access-gateway/add-app-saml-pass-thru-add-okta.htm).                   |
| `MEMGRAPH_SSO_OKTA_ID_SAML_IDP_CERT`              | Path to the app’s [SAML certificate](https://help.okta.com/oie/en-us/content/topics/apps/manage-signing-certificates.htm).                       |
| `MEMGRAPH_SSO_OKTA_SAML_IDP_ID`                   | The [Okta issuer URL](https://support.okta.com/help/s/article/What-is-theIssuerlocated-under-the-OpenID-Connect-ID-Token-app-settings-used-for). |
| `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](#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](https://memgraph.com/docs/data-visualization/user-manual/single-sign-on).

#### 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:

```bash
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](https://memgraph.com/docs/data-visualization/user-manual/single-sign-on) for
  details.

Role mapping uses the same syntax described in [Role mapping](#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:
- [Access token claims]((https://learn.microsoft.com/en-us/entra/identity-platform/access-tokens))
- [ID token claims]((https://learn.microsoft.com/en-us/entra/identity-platform/id-tokens))

#### Okta

For using OIDC with Okta you have to set the following environmental variables:
```bash
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](#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

> **Warning**
>
> 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:

```mdx
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](#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).

##### Self-signed certificates

If your custom OIDC identity provider uses self-signed certificates, you can
configure Memgraph to trust them by setting the `MEMGRAPH_SSO_CUSTOM_OIDC_EXTRA_CA_CERTS`
environment variable. This variable should point to a file containing the CA
certificates that should be trusted when connecting to your
identity server.

```bash
MEMGRAPH_SSO_CUSTOM_OIDC_EXTRA_CA_CERTS=/path/to/ca-certificates
```

#### 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``` 

> **Info**
>
> 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.

```python
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](https://www.okta.com/identity-101/access-token/) and
[id](https://developer.okta.com/docs/guides/validate-id-tokens/main/#id-tokens-vs-access-tokens)
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](https://developer.okta.com/docs/guides/customize-tokens-returned-from-okta/main/).

#### 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](https://memgraph.com/docs/database-management/configuration#auth-module) 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](https://memgraph.com/docs/client-libraries/python#connect-with-single-sign-on-sso).

### Kerberos

Memgraph supports Kerberos SSO via a built-in `kerberos.py` auth module.
Authentication is performed by validating a client-supplied service ticket via
GSSAPI; authorization is delegated either to **AD/LDAP group membership**
(default) or a static **principal-to-role** map. The module is registered
under the `kerberos` auth scheme.

> **Info**
>
> Memgraph Lab does not currently support Kerberos SSO. Connect to a
> Kerberos-enabled Memgraph instance through a Bolt driver (e.g. the Neo4j
> Python driver).

#### Module requirements

The Kerberos module is written in Python 3 and uses the `gssapi` package
(included in the bundled `requirements.txt`, version `1.9.0`). The package
is preinstalled in the Memgraph Docker image.

When running in the default `ldap` role-mapping mode, the module additionally
imports `ldap3`, which is **not** bundled. Install it separately:

```
pip install ldap3
```

System packages needed at runtime:

- RHEL family: `krb5-libs`
- Debian family: `libkrb5-3`

(Building Memgraph from source additionally needs `krb5-devel` /
`libkrb5-dev`.)

#### Enabling Kerberos

Enable the built-in module via `--auth-module-mappings`:

```
--auth-module-mappings=kerberos
```

Or, to use a custom path:

```
--auth-module-mappings=kerberos:/path/to/kerberos.py
```

#### Server-side configuration

The module is fully configured via environment variables.

##### Core variables

| Variable                                          | Description                                                                                                                                                  | Required |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- |
| `MEMGRAPH_SSO_KERBEROS_KEYTAB`                    | Absolute path to the keytab containing the service principal's key. The module sets `KRB5_KTNAME` to this value.                                             | Yes      |
| `MEMGRAPH_SSO_KERBEROS_SERVICE_PRINCIPAL`         | Service principal Memgraph runs as, in the form `service/fqdn@REALM`, e.g. `memgraph/dbhost.example.com@EXAMPLE.COM`.                                        | Yes      |
| `MEMGRAPH_SSO_KERBEROS_ROLE_MAPPING`              | The [role mapping](#role-mapping) string. Use `*:<role>` to map any authenticated principal to a default role.                                               | Yes      |
| `MEMGRAPH_SSO_KERBEROS_REALM`                     | When set, authenticated principals must belong to this realm; otherwise the request is rejected.                                                             | No       |
| `MEMGRAPH_SSO_KERBEROS_USERNAME_FIELD`            | What to use as the Memgraph username: `name` (default — the part of the principal before `@`) or `principal` (the full principal).                          | No       |
| `MEMGRAPH_SSO_KERBEROS_ROLE_MAPPING_MODE`         | `ldap` (default) — query AD/LDAP for group membership and map groups to roles. `principal` — match the Kerberos principal name directly against the mapping. | No       |

##### LDAP role-mapping mode

The variables below apply only when `MEMGRAPH_SSO_KERBEROS_ROLE_MAPPING_MODE`
is `ldap` (the default).

| Variable                                                       | Description                                                                                                                                          | Required |
| -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `MEMGRAPH_SSO_KERBEROS_LDAP_URI`                               | LDAP server URI, e.g. `ldap://dc.example.com:389` or `ldaps://dc.example.com:636`.                                                                   | Yes      |
| `MEMGRAPH_SSO_KERBEROS_LDAP_BASE_DN`                           | Base DN for the directory, e.g. `DC=example,DC=com`.                                                                                                 | Yes      |
| `MEMGRAPH_SSO_KERBEROS_LDAP_SEARCH_BASE`                       | Base under which the user lookup is performed. Defaults to `MEMGRAPH_SSO_KERBEROS_LDAP_BASE_DN`.                                                     | No       |
| `MEMGRAPH_SSO_KERBEROS_LDAP_AUTH`                              | `gssapi` (default) — bind to LDAP via SASL/GSSAPI using the credentials from the service keytab. `simple` — bind with a username and password (set the two variables below). | No       |
| `MEMGRAPH_SSO_KERBEROS_LDAP_BIND_DN`                           | Bind DN, used only with `LDAP_AUTH=simple`.                                                                                                          | No       |
| `MEMGRAPH_SSO_KERBEROS_LDAP_BIND_PASSWORD`                     | Bind password, used only with `LDAP_AUTH=simple`.                                                                                                    | No       |
| `MEMGRAPH_SSO_KERBEROS_LDAP_USER_ATTRIBUTE`                    | LDAP attribute that matches the Kerberos principal name. Defaults to `sAMAccountName` (suitable for AD).                                             | No       |
| `MEMGRAPH_SSO_KERBEROS_LDAP_USER_OBJECT_CLASS`                 | LDAP object class of user entries. Defaults to `user`.                                                                                               | No       |
| `MEMGRAPH_SSO_KERBEROS_LDAP_USER_SEARCH_FILTER`                | Custom LDAP user-search filter; use `{username}` as a placeholder. Overrides the two variables above.                                                | No       |
| `MEMGRAPH_SSO_KERBEROS_LDAP_GROUP_MEMBERSHIP_ATTRIBUTE`        | LDAP attribute holding group memberships on the user entry. Defaults to `memberOf`.                                                                  | No       |
| `MEMGRAPH_SSO_KERBEROS_LDAP_NESTED_GROUPS_ENABLED`             | `true` to transitively resolve nested groups via AD's `LDAP_MATCHING_RULE_IN_CHAIN` (`1.2.840.113556.1.4.1941`). Defaults to `false`.                | No       |
| `MEMGRAPH_SSO_KERBEROS_LDAP_NESTED_GROUPS_SEARCH_FILTER`       | Custom nested-group filter; use `{user_dn}` as a placeholder. Defaults to `(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={user_dn}))`.       | No       |

#### Role-mapping examples

Role mapping uses the same syntax as the other SSO modules — see
[Role mapping](#role-mapping).

In `principal` mode, the left-hand side of each pair is matched against either
the full Kerberos principal (`alice@EXAMPLE.COM`) or the name before `@`
(`alice`). In `ldap` mode, the left-hand side is matched against AD group
**CNs** (the canonical names extracted from group DNs).

```bash
# principal mode: full principal or name-before-@
MEMGRAPH_SSO_KERBEROS_ROLE_MAPPING_MODE=principal
MEMGRAPH_SSO_KERBEROS_ROLE_MAPPING="alice@EXAMPLE.COM:memadmin; bob:memuser"
```

```bash
# ldap mode: AD group CNs map to Memgraph roles
MEMGRAPH_SSO_KERBEROS_ROLE_MAPPING_MODE=ldap
MEMGRAPH_SSO_KERBEROS_ROLE_MAPPING="Memgraph Admins:memadmin; Memgraph Users:memuser, memdev"
```

`*:role` is a wildcard that maps any authenticated principal (or any LDAP user
the search returns) to that role.

#### End-to-end example

A minimal working setup for realm `EXAMPLE.COM` and host
`dbhost.example.com`:

```bash
# Memgraph startup
docker run -it -p 7687:7687 -p 7444:7444 \
  -e MEMGRAPH_SSO_KERBEROS_KEYTAB=/etc/memgraph/memgraph.keytab \
  -e MEMGRAPH_SSO_KERBEROS_SERVICE_PRINCIPAL=memgraph/dbhost.example.com@EXAMPLE.COM \
  -e MEMGRAPH_SSO_KERBEROS_REALM=EXAMPLE.COM \
  -e MEMGRAPH_SSO_KERBEROS_USERNAME_FIELD=name \
  -e MEMGRAPH_SSO_KERBEROS_ROLE_MAPPING_MODE=ldap \
  -e MEMGRAPH_SSO_KERBEROS_LDAP_URI=ldap://dc.example.com:389 \
  -e MEMGRAPH_SSO_KERBEROS_LDAP_BASE_DN="DC=example,DC=com" \
  -e MEMGRAPH_SSO_KERBEROS_ROLE_MAPPING="Memgraph Admins:memadmin; Memgraph Users:memuser" \
  -v /etc/memgraph/memgraph.keytab:/etc/memgraph/memgraph.keytab:ro \
  memgraph/memgraph \
  --auth-module-mappings=kerberos
```

Make sure the `memadmin` and `memuser` roles exist in the database before
authentication is enabled — see
[Docker deployment note](#docker-deployment-note).

#### Connecting with the Neo4j Python driver

Memgraph expects the credential to be the **base64-encoded GSSAPI service
ticket** for the configured service principal. 

```python
from neo4j import GraphDatabase, kerberos_auth

driver = GraphDatabase.driver(
    "bolt://dbhost.example.com:7687",
    auth=kerberos_auth(base64_ticket),  # base64-encoded service ticket
)
```

## Basic authentication

Regular username and password authentication uses Memgraph's internal user
management and works alongside SSO without any additional configuration.

To use LDAP or another custom module for basic authentication instead of
Memgraph's internal user storage, set
`--auth-module-mappings=basic:<path to module>`. This routes all username and
password authentication through the specified module. Note that if a local user
with the same username exists, authentication for that user will fail — avoid
creating local users that overlap with externally managed users.

### 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:

```plaintext
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/ldap.yaml
```  

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

```
/etc/memgraph/auth/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:/usr/lib/memgraph/auth_module/ldap.py
```

You can also combine this with other configuration flags listed in
[Configuration flags](#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:

```plaintext
# 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](https://memgraph.com/docs/getting-started) for running Memgraph, and refer to [User
 privileges](https://memgraph.com/docs/database-management/authentication-and-authorization/role-based-access-control)
 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.

```cypher
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:

```plaintext
--auth-module-mappings=basic
```

Also, add the following LDAP module configuration to
`/etc/memgraph/auth/ldap.yaml`:

```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:

```cypher
GRANT MATCH TO moderator;
```

Once Alice logs in the second time, she should be able to execute the following
query:

```cypher
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:

```yaml
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:

```cypher
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.
