Attribute-based access controlAuraDB Business CriticalAuraDB Virtual Dedicated CloudCypher 25Enterprise EditionIntroduced in 2026.03
Attribute-based access control (ABAC) grants roles based on the evaluation of user attributes. These could be claims contained in a user’s authentication token, or starting with Neo4j 2026.06, tags attached to a native user object.
ABAC is useful when access should depend on who a user is or the context of their request, rather than on a static, manually maintained mapping of users to roles.
Because roles are assigned dynamically from attributes, you can express access policies declaratively, for example, "grant the finance role to users in the finance department" or "grant elevated access only during on-call hours", and have them applied automatically as users and their attributes change.
This reduces the need to manually grant and revoke roles as people join, move between teams, or leave, keeps authorization decisions consistent with the source of truth for user attributes, such as your identity provider, and makes it possible to enforce fine-grained, context-aware policies that would be cumbersome to maintain with role assignments alone.
ABAC is also useful when you need more flexibility than an external auth provider, such as LDAP or OIDC, can offer on its own. For example, you may not have control over the provider, the provider might not expose a claim for everything you want to base access on, or you might want to combine its claims with attributes managed inside Neo4j (native user tags) or with contextual conditions such as the time of day. In these cases, auth rules let you layer additional, locally-defined logic on top of the identity information supplied by the external provider.
|
User metadata tagging for native DBMS users as part of ABAC rules is available in Neo4j 2026.06 and later. |
Setup
To set up attribute-based access control, follow these steps:
-
In the neo4j.conf file, set
dbms.security.abac.authorization_providersto be the list of authorization provider(s) you want to use for ABAC. These can include any OIDC provider, as well as thenativeprovider starting with Neo4j 2026.06. In order for a provider to be allowed in the list ofdbms.security.abac.authorization_providers, it must also appear in the list ofdbms.security.authorization_providers.When reasoning about which auth rules will apply for your users, given your choice of
dbms.security.abac.authorization_providers, consider which rules could feasibly be executed.For example, a purely temporal rule such as
time.transaction('UTC').hour >= 9 AND time.transaction('UTC').hour < 17does not reference any provider, so it can execute regardless of which providers are configured (but only when at least one valid provider is indeed configured).In contrast, a rule that calls the metadata accessor function of a provider that is not in the list will fail. When a provider is not listed in
dbms.security.abac.authorization_providers, its relevant accessor function, for example,abac.oidc.user_attribute()for an OIDC provider, orabac.native.user_tags()for thenativeprovider, is not available at all. Therefore, any rule that references it intentionally fails rather than silently evaluating to a default, meaning the rule cannot be fulfilled, and the user cannot receive the roles from that rule. -
Define authorization rules for granting roles based on user attributes using the
CREATE AUTH RULEcommand. See Create auth rules for details. -
Specify which roles to assign when the authorization rules are fulfilled using the
GRANT ROLEcommand. See Assign roles to auth rules for details.
Create auth rules
To create an authorization rule, use the CREATE AUTH RULE command.
|
The |
CREATE AUTH RULE syntax
CREATE [OR REPLACE] AUTH RULE ruleName (1)
[IF NOT EXISTS] (2)
SET CONDITION conditionExpression (3)
[ SET ENABLED {true | false} ] (4)
Where:
| 1 | Adding OR REPLACE to the command deletes any existing auth rule with the same name and creates a new auth rule with the same name.
Any assigned roles associated with the old auth rule will not be associated to the new auth rule. |
||||
| 2 | Appending IF NOT EXISTS to the command ensures that no error is returned and nothing happens should a rule with the same name already exist, and the command has no effect.
OR REPLACE and IF NOT EXISTS cannot be used at the same time. |
||||
| 3 | Introduced in 2026.06 The SET CONDITION clause allows you to specify a condition that must be met for a user to be granted the roles associated with the auth rule.
The For more information on attaching tags to native users, see Creating users and Modifying users. The
|
||||
| 4 | (Optional) The SET ENABLED clause allows you to enable or disable the rule upon creation.
By default, the rule is enabled. |
Create an auth rule with a simple condition
The following example creates an auth rule that grants the associated roles to users who have the attribute department equals sales:
CREATE AUTH RULE salesRule
SET CONDITION abac.oidc.user_attribute('department') = 'sales';
Create an auth rule with multiple conditions
The following example creates an auth rule that grants the associated roles to users who have attributes department equals engineering and location equals UK:
CREATE AUTH RULE engineeringUKRule
SET CONDITION abac.oidc.user_attribute('department') = 'engineering'
AND abac.oidc.user_attribute('location') = 'UK';
Create an auth rule based on a list of values
The following example creates an auth rule that grants the associated roles to users who have the attribute citizenshipCountries containing any of the allowed countries c1 or c5:
CREATE AUTH RULE ruleset_countries SET CONDITION
any(country IN abac.oidc.user_attribute('citizenshipCountries')
WHERE country IN ['c1', 'c5']);
Create auth rules with temporal conditions
The following example creates an auth rule that temporarily grants the assigned roles to users who have the attribute jobTitle equals developer, between the hours of 19:00 and 20:00:
CREATE AUTH RULE temporary_reader
SET CONDITION abac.oidc.user_attribute('jobTitle') = 'developer'
AND datetime.transaction().hour >= 19 AND datetime.transaction().hour < 20;
The following example uses time.transaction() anchored to UTC to avoid dependency on the server’s default timezone, granting access to users in the EMEA region during European working hours (06:00–18:00 UTC):
CREATE AUTH RULE emea_working_hours
SET CONDITION abac.oidc.user_attribute('region') = 'EMEA'
AND time.transaction('UTC').hour >= 6 AND time.transaction('UTC').hour < 18;
Create an auth rule based on native user tagsIntroduced in 2026.06
As well as evaluating claims from an OIDC token, auth rules can evaluate the tags attached to a native user using the abac.native.user_tags() function.
This function returns the list of tags assigned to the authenticated user.
The following example grants the associated roles to any native user who has been tagged with pii-access:
CREATE AUTH RULE piiAccessRule
SET CONDITION 'pii-access' IN abac.native.user_tags();
Create an auth rule requiring multiple native user tagsIntroduced in 2026.06
Because abac.native.user_tags() returns a list, you can combine it with the list predicate functions to require several tags at once.
The following example grants the associated roles only to native users tagged with both finance and auditor:
CREATE AUTH RULE financeAuditorRule
SET CONDITION all(tag IN ['finance', 'auditor'] WHERE tag IN abac.native.user_tags());
Combine native user tags with other conditionsIntroduced in 2026.06
Native user tags can be combined with OIDC claims, temporal functions, and any other supported expression within a single condition (see the SET CONDITION clause).
The following example grants the associated roles to native users tagged with on-call, but only outside standard working hours (before 09:00 or after 17:00 UTC):
CREATE AUTH RULE onCallRule
SET CONDITION 'on-call' IN abac.native.user_tags()
AND (time.transaction('UTC').hour < 9 OR time.transaction('UTC').hour >= 17);
Combine native user tags with OIDC claimsIntroduced in 2026.06
A single condition can evaluate both native user tags and claims from an OIDC token, allowing you to combine attributes managed in your database with attributes asserted by your identity provider.
The following example grants the associated roles to users who are tagged with finance on their native user object and whose department claim in the OIDC token equals finance:
CREATE AUTH RULE financeApproverRule
SET CONDITION 'finance' IN abac.native.user_tags()
AND abac.oidc.user_attribute('department') = 'finance';
For this rule to evaluate abac.native.user_tags() for the OIDC-authenticated user, that user must be linked to a native user — see linking external users.
An auth rule to avoid (condition based on the absence of a tag)Introduced in 2026.06
|
This example illustrates an auth rule design that you should avoid. It demonstrates the risk described in this warning. |
The following rule grants its roles to any native user who does not have the restricted tag:
CREATE AUTH RULE unrestrictedRule
SET CONDITION NOT ('restricted' IN abac.native.user_tags());
Because the condition is satisfied solely by the absence of the restricted tag, any user with no tags meets it.
Subsequently, someone who holds the USER MANAGEMENT privilege but not the USER METADATA MANAGEMENT privilege can create such a user (they can create users, but cannot set or remove tags), and yet that new user would be granted the roles associated with unrestrictedRule.
Instead, base the condition on the presence of a required tag (as in Create an auth rule based on native user tags), so that the roles are only granted when a tag has been deliberately attached by someone holding the SET USER METADATA privilege.
|
For an auth rule to evaluate This linking is achieved either by:
|
Assign roles to auth rules
To specify which roles to grant to the user when the authorization rule is satisfied, use the GRANT ROLE command.
|
The |
GRANT ROLE syntax
GRANT ROLE[S] role[, ...] TO AUTH RULE[S] ruleName[, ...]
For information about the GRANT ROLE command, see Assigning roles to users.
Assign roles to an auth rule example
The following example assigns roles to the auth rules from the examples in Create auth rules:
GRANT ROLE salesTeam TO AUTH RULE salesRule;
GRANT ROLE engineeringTeamUK TO AUTH RULE engineeringUKRule;
GRANT ROLE countryAccessRole TO AUTH RULE ruleset_countries;
GRANT ROLE reader TO AUTH RULE temporary_reader;
GRANT ROLE piiAccessTeam TO AUTH RULE piiAccessRule;
GRANT ROLE financeAuditTeam TO AUTH RULE financeAuditorRule;
GRANT ROLE onCallTeam TO AUTH RULE onCallRule;
GRANT ROLE financeApproverTeam TO AUTH RULE financeApproverRule;
|
No roles with associated deny privileges can be assigned to an auth rule. Also, denied privileges may not be subsequently assigned to a role once that role has been assigned to an auth rule. This ensures that if a rule is unexpectedly not fulfilled (e.g., because a claim is missing from the user’s auth token), then there can never be an escalation of privileges, only ever a reduction. |
|
ABAC rules do not restrict RBAC roles.
Users receive both their RBAC roles and the roles from fulfilled auth rules.
If a user receives a role via both ABAC and RBAC, the user will have that role regardless of whether the ABAC rule is currently satisfied.
For example, if a user receives the |
Revoke roles from auth rules
To revoke roles from an authorization rule, use the REVOKE ROLE command.
|
The |
REVOKE ROLE syntax
REVOKE ROLE[S] role[, ...] FROM AUTH RULE[S] ruleName[, ...]
For information about the REVOKE ROLE command, see Revoking roles from users.
Showing auth rules
You can show all auth rules using the Cypher command SHOW AUTH RULES.
|
The |
SHOW AUTH RULES syntax
SHOW AUTH RULES
SHOW AUTH RULES returns a table containing a single row per auth rule with the following columns:
| Column | Description | Type |
|---|---|---|
name |
The name of the auth rule as defined in the |
|
condition |
A Cypher expression that is evaluated when determining whether to grant the roles to the user. |
|
enabled |
Whether the auth rule is enabled or not.
This column has the value |
|
roles |
The roles granted to the auth rule via one or more |
|
To view the auth rules as commands, use the SHOW AUTH RULES AS COMMANDS, which returns a single column by default.
Optionally, you can append YIELD * to additionally see which roles has been granted to the auth rule.
SHOW AUTH RULES AS COMMANDS syntax
SHOW AUTH RULES AS COMMANDS
SHOW AUTH RULES AS COMMANDS returns a table containing a single row per auth rule with the following columns:
| Column | Description | Type |
|---|---|---|
command |
The |
|
roles |
The roles granted to the auth rule via one or more |
|
Show all auth rules
The following example shows all auth rules with their conditions, enablement, and assigned roles:
SHOW AUTH RULES;
| name | condition | enabled | roles |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Rows: 9 |
|||
Show auth rules with filtering and sorting
To filter and sort the returned results, you can use YIELD, ORDER BY, and WHERE:
SHOW AUTH RULES YIELD name, roles
ORDER BY name
WHERE name ENDS WITH 'e';
The result is a table of auth rules whose names end in 'e', along with their assigned roles, ordered by name:
| name | roles |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Rows: 6 |
|
It is also possible to use SKIP and LIMIT to paginate the results.
Show auth rules as commands
The following example shows the auth rules as commands output, which can be used to recreate the auth rules:
SHOW AUTH RULES AS COMMANDS;
| command |
|---|
|
|
|
|
|
|
|
|
|
Rows: 9 |
Rename auth rules
To rename an existing authorization rule, use the RENAME AUTH RULE command.
|
The |
Modify auth rules
To modify an existing authorization rule, use the ALTER AUTH RULE command.
|
The |
ALTER AUTH RULE syntax
ALTER AUTH RULE ruleName [IF EXISTS]
[SET CONDITION conditionExpression]
[SET ENABLED {true | false}]
If specifying IF EXISTS, no error is raised if the rule does not exist, and the command has no effect.
At least one of SET CONDITION and SET ENABLED must be specified.
Modify the condition of an auth rule
The following example modifies the auth rule ruleset_countries to set a new condition that also allows the country 'c6':
ALTER AUTH RULE ruleset_countries SET CONDITION any(country IN abac.oidc.user_attribute('citizenshipCountries')
WHERE country IN ['c1', 'c5', 'c6']);
Drop auth rules
To drop an existing authorization rule, use the DROP AUTH RULE command.
|
The |
Caveats and limitations
ABAC has the following caveats and limitations:
-
When evaluating
abac.oidc.user_attribute(), if the claim does not exist in the authentication token, it evaluates tonull. -
When evaluating
abac.native.user_tags(), if the user does not have tags set, the function returns an empty list. -
When evaluating
abac.native.user_tags()in conjunction with external authentication , the function returns an empty list if the native user is not found (unlessrequire_local_useris set totrue, in which case the absence of a native user prevents the user from authenticating). -
Newly created or altered auth rule conditions are applied to existing user sessions (i.e., at the start of the user’s next transaction), but can only have access to the user claims that had rule conditions referencing them at the start of the session. Only user claims that are used in pre-existing auth rule conditions at the start of a session are retained. If the new or amended rule conditions use new claims, users must re-authenticate for the new or amended rules to be applied.
-
Changes to a user’s tags (effected via the
ALTER USERcommand) take effect from the start of the user’s next transaction. -
Only OIDC and native authorization providers may be used to supply user attributes. Other types of providers, such as LDAP, can be used in conjunction with native users and their tags, but cannot directly supply attributes to auth rules.
-
Tags support newline characters in the same way that labels do. However, care must be taken when inspecting debug and security logs, as newline characters are replaced with spaces in the log output. This is done to prevent log forging (log injection), where a value containing newlines could otherwise be used to insert fake log entries. As a result, a tag containing a newline character will appear in the logs with a space in place of the newline, making it indistinguishable from a tag that actually contains a space. Reconciling such a tag may therefore require extra steps, for example, combining the output of
SHOW USERS YIELD *(to see the actual tag values assigned to users) withSHOW AUTH RULES(to see the tags referenced by auth rules).
Debugging ABAC evaluation
-
For troubleshooting ABAC evaluation, enable debug logging for the security log and debug log. This allows you to see the outcome of auth rule evaluations.
-
Introduced in 2026.06 Additionally, if using
abac.oidc.user_attribute(), turn on JWT claims logging at the debug level in the neo4j.conf file by settingdbms.security.logs.oidc.jwt_claims_at_debug_level_enabled=true. This allows you to see the claims being evaluated in the auth rules.