Neo4j Role-Based Access: Missing Password Expiration Enforcement
0 reputation · 25 Jul 2021, 09:41 UTC
0 reputation · 25 Jul 2021, 09:41 UTC
Neo4j 4.x and 5.x expose predefined roles such as read, write, and admin, and allow custom roles to be defined. The goal is to apply least‑privilege authentication while ensuring that users cannot continue to authenticate with a password that has surpassed an acceptable age.
Passwords are stored internally using PBKDF2 and the internal user store offers no configuration flag to enforce password expiration. Authentication failures are logged, but the engine does not revoke roles or terminate sessions when a password becomes stale. Consequently, administrators must rely on manual password changes or auxiliary scripts to enforce expiry.
To implement expiry logic, one could augment the internal store with a custom table that records password_last_set timestamps, or create a stored procedure that throws an error when a login attempt occurs with an outdated password. Each approach introduces trade‑offs: additional storage, query overhead, and potential gaps if external tooling is not kept current. Moreover, it is unclear whether future Neo4j releases will add native support for password expiration.
34775 reputation · 25 Jul 2021, 12:43 UTC
The most robust method to enforce password age is to delegate authentication to an external identity provider like LDAP, Active Directory, or OAuth2. These systems handle password complexity, rotation policies, and expiration natively. Neo4j then simply maps the external groups to its internal roles.
neo4j.conf using dbms.security.ldap.enabled=true.CREATE ROLE ... AS GROUP TO ....If you must use the internal store, you can implement a custom authentication provider. Since Neo4j allows for custom security providers via the API, you can write a plugin that intercepts the login attempt.
password_last_set timestamp for each user.If a plugin is not feasible, use an external script to query the database and manage user states.
ALTER USER ... DISABLE or remove the user from specific roles to effectively block access until a manual reset occurs.This analysis assumes you are using Neo4j 4.x or 5.x. It is assumed that you are using the internal user store; if you are already using LDAP, the enforcement is handled by that server. It is currently uncertain if Neo4j will introduce a nativepassword.expiration.days setting in future releases.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 25 Jul 2021, 14:19 UTC
While delegating authentication to LDAP or Active Directory is the standard for enterprise password rotation, it is important to note that users created specifically within the internal store (via CREATE USER) cannot be managed by these external policies. For environments requiring a hybrid approach, the lack of a native EXPIRES clause in the ALTER USER command means that any internal-only accounts—including some administrative or service accounts—will remain static indefinitely unless manually rotated.
To confirm the current state of native support in your specific build, you can attempt to execute a password expiration attribute change. The following check typically confirms the absence of native expiration properties:
ALTER USER username SET PASSWORD expiration = '2026-12-31';
If this returns a syntax error, it confirms that the internal authentication provider does not support native expiration metadata, necessitating the external providers or custom plugins mentioned in previous responses.