neo4j-security-skill
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,
By neo4j-contrib · 531 installs
npx skills add neo4j-contrib/neo4j-skills --skill neo4j-security-skill
Source repository · Upstream listing
When to Use
Creating, altering, suspending, or dropping users
Creating roles, granting/revoking role membership
Granting/denying/revoking graph, database, or DBMS privileges
Inspecting current privileges ( SHOW PRIVILEGES )
Implementing property level access control (read/write per property)
Setting up ABAC rules against OIDC claims or native user tags
Referencing LDAP/SSO auth provider configuration
When NOT to Use
Writing Cypher queries against application data → neo4j cypher skill
Cluster ops, backups, server config → neo4j cli tools skill
Driver connection setup → neo4j driver skill
MCP Write Gate — MANDATORY
Before executing ANY of the following, show the planned command and wait for explicit confirmation:
CREATE USER / ALTER USER / DROP USER
CREATE ROLE / DROP ROLE
GRANT / DENY / REVOKE (any privilege)
CREATE AUTH RULE / DROP AUTH RULE
Never auto execute privilege changes. Show exact Cypher, annotate impact, get "yes".
Execution Context
All security Cypher runs against the system database:
1. User Management
Create user
Parameterised password (preferred in scripts)
Alter user
User tags [2026.06+, Enterprise]
Tags are arbitrary strings on the native user object, readable in ABAC rules via abac.native.user tags() .
SET/ADD/REMOVE TAG[S] requires SET USER METADATA ; reading tag values requires SHOW USER METADATA :
Show users
Drop user
2. Role Management
Create / drop role
Assign / remove roles
Inspect roles
3. Privilege Decision Table
Goal Command
Allow db connection GRANT ACCESS ON DATABASE mydb TO analyst
Read all graph data GRANT MATCH { } ON GRAPH mydb ELEMENTS TO analyst
Read specific label GRANT MATCH { } ON GRAPH mydb NODES Person TO analyst
Read specific rel type GRANT MATCH { } ON GRAPH mydb RELATIONSHIPS KNOWS TO analyst
Read one property GRANT READ {email} ON GRAPH mydb NODES Person TO analyst
Traverse but hide properties GRANT TRAVERSE ON GRAPH mydb NODES Person TO analyst
Write (create/set) GRANT WRITE ON GRAPH mydb TO writer
Create nodes only GRANT CREATE ON GRAPH mydb NODES Person TO writer
Delete nodes only GRANT DELETE ON GRAPH mydb NODES Person TO writer
Execute procedure GRANT EXECUTE PROCEDURE apoc. TO analyst
Execute function GRANT EXECUTE USER DEFINED FUNCTION apoc. TO analyst
All on one db GRANT ALL ON DATABASE mydb TO dba
Full DBMS admin GRANT ALL ON DBMS TO dba
Manage users GRANT USER MANAGEMENT ON DBMS TO secadmin
Manage user tags [2026.06] GRANT USER METADATA MANAGEMENT ON DBMS TO secadmin
Manage roles GRANT ROLE MANAGEMENT ON DBMS TO secadmin
Schema changes GRANT CREATE ELEMENT TYPES ON DATABASE mydb TO schemaadmin
DENY overrides GRANT
REVOKE removes a specific grant or deny
4. Common Role Patterns
Read only analyst
Write role (no admin)
Read only on specific labels only
DBA role (full admin)
5. Property Level Access Control (Enterprise)
Restrict read access to individual properties:
Property based pattern matching (sub graph access):
Constraints:
FOR pattern applies to read privileges only — not write
Each property based privilege restricted by a single property
Performance overhead scales with number of rules; TRAVERSE rules cost more than READ
Ensure the property used for rules cannot be modified by the restricted role
6. ABAC — Attribute Based Access Control (Enterprise)
ABAC grants roles dynamically from OIDC/JWT claims or native user tags rather than explicit GRANT ROLE ... TO user .
Prerequisites
Unlisted provider → its accessor function ( abac.oidc.user attribute() , abac.native.user tags() ) unavailable and rules referencing it fail (no silent default).
Create auth rule
Compound conditions
Manage auth rules
Native users [2026.06+]: tag native DB users (see [User tags]( user tags 202606 enterprise)) and match tags in rules via abac.native.user tags() — no OIDC required:
❌ Never condition on tag absence: NOT ('restricted' IN abac.native.user tags()) — any user created without tags satisfies it, escalating privileges.
✅ Require presence of a tag: 'unrestricted' IN abac.native.user tags() .
Notes:
Missing claims evaluate to NULL → rule condition false → role not granted
Rules apply immediately to existing sessions when claims are already loaded
OIDC claims via abac.oidc.user attribute() ; native user tags via abac.native.user tags() [2026.06+]. LDAP has no accessor function — tag the LDAP user's native user object instead
User defined functions rejected in PBAC property rule predicates [2026.06+]
Infinigraph (sharded property databases) supports PBAC READ only, granted on the virtual database [2026.07+, not on Aura] — see [references/privilege reference.md](references/privilege reference.md)
7. SHOW PRIVILEGES Patterns
8. Built in Roles (do not drop)
Role Scope
admin Full DBMS + all databases
architect Schema changes + write on all databases
publisher Write on all databases
editor Write excluding schema changes
reader Read only on all databases
public All users implicitly; default home database access
Assign built in roles: GRANT ROLE reader TO alice;
9. Auth Provider Config Reference (operational — not Cypher)
Native (default)
LDAP
OIDC / SSO (Okta, Auth0, Entra ID)
Config changes require server restart . Roles referenced in mappings must exist in Neo4j (native or created via Cypher).
Checklist — New Role Setup
[ ] Determine required operations: read / write / admin
[ ] Identify target database(s) and graph scope (all labels vs specific)
[ ] Identify any properties that must be hidden (→ DENY READ)
[ ] Create role: CREATE ROLE ... IF NOT EXISTS
[ ] Grant ACCESS on database
[ ] Grant MATCH / TRAVERSE / WRITE as needed
[ ] Apply DENY for restricted properties
[ ] Run SHOW ROLE ... PRIVILEGES AS COMMANDS to verify
[ ] Assign to users: GRANT ROLE ... TO ...
[ ] Test with SHOW USER ... PRIVILEGES AS COMMANDS
Full privilege syntax → [references/privilege reference.md](references/privilege reference.md)