Attribute-based access control

Attribute-based access control (ABAC) grants roles based on the evaluation of attributes (or claims) contained in a user’s authentication token.

Setup

To set up attribute-based access control, follow these steps:

  1. In the neo4j.conf file, set dbms.security.abac.authorization_providers to the OIDC provider(s) you want to use for ABAC.

  2. Define authorization rules for granting roles based on user attributes using the CREATE AUTH RULE command. See Create auth rules for details.

  3. Specify which roles to assign when the authorization rules are fulfilled using the GRANT ROLE command. 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 command requires the CREATE AUTH RULE privilege. See Grant privilege to create auth rules for details on how to grant this privilege.

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 exists, and the command has no effect. OR REPLACE and IF NOT EXISTS cannot be used at the same time.
3 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 conditionExpression is a Boolean Cypher expression that evaluates user attributes (claims) contained in the authentication token. To access an attribute, use the syntax abac.oidc.user_attribute('<claim_key>').

The conditionExpression can use any valid Cypher expression that evaluates to a Boolean value, including logical operators (AND, OR, NOT, etc), comparison operators (=, <>, <, >, , and >=), and the following built-in functions:

Table 1. Neo4j built-in functions for auth rule conditions
Function group Functions

List functions

range(), reduce(), reverse(), tail(), toBooleanList(), toFloatList(), toIntegerList(), toStringList()

Numeric functions

abs(), ceil(), floor(), isNaN(), round(), sign()

Predicate functions

all(), any(), isEmpty(), none(), single()

Scalar functions

char_length(), character_length(), coalesce(), head(), last(), nullIf(), size(), toBoolean(), toBooleanOrNull(), toFloat(), toFloatOrNull(), toInteger(), toIntegerOrNull()

String Functions

btrim(), left(), lower(), ltrim(), replace(), reverse(), right(), rtrim(), split(), substring(), toLower(), toString(), toStringOrNull(), toUpper(), trim(), upper()

Temporal duration functions

duration(), duration.between(), duration.inDays(), duration.inMonths(), duration.inSeconds()

Temporal instant types functions

date([ input, pattern ]), date.transaction(), date.truncate(), datetime([ input, pattern ]), datetime.transaction(), datetime.truncate(), localdatetime([ input, pattern ]), localdatetime.transaction(), localdatetime.truncate(), localtime([ input, pattern ]), localtime.transaction(), localtime.truncate(), time([ input, pattern ]), time.transaction(), time.truncate()

The functions, date, datetime, localdatetime, localtime, and time are only supported when you use an input argument.

4 (Optional) The SET ENABLED clause allows you to enable or disable the rule upon creation. By default, the rule is enabled.

Example 1: Create auth rules with a simple condition

The following example creates an auth rule that grants the associated roles to users with the attribute department equals sales:

CREATE AUTH RULE salesRule
    SET CONDITION abac.oidc.user_attribute('department') = 'sales';

Example 2: Create auth rules with multiple conditions

The following example creates an auth rule that grants the associated roles to users with the attribute 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';

Example 3: Create auth rules based on a list of values

The following example creates an auth rule that grants the associated roles to users with 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']);

Example 4: Create auth rules with temporal conditions

The following example creates an auth rule that temporarily grants the assigned roles to users with 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;

Assign roles to auth rules

To specify which roles to be granted to the user when the authorization rule is fulfilled, use the GRANT ROLE command.

The GRANT ROLE command requires the ASSIGN ROLE privilege. See Grant privilege to assign roles for details on how to grant this privilege.

GRANT ROLE syntax
GRANT ROLE[S] role[, ...] TO AUTH RULE[S] ruleName[, ...]

For information about the GRANT ROLE command, see Assigning roles to users.

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;

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.

The ABAC rule does not restrict the RBAC role. Users receive both their RBAC roles and the roles from fulfilled auth rules. If a user receives a role via both ABAC and RBAC, then the user will have that role regardless of whether the ABAC rule is currently fulfilled or not. For example, if a user receives the admin role because it appears in their JWT groups claim (RBAC), and there is also an ABAC rule that grants the admin role between the hours of 19:00 and 20:00, then the user will have the admin role at all times, even outside the hours of 19:00 and 20:00, because of the RBAC assignment.

Revoke roles from auth rules

To revoke roles from an authorization rule, use the REVOKE ROLE command.

The REVOKE ROLE command requires the REMOVE ROLE privilege. See Grant privilege to remove roles for details on how to grant this privilege.

REVOKE ROLE syntax
REVOKE ROLE[S] role[, ...] FROM AUTH RULE[S] ruleName[, ...]

For information about the REVOKE ROLE command, see Revoking roles from users.

The following example revokes the reader role from the auth rule temporary_reader:

REVOKE ROLE reader FROM AUTH RULE temporary_reader;

Listing auth rules

You can list all auth rules using the Cypher command SHOW AUTH RULES.

The SHOW AUTH RULES command requires the SHOW AUTH RULE privilege. See Grant privilege to list auth rules for details on how to grant this privilege.

SHOW AUTH RULES returns a table containing a single row per auth rule with the following columns:

Table 2. SHOW AUTH RULES output
Column Description Type

name

The name of the auth rule as defined in the CREATE or RENAME AUTH RULE command.

STRING

condition

A Cypher expression that is evaluated when determining whether to grant the roles to the user.

STRING

enabled

Whether the auth rule is enabled or not. This column has the value true when the auth rule is enabled, and false when it is not. When an auth rule is disabled, it is not evaluated, so users cannot receive its roles.

BOOLEAN

roles

The roles granted to the auth rule via one or more GRANT ROLE … TO AUTH RULE … commands. This column returns null if the executing user is missing or denied the SHOW ROLES privilege.

LIST OF STRING

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.

Table 3. SHOW AUTH RULES AS COMMANDS output
Column Description Type

command

The CREATE AUTH RULE command to create the auth rule.

STRING

roles

The roles granted to the auth rule via one or more GRANT ROLE … TO AUTH RULE … commands. This column returns null if the executing user is missing or denied the SHOW ROLES privilege.

LIST OF STRING

Example 1: List auth rules

The following example lists all auth rules with their conditions, enablement, and assigned roles:

SHOW AUTH RULES;
Table 4. Result
name condition enabled roles

"salesRule"

"abac.oidc.user_attribute('department') = 'sales'"

true

["salesTeam"]

"engineeringUKRule"

"abac.oidc.user_attribute('department') = 'engineering' AND abac.oidc.user_attribute('location') = 'UK'"

true

["engineeringTeamUK"]

"ruleset_countries"

"any(country IN abac.oidc.user_attribute('citizenshipCountries') WHERE country IN ['c1', 'c5'])"

true

["countryAccessRole"]

Rows: 3

Example 2: List 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:

Table 5. Result
name roles

"engineeringUKRule"

["engineeringTeamUK"]

"salesRule"

["salesTeam"]

Rows: 2

It is also possible to use SKIP and LIMIT to paginate the results.

Example 3: List auth rules as commands

The following example lists the auth rules as commands:

SHOW AUTH RULES AS COMMANDS;
Table 6. Result
command

CREATE AUTH RULE engineeringUKRule SET CONDITION abac.oidc.user_attribute('department') = 'engineering' AND abac.oidc.user_attribute('location') = 'UK' SET ENABLED true

CREATE AUTH RULE salesRule SET CONDITION abac.oidc.user_attribute('department') = 'sales' SET ENABLED true

CREATE AUTH RULE ruleset_countries SET CONDITION any(country IN abac.oidc.user_attribute('citizenshipCountries') WHERE country IN ['c1', 'c5']) SET ENABLED true

Rows: 3

Rename auth rules

To rename an existing authorization rule, use the RENAME AUTH RULE command.

The RENAME AUTH RULE command requires the RENAME AUTH RULE privilege. See Grant privilege to rename auth rules for details on how to grant this privilege.

RENAME AUTH RULE syntax
RENAME AUTH RULE ruleName [IF EXISTS] TO newRuleName

If specifying IF EXISTS, no error is raised if the rule does not exist and the command has no effect.

For example, use the following command to rename the auth rule ruleset_countries to disabled_ruleset_countries:

RENAME AUTH RULE ruleset_countries TO disabled_ruleset_countries;

Modify auth rules

To modify an existing authorization rule, use the ALTER AUTH RULE command.

The ALTER AUTH RULE command requires the ALTER AUTH RULE privilege. See Grant privilege to modify auth rules for details on how to grant this privilege.

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.

Example 1: 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'])

Example 2: Disable an auth rule

The following example disables the auth rule ruleset_countries:

ALTER AUTH RULE ruleset_countries SET ENABLED false

Drop auth rules

To drop an existing authorization rule, use the DROP AUTH RULE command.

The DROP AUTH RULE command requires the DROP AUTH RULE privilege. See Grant privilege to delete auth rules for details on how to grant this privilege.

DROP AUTH RULE syntax
DROP AUTH RULE ruleName [IF EXISTS]

If specifying IF EXISTS, no error is raised if the rule does not exist and the command has no effect.

For example, use the following command to delete the auth rule temporary_reader:

DROP AUTH RULE temporary_reader;

Caveats and limitations

ABAC has the following caveats and limitations:

  • When evaluating abac.oidc.user_attribute('<claim_key>'), if the claim does not exist in the authentication token, it will evaluate to NULL.

  • Newly created auth rules are applied to existing user sessions, but can only have access to the user claims which had rules referencing them at the start of the session. Only user claims that are used in pre-existing auth rules at the start of a session are retained. If the new rules use new claims, users must re-authenticate for the new rules to be applied.

  • Attribute-based access control is only supported for OIDC authentication providers.

  • For troubleshooting ABAC evaluation, enable debug logging for the security log and debug log, and turn on JWT claims logging at debug level in the neo4j.conf file by setting dbms.security.logs.oidc.jwt_claims_at_debug_level_enabled=true.