Neo4j Single Sign-On (SSO) configuration

Neo4j supports SSO authentication and authorization through identity providers implementing the OpenID Connect (OIDC) standard. This page features detailed examples of how to configure Single Sign-On (SSO) for several identity providers. It also presents frequently asked questions and solutions to common problems encountered when configuring SSO.

The following configurations are crafted for a Neo4j Browser served on http://localhost:7474/browser/ (the default URL when starting the database on localhost).

Therefore, when reproducing them in the identity providers, you must modify the redirect URI to include the URI serving your Neo4j Browser application. For example:

http://localhost:7474/browser/?idp_id={provider}&auth_flow_step=redirect_uri

SSO works in the following way:

  1. The server (Neo4j DBMS) contacts the identity provider (Okta, Entra ID, Google, etc.) and fetches the JSON Web Keys (JWKs) from the provider.

  2. The client (e.g., Bloom, Neo4j Browser, etc.) asks the user for credentials and contacts the identity provider.

  3. The identity provider responds with a JSON Web Token (JWT), a JSON file containing fields (claims) relative to the user (email, audience, groups, etc.).

  4. The client provides the server with the JWT, and the server verifies its signature with the JWKs.

    JWTs must always contain a value for sub even when using a different claim for username. It is the only claim guaranteed to be unique and stable. Other claims, such as email or preferred_username are less secure and may change over time. They should not be used for authentication. Neo4j may assign permissions to a user based on this username value in a hybrid authorization configuration. Thus, changing the username claim from sub is not recommended.

Okta

Access token

This example shows how to configure Okta for authentication and authorization using access tokens.

  1. Configure the client with the appropriate redirect URI. You can skip the group assignments in this step:

    oidc okta client creation
    Figure 1. Okta OIDC client creation
    oidc okta client config a
    Figure 2. Okta OIDC client configuration
  2. Take note of the Client ID and the Okta domain. You will need them later when configuring the Okta parameters and the Well-known OpenID Connect endpoint in the neo4j.conf file:

    oidc okta client config b
    Figure 3. Okta OIDC client configuration
  3. Create groups in Okta, assign users to them (the user can be added to a group either on user creation or editing the group), and map them in the neo4j.conf to native groups:

    oidc okta server groups
    Figure 4. Okta OIDC server groups
  4. Configure the default authorization server (the one that shows api://default as audience) to return the groups claim in access tokens:

    oidc okta authz server
    Figure 5. Okta OIDC authorization server
    oidc okta server claims
    Figure 6. Okta OIDC server claims
  5. Configure Neo4j to use Okta authentication by configuring the following settings in the neo4j.conf file:

    dbms.security.authentication_providers=oidc-okta
    dbms.security.authorization_providers=oidc-okta
    dbms.security.oidc.okta.display_name=Okta
    dbms.security.oidc.okta.auth_flow=pkce
    dbms.security.oidc.okta.well_known_discovery_uri=https://dev-21056049.okta.com/oauth2/default/.well-known/openid-configuration
    dbms.security.oidc.okta.audience=api://default
    dbms.security.oidc.okta.claims.username=sub
    dbms.security.oidc.okta.claims.groups=groups
    dbms.security.oidc.okta.params=client_id=0oa3oq6uw3uSOBf8y5d7;response_type=code;scope=openid profile email
    dbms.security.oidc.okta.authorization.group_to_role_mapping= "engineers" = admin; \
                                                                 "collaborators" = reader

    The token_type_principal and the token_type_authentication are omitted, meaning access tokens are used instead.

  6. Log in with your Okta SSO credentials using the email of an engineer role user that results in an admin role in the database:

    oidc okta successful login
    Figure 7. Okta OIDC successful login

ID token

This example shows how to configure Okta for authentication and authorization using ID tokens.

  1. Follow the first two steps from the instructions for Access token.

  2. Create the claims as indicated:

    okta claims
    Figure 8. Okta claim creation panel

    In the case of access tokens, a default sub is already provided automatically. However, for ID tokens, the name you give to your claim needs to be also indicated in the configuration dbms.security.oidc.okta.claims.username=userid.

  3. Configure the default authorization server (the one that shows api://default as audience) as indicated:

    dbms.security.authentication_providers=oidc-okta, native
    dbms.security.authorization_providers=oidc-okta
    dbms.security.oidc.okta.display_name=Okta
    dbms.security.oidc.okta.auth_flow=pkce
    dbms.security.oidc.okta.well_known_discovery_uri=https://trial-2696363.okta.com/oauth2/default/.well-known/openid-configuration
    dbms.security.oidc.okta.audience=0oa42hwrygsUCFlLO697
    dbms.security.oidc.okta.claims.username=userid
    dbms.security.oidc.okta.claims.groups=groups
    dbms.security.oidc.okta.params=client_id=0oa42hwrygsUCFlLO697;response_type=code;scope=openid profile email
    dbms.security.oidc.okta.authorization.group_to_role_mapping="admin_group" = admin;
    dbms.security.oidc.okta.config=token_type_principal=id_token;token_type_authentication=id_token
  4. You should now find the audience under Okta’s sign-on tab:

    okta sign on tab
    Figure 9. Okta’s sign-on tab

Microsoft Entra ID (formerly Azure Active Directory)

Access token

This example shows how to configure Entra ID for authentication and authorization using an access token.

  1. Set parameters to be access_token:

    dbms.security.oidc.azure.config=principal=unique_name;code_challenge_method=S256;token_type_principal=access_token;token_type_authentication=access_token
  2. Add the following parameter:

    dbms.security.oidc.azure.token_endpoint=https://login.microsoftonline.com/54e85725-ed2a-49a4-a19e-11c8d29f9a0f/oauth2/v2.0/token

    The GUID is the directory (tenant) ID. You can find it on the app registration page:

    azure id
  3. Include the issuer:

    dbms.security.oidc.azure.issuer=https://sts.windows.net/54e85725-ed2a-49a4-a19e-11c8d29f9a0f/

    As previously mentioned, the GUID here is also the directory (tenant) ID. Make sure you add the trailing slash (/) at the end or this operation might fail.

  4. Go to the "Expose an API" tab and click "Add a Scope" to include the following statement:

    dbms.security.oidc.azure.params=client_id=4376dc8b-b5af-424f-9ada-c1c1b2d416b9;response_type=code;scope=openid profile email api://4376dc8b-b5af-424f-9ada-c1c1b2d416b9/access-token
  5. Add the value in the scope column to the scopes in the configuration. Note that the audience parameter for access tokens are typically set with` api://` at the front.

ID token

This example shows how to configure Entra ID for authentication and authorization using ID tokens.

Register the application

  1. Log in to the Azure portal.

  2. Navigate to Microsoft Entra ID > Overview.

  3. From the Add dropdown menu, select App registration and fill in the following information to create your SSO application:

    oidc azure client creation
    Figure 10. Entra OIDC client creation

    The redirect URI http://localhost:7474/browser/?idp_id=azure&auth_flow_step=redirect_uri is the URI that will accept returned token responses after successful authentication.

  4. Click Register.

Configure Neo4j

  1. After the successful app creation, on the app’s Overview page, find the Application (client) ID value. Use it to configure the following properties in the neo4j.conf file.

    dbms.security.oidc.azure.audience=c2830ff5-86d9-4e38-8a2b-9efad6f3d06d
    dbms.security.oidc.azure.params=client_id=c2830ff5-86d9-4e38-8a2b-9efad6f3d06d;response_type=code;scope=openid profile email
  2. Navigate to Endpoints, to find the OpenID Connect metadata document. Use it to configure the well_known_discovery_uri in the neo4j.conf file.

    oidc azure client config
    Figure 11. Entra OIDC client config
    dbms.security.oidc.azure.well_known_discovery_uri=https://login.microsoftonline.com/ce976899-299d-4a01-91e5-a5fee8f98626/v2.0/.well-known/openid-configuration
  3. Configure Neo4j to use Entra ID authentication by configuring the following settings in the neo4j.conf file:

    dbms.security.authentication_providers=oidc-azure
    dbms.security.authorization_providers=oidc-azure
    dbms.security.oidc.azure.display_name=Azure
    dbms.security.oidc.azure.auth_flow=pkce
    dbms.security.oidc.azure.config=token_type_principal=id_token;token_type_authentication=id_token
  4. Configure which JWT claim should be used for usernames. Possible values are sub, email, or preferred_username.

    sub is the only claim guaranteed to be unique and stable. For details, see Microsoft documentation as well as the OpenId spec.

    dbms.security.oidc.azure.claims.username=sub

Map Entra groups to Neo4j roles

Decide whether you want to use Entra groups directly or Entra App Roles.

Using Entra groups directly might be convenient if you already have users assigned to those groups and want to perform Group-to-Role mapping in Neo4j settings.

Entra App Roles allow a layer of separation between Neo4j roles and groups. When App Roles are used, only the roles relevant to Neo4j are sent in the JWT token. This prevents leaking permissions between applications. JWT tokens also have a limitation of 200 roles per token per user, which can be avoided by sending only the relevant App Roles.

Details about Entra ID App Roles can be found in the Microsoft documentation.

Using Entra groups directly

  1. Configure the server to return the Group Object IDs in the JWT identity tokens. To do this, set groupMembershipClaims to SecurityGroup in the Manifest of the registered application:

    oidc azure server claims
    Figure 12. Entra OIDC server claims
  2. Create groups in the Entra AD console and assign users to them. Take note of the Object Id column. In the next step, you must map these to user roles in the Neo4j settings.

    oidc azure server groups
    Figure 13. Entra OIDC server groups
  3. Configure a mapping from Entra Group Object IDs to Neo4j roles. For details, see Map the Identity Provider Groups to the Neo4j Roles.

    dbms.security.oidc.azure.authorization.group_to_role_mapping= "e8b6ddfa-688d-4ace-987d-6cc5516af188" = admin; \
                                                                  "9e2a31e1-bdd1-47fe-844d-767502bd138d" = reader
  4. Configure Neo4j to use the groups field from the JWT token.

    dbms.security.oidc.azure.claims.groups=groups

Using Entra ID App Roles

  1. On the app’s home page, navigate to App roles and add the Neo4j roles to the Microsoft Entra ID.

    oidc azure app roles
    Figure 14. Entra OIDC app roles config
  2. The Value column in the App roles config must either correspond to Neo4j Roles or be mapped in the neo4j.conf file. For details, see Map the Identity Provider Groups to the Neo4j Roles.

    dbms.security.oidc.azure.authorization.group_to_role_mapping= "managers" = admin; \
                                                                  "engineers" = reader
  3. Configure Neo4j to use the roles field from the JWT token.

    dbms.security.oidc.azure.claims.groups=roles

Google

This example shows how to use Google OpenID Connect for authentication using ID tokens in conjunction with native authorization.

  1. Configure the client and the redirect URI:

    oidc google client creation
    Figure 15. Google OIDC client creation
    oidc google client config
    Figure 16. Google OIDC client configuration

    SSO authorization does not work with Google, as the JWT returned by Google does not contain information about the groups that a user belongs to, and cannot be configured to. Therefore, it is recommended to use native (or another flavor) authorization by creating a native version of the user in Neo4j.

  2. The role assigned to the email used to log in with SSO, in this case, alice@neo4j-test.com, must have GRANT ROLE permissions in the database (native authentication temporarily enabled):

    CREATE USER `alice@neo4j-test.com` SET PASSWORD 'secretpassword';
    GRANT ROLE admin to `alice@neo4j-test.com`;
  3. Configure Neo4j to use Google authentication by configuring the following settings in the neo4j.conf file:

    dbms.security.authentication_providers=oidc-google
    dbms.security.authorization_providers=native
    dbms.security.oidc.google.display_name=Google
    dbms.security.oidc.google.auth_flow=pkce
    dbms.security.oidc.google.well_known_discovery_uri=https://accounts.google.com/.well-known/openid-configuration
    dbms.security.oidc.google.audience=345461137297-v9brpjmgbvbm3d5s9fq65tktevosd3rn.apps.googleusercontent.com
    dbms.security.oidc.google.claims.username=email
    dbms.security.oidc.google.params=client_id=345461137297-v9brpjmgbvbm3d5s9fq65tktevosd3rn.apps.googleusercontent.com;response_type=code;scope=openid profile email
    dbms.security.oidc.google.token_params=client_secret=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
    dbms.security.oidc.google.config=token_type_principal=id_token;token_type_authentication=id_token
  4. Log in with your Google SSO credentials using the email address and get the admin role when doing so:

    oidc azure successful login
    Figure 17. Entra OIDC successful login

    The native authentication is disabled to prevent someone from logging in to alice@neo4j-test.com with the set password.

FAQ

When should pkce be used as auth flow?

Assuming the client (Neo4j Browser or Bloom) can be accessed through the public internet, always use pkce auth-flow rather than implicit because the latter requires the client’s secret to be available to the public client. In general, if both flows are available, it is recommended to opt for pkce because it is more secure than implicit.

Is Google authentication secure if it has a client secret listed in the config?

Yes. Google uses the pkce flow, but identity providers sometimes also use a client secret to ensure the client asking for a token is the one using it (pkce does not guarantee that). The client secret does not add any additional security as it is public but the pkce flow provides sufficient security.

Could not parse JWT of type "access_token"

When getting the message Failed to get credentials: Could not parse JWT of type "access_token" on Browser, it probably means the provider only accepts ID tokens.

oidc access token error
Figure 18. Failed to parse JWT of type access_token

Change to ID tokens in your neo4j.conf:

dbms.security.oidc.{{provider}}.config=token_type_principal=id_token;token_type_authentication=id_token

When should identity tokens vs. access tokens be used?

It is generally safer to use access tokens when possible due to being shorter-lived. If authorization permissions change on the identity provider, Neo4j will fail authorization. Neo4j Browser will try to reconnect and reflect the changed permissions faster than if ID tokens were used.

Debug logging of JWT claims

While setting up an OIDC integration, it is sometimes necessary to perform troubleshooting. In these cases, it can be useful to view the claims contained in the JWT supplied by the identity provider. To enable the logging of these claims at DEBUG level in the security log, set dbms.security.logs.oidc.jwt_claims_at_debug_level_enabled to true and the security log level to DEBUG.

Make sure to set dbms.security.logs.oidc.jwt_claims_at_debug_level_enabled back to false for production environments to avoid unwanted logging of potentially sensitive information. Also, bear in mind that the set of claims provided by an identity provider in the JWT can change over time.

How to debug further problems with the configuration

Apart from the logs available in logs/debug.log and logs/security.log in the Neo4j path, you can also use the web-development console in your web browser when doing the SSO authentication flow with Bloom or Neo4j Browser. This could reveal potential problems, such as the one presented below with an example identity provider and the Cross-Origin Request policy:

oidc cors error
Figure 19. CORS error

The solution involves adding the redirect domain to the list of allowed domains in the provider (in this case, localhost:8080):

oidc cors error solution
Figure 20. CORS error solution allowing the redirect domain on the provider