Loading...
Loading...
Programmatic security management in Neo4j — RBAC/ABAC, user lifecycle (CREATE/ALTER/DROP USER), role lifecycle (CREATE/GRANT ROLE/DROP ROLE), privilege grants and denies (GRANT/DENY/REVOKE on graph, database, DBMS), property-level access control, sub-graph access control, SHOW PRIVILEGES inspection, and auth provider config reference (LDAP, OIDC/SSO). Use when an agent needs to manage users, roles, or privileges programmatically via Cypher on the system database. Does NOT handle Cypher query writing — use neo4j-cypher-skill. Does NOT handle cluster ops or backups — use neo4j-cli-tools-skill. Property-level security and ABAC require Enterprise Edition.
npx skill4agent add neo4j-contrib/neo4j-skills neo4j-security-skillSHOW PRIVILEGESneo4j-cypher-skillneo4j-cli-tools-skillneo4j-driver-*-skillCREATE USERALTER USERDROP USERCREATE ROLEDROP ROLEGRANTDENYREVOKECREATE AUTH RULEDROP AUTH RULE// Neo4j auto-routes CREATE/ALTER/SHOW USER|ROLE|PRIVILEGE to system
// If using cypher-shell: cypher-shell -d system
// If using driver: use database="system"CREATE USER alice SET PASSWORD 'secret' CHANGE NOT REQUIRED;
// CHANGE REQUIRED (default): forces password change on first login
// CHANGE NOT REQUIRED: password valid immediately
// SET STATUS ACTIVE (default) | SUSPENDEDCREATE USER $username SET PASSWORD $password CHANGE NOT REQUIRED;ALTER USER alice SET PASSWORD $newPw CHANGE NOT REQUIRED;
ALTER USER alice SET STATUS SUSPENDED; // lock account
ALTER USER alice SET STATUS ACTIVE; // unlock
ALTER USER alice SET HOME DATABASE mydb; // default db on connect
ALTER USER alice IF EXISTS SET PASSWORD $pw; // safe if missingSHOW USERS YIELD username, roles, passwordChangeRequired, suspended, homeDatabase
WHERE suspended = false
RETURN username, roles ORDER BY username;DROP USER alice IF EXISTS;CREATE ROLE analyst;
CREATE ROLE analyst IF NOT EXISTS;
DROP ROLE analyst IF EXISTS;GRANT ROLE analyst TO alice;
GRANT ROLE analyst, writer TO alice, bob; // bulk
REVOKE ROLE analyst FROM alice;SHOW ROLES YIELD role, member ORDER BY role;
SHOW ROLE analyst PRIVILEGES AS COMMANDS; // returns runnable GRANT commands
SHOW POPULATED ROLES YIELD role; // only roles with members| Goal | Command |
|---|---|
| Allow db connection | |
| Read all graph data | |
| Read specific label | |
| Read specific rel type | |
| Read one property | |
| Traverse but hide properties | |
| Write (create/set) | |
| Create nodes only | |
| Delete nodes only | |
| Execute procedure | |
| Execute function | |
| All on one db | |
| Full DBMS admin | |
| Manage users | |
| Manage roles | |
| Schema changes | |
// Analyst can read Person but NOT the ssn property
GRANT MATCH {*} ON GRAPH mydb NODES Person TO analyst;
DENY READ {ssn} ON GRAPH mydb NODES Person TO analyst;REVOKE GRANT READ {email} ON GRAPH mydb NODES Person FROM analyst;
REVOKE DENY READ {ssn} ON GRAPH mydb NODES Person FROM analyst;
REVOKE MATCH {*} ON GRAPH mydb NODES Person FROM analyst; // removes both grant+denyCREATE ROLE analyst IF NOT EXISTS;
GRANT ACCESS ON DATABASE mydb TO analyst;
GRANT MATCH {*} ON GRAPH mydb ELEMENTS * TO analyst;
GRANT EXECUTE PROCEDURE apoc.* TO analyst;CREATE ROLE writer IF NOT EXISTS;
GRANT ACCESS ON DATABASE mydb TO writer;
GRANT MATCH {*} ON GRAPH mydb ELEMENTS * TO writer;
GRANT WRITE ON GRAPH mydb TO writer;CREATE ROLE limited_reader IF NOT EXISTS;
GRANT ACCESS ON DATABASE mydb TO limited_reader;
GRANT TRAVERSE ON GRAPH mydb ELEMENTS * TO limited_reader; // can traverse
GRANT MATCH {*} ON GRAPH mydb NODES Person TO limited_reader; // Person props visible
GRANT MATCH {*} ON GRAPH mydb NODES Company TO limited_reader; // Company props visible
// Other labels: traversable but properties invisibleCREATE ROLE dba IF NOT EXISTS;
GRANT ALL ON DBMS TO dba;
GRANT ALL ON DATABASE * TO dba;// Grant read on all Person props, then deny sensitive ones
GRANT MATCH {*} ON GRAPH mydb NODES Person TO analyst;
DENY READ {ssn, dateOfBirth} ON GRAPH mydb NODES Person TO analyst;// Only see Person nodes where classification = 'public'
GRANT MATCH {*} ON GRAPH mydb
FOR (n:Person) WHERE n.classification = 'public'
TO analyst;
// Block access to classified nodes
DENY MATCH {*} ON GRAPH mydb
FOR (n) WHERE n.classification <> 'UNCLASSIFIED'
TO regularUsers;FORTRAVERSEREADGRANT ROLE ... TO user# neo4j.conf
dbms.security.abac.authorization_providers=<oidc-provider-alias>CREATE AUTH RULE salesRule
SET CONDITION abac.oidc.user_attribute('department') = 'sales';
GRANT ROLE analyst TO AUTH RULE salesRule;CREATE OR REPLACE AUTH RULE seniorRule
SET CONDITION abac.oidc.user_attribute('department') = 'engineering'
AND abac.oidc.user_attribute('level') >= 5;
GRANT ROLE senior_engineer TO AUTH RULE seniorRule;SHOW AUTH RULES YIELD ruleName, condition, roles;
ALTER AUTH RULE salesRule SET ENABLED false; // disable without dropping
RENAME AUTH RULE salesRule TO salesDeptRule;
DROP AUTH RULE salesDeptRule;
REVOKE ROLE analyst FROM AUTH RULE salesRule;// All privileges in the system
SHOW PRIVILEGES YIELD *;
// Privileges for a specific user (as runnable commands)
SHOW USER alice PRIVILEGES AS COMMANDS;
// Privileges for a specific role
SHOW ROLE analyst PRIVILEGES YIELD privilege, action, resource, graph, segment;
// Find who has access to a database
SHOW PRIVILEGES YIELD *
WHERE graph = 'mydb'
RETURN role, action, resource, segment ORDER BY role;
// Find all DENY rules
SHOW PRIVILEGES YIELD *
WHERE access = 'DENIED'
RETURN role, action, resource, segment;| Role | Scope |
|---|---|
| Full DBMS + all databases |
| Schema changes + write on all databases |
| Write on all databases |
| Write excluding schema changes |
| Read-only on all databases |
| All users implicitly; default home database access |
GRANT ROLE reader TO alice;dbms.security.auth_enabled=true
dbms.security.auth_max_failed_attempts=3 # lockout thresholddbms.security.auth_provider=ldap
dbms.security.ldap.host=ldap://ldap.example.com
dbms.security.ldap.authentication.mechanism=simple
dbms.security.ldap.authentication.user_dn_template=uid={0},ou=users,dc=example,dc=com
dbms.security.ldap.authorization.group_membership_attributes=memberOf
dbms.security.ldap.authorization.group_to_role_mapping=\
"cn=analysts,ou=groups,dc=example,dc=com" = analyst;\
"cn=admins,ou=groups,dc=example,dc=com" = admindbms.security.oidc.<alias>.display_name=Okta
dbms.security.oidc.<alias>.auth_flow=pkce
dbms.security.oidc.<alias>.well_known_discovery_uri=https://example.okta.com/.well-known/openid-configuration
dbms.security.oidc.<alias>.audience=neo4j
dbms.security.oidc.<alias>.claims.username=email
dbms.security.oidc.<alias>.claims.groups=groups
dbms.security.oidc.<alias>.authorization.group_to_role_mapping=\
"neo4j-analysts" = analyst;\
"neo4j-admins" = adminCREATE ROLE ... IF NOT EXISTSSHOW ROLE ... PRIVILEGES AS COMMANDSGRANT ROLE ... TO ...SHOW USER ... PRIVILEGES AS COMMANDS