关于 neo4j-security-skill
面向管理 Neo4j 安全设置的 Agent 技能,涵盖用户、角色、权限、属性级控制和 ABAC 规则。它要求执行安全变更前先展示命令并取得明确确认。
主要功能
- 01用户与角色管理指引
- 02权限授予、拒绝与检查
- 03属性级访问控制模式
- 04基于 OIDC 声明和用户标签的 ABAC
- 05安全变更确认门控
适用场景
- 01创建或暂停数据库用户
- 02设计只读或写入角色
- 03限制敏感属性的访问
- 04按声明或标签动态分配角色
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ neo4j-contrib/ neo4j-skills --skill neo4j-security-skill安装后在 Claude Code 中输入/neo4j-security-skill确认已加载。
附带文件README.mdreferences/privilege-reference.md
详细介绍
适用场景
- 创建、修改、暂停或删除用户
- 创建角色、授予或撤销角色成员资格
- 授予、拒绝或撤销图、数据库或 DBMS 权限
- 检查当前权限(
SHOW PRIVILEGES) - 实施属性级访问控制(按属性控制读写)
- 针对 OIDC 声明或原生用户标签设置 ABAC 规则
- 参考 LDAP/SSO 身份验证提供程序配置
不适用场景
- 针对应用数据编写 Cypher 查询 →
neo4j-cypher-skill - 集群运维、备份、服务器配置 →
neo4j-cli-tools-skill - 驱动程序连接设置 →
neo4j-driver-*-skill
MCP 写入门禁 — 必须遵守
执行以下任何操作前,先展示计划执行的命令并等待明确确认:
CREATE USER/ALTER USER/DROP USERCREATE ROLE/DROP ROLEGRANT/DENY/REVOKE(任何权限)CREATE AUTH RULE/DROP AUTH RULE
绝不自动执行权限变更。展示完整 Cypher,说明影响,并取得“yes”确认。
执行上下文
所有安全相关的 Cypher 都在 system 数据库中运行:
// 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"
1. 用户管理
创建用户
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) | SUSPENDED
参数化密码(脚本中推荐使用)
CREATE USER $username SET PASSWORD $password CHANGE NOT REQUIRED;
Aura 密码的最小长度将在 2027.01 升级(2027 年 1 月)时从 8 位提高到 16 位——仅对新用户以及密码更改或重置生效;现有密码仍可使用。现在就为配置脚本生成至少 16 位的密码。
修改用户
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 missing
用户标签 [2026.06+,Enterprise]
标签是原生用户对象上的任意字符串,可在 ABAC 规则中通过 abac.native.user_tags() 读取。
CREATE USER jake SET PASSWORD $pw SET TAGS 'finance', 'auditor';
ALTER USER jake REMOVE TAG 'auditor' ADD TAG 'on-call'; // REMOVE before ADD before SET
ALTER USER jake SET TAGS 'finance', 'auditor'; // replaces all existing tags
ALTER USER jake REMOVE ALL TAGS;
ALTER USERS jake, alice ADD TAGS 'pii-access'; // bulk tag edit
SET/ADD/REMOVE TAG[S] 需要 SET USER METADATA 权限;读取标签值需要 SHOW USER METADATA 权限:
GRANT SET USER METADATA ON DBMS TO userAdmin;
GRANT SHOW USER METADATA ON DBMS TO auditor;
GRANT USER METADATA MANAGEMENT ON DBMS TO userManager; // both of the above
显示用户
SHOW USERS YIELD user, roles, passwordChangeRequired, suspended, home
WHERE suspended = false
RETURN user, roles ORDER BY user;
// tags column returns null without SHOW USER METADATA [2026.06+]
SHOW USERS YIELD user, roles, tags;
// runnable CREATE USER commands for the whole DBMS [2026.09]
// requires SHOW USER + SHOW USER CREDENTIALS; tags omitted without SHOW USER METADATA
SHOW USERS AS COMMANDS;
SHOW USERS WITH AUTH AS COMMANDS; // includes auth provider config + credentials
SHOW USERS WITH AUTH AS COMMANDS 会公开凭据。仅用于安全的备份/恢复处理。如果不需要身份验证材料,优先使用 SHOW USERS AS COMMANDS。切勿将身份验证导出的输出粘贴到明文文档、日志、工单或源代码管理中。
删除用户
DROP USER alice IF EXISTS;
2. 角色管理
创建 / 删除角色
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
// runnable CREATE ROLE commands for the whole DBMS [2026.09]
SHOW ROLES AS COMMANDS;
SHOW ROLES WITH USERS AS COMMANDS; // adds GRANT ROLE ... TO user
SHOW ROLES WITH AUTH RULES AS COMMANDS; // adds GRANT ROLE ... TO AUTH RULE
3. 权限决策表
| 目标 | 命令 |
|---|---|
| 允许连接数据库 | GRANT ACCESS ON DATABASE mydb TO analyst |
| 读取所有图数据 | GRANT MATCH {*} ON GRAPH mydb ELEMENTS * TO analyst |
| 读取特定标签 | GRANT MATCH {*} ON GRAPH mydb NODES Person TO analyst |
| 读取特定关系类型 | GRANT MATCH {*} ON GRAPH mydb RELATIONSHIPS KNOWS TO analyst |
| 读取单个属性 | GRANT READ {email} ON GRAPH mydb NODES Person TO analyst |
| 遍历但隐藏属性 | GRANT TRAVERSE ON GRAPH mydb NODES Person TO analyst |
| 写入(创建/设置) | GRANT WRITE ON GRAPH mydb TO writer |
| 仅创建节点 | GRANT CREATE ON GRAPH mydb NODES Person TO writer |
| 仅删除节点 | GRANT DELETE ON GRAPH mydb NODES Person TO writer |
| 执行过程 | GRANT EXECUTE PROCEDURE apoc.* TO analyst |
| 执行函数 | GRANT EXECUTE USER DEFINED FUNCTION apoc.* TO analyst |
| 对单个数据库拥有全部权限 | GRANT ALL ON DATABASE mydb TO dba |
| 完整 DBMS 管理权限 | GRANT ALL ON DBMS TO dba |
| 管理用户 | GRANT USER MANAGEMENT ON DBMS TO secadmin |
| 管理用户标签 [2026.06] | GRANT USER METADATA MANAGEMENT ON DBMS TO secadmin |
| 管理角色 | GRANT ROLE MANAGEMENT ON DBMS TO secadmin |
| 修改架构 | GRANT CREATE ELEMENT TYPES ON DATABASE mydb TO schemaadmin |
DENY 优先于 GRANT
// 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 用于撤销特定的授权或拒绝
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+deny
4. 常见角色模式
只读分析师
CREATE 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 invisible
DBA 角色(完整管理权限)
CREATE ROLE dba IF NOT EXISTS;
GRANT ALL ON DBMS TO dba;
GRANT ALL ON DATABASE * TO dba;
5. 属性级访问控制(企业版)
限制对单个属性的读取访问:
// 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;
// List-valued property contains a value [2026.08, Cypher 25]
GRANT MATCH {*} ON GRAPH mydb
FOR (n) WHERE 'gold' IN n.clearanceLevels
TO goldTier;
GRANT READ {*} ON GRAPH mydb FOR (n) WHERE 'EU' IN n.regions TO regularUsers;
GRANT MATCH {*} ON GRAPH mydb FOR (n) WHERE NOT 'EU' IN n.regions TO regularUsers;
// Property on the right-hand side of a comparison [2026.08, Cypher 25]
GRANT MATCH {*} ON GRAPH mydb
FOR (n) WHERE 1 > n.level
TO analyst;
GRANT READ {*} ON GRAPH mydb FOR (n) WHERE 3 < n.securityLevel TO regularUsers;
// Dynamic row-level security: property matches caller's native user tags [2026.10, Enterprise]
GRANT TRAVERSE ON GRAPH * FOR (n:Project) WHERE n.department IN abac.native.user_tags() TO projectTeam;
n.prop IN abac.native.user_tags()[2026.10] — 一个角色适用于所有标签值;需要在dbms.security.abac.authorization_providers中配置native(参见 §6)。不能使用NOT取反 → 应改为在标签匹配时授予权限value IN n.listProp— 列表属性包含该值- 属性缺失或为标量 — 不匹配
- 左侧的值 — 非 null 且非 NaN
n.prop IN [v1, v2]— 标量与列表比较- Cypher 25 之前的版本 — 将属性保留在比较的左侧
PBAC 边缘情况和导出模式 → references/privilege-reference.md
限制:
FOR模式仅适用于读取权限,不适用于写入权限- 每项基于属性的权限只能受单个属性限制
- 2026.08 之前的版本:不接受列表成员关系和属性位于右侧的谓词 — 应改写为
n.prop <op> <literal>,或维护一个标量标志属性 - 性能开销随规则数量增加;
TRAVERSE规则的开销高于READ - 确保受限制角色无法修改规则所用的属性
6. ABAC — 基于属性的访问控制(企业版)
ABAC 根据 OIDC/JWT 声明或原生用户标签动态授予角色,而不是显式执行 GRANT ROLE ... TO user。
前提条件
# neo4j.conf — providers must also appear in dbms.security.authorization_providers
dbms.security.abac.authorization_providers=<oidc-provider-alias>,native # native [2026.06+]
未列出的提供方 → 其访问器函数(abac.oidc.user_attribute()、abac.native.user_tags())不可用,引用它们的规则会失败(不会静默使用默认值)。
创建授权规则
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;
原生用户 [2026.06+]:为原生数据库用户添加标签(参见用户标签),并通过 abac.native.user_tags() 在规则中匹配标签 — 无需 OIDC:
CREATE AUTH RULE nativeSalesRule
SET CONDITION 'sales' IN abac.native.user_tags();
GRANT ROLE analyst TO AUTH RULE nativeSalesRule;
// require several tags at once
CREATE AUTH RULE financeAuditRule
SET CONDITION all(tag IN ['finance', 'auditor'] WHERE tag IN abac.native.user_tags());
// combine tags with OIDC claims and temporal conditions
CREATE AUTH RULE onCallRule
SET CONDITION 'on-call' IN abac.native.user_tags()
AND abac.oidc.user_attribute('department') = 'engineering'
AND time.transaction('UTC').hour >= 9;
❌ 切勿以标签缺失为条件:NOT ('restricted' IN abac.native.user_tags()) — 任何未创建标签的用户都会满足此条件,从而获得更高权限。
✅ 要求存在标签:'unrestricted' IN abac.native.user_tags()。
注意:
- 缺失的声明会被计算为 NULL → 规则条件为 false → 不授予角色
- 如果声明已加载,规则会立即应用于现有会话
- OIDC 声明通过
abac.oidc.user_attribute()获取;原生用户标签通过abac.native.user_tags()获取 [2026.06+]。LDAP 没有访问器函数 — 应改为给 LDAP 用户的原生用户对象添加标签 - PBAC 属性规则谓词中不接受用户定义函数 [2026.06+]
- Infinigraph(分片属性数据库)仅支持 PBAC
READ,且权限授予虚拟数据库 [2026.07+,Aura 除外] — 参见 references/privilege-reference.md
7. SHOW PRIVILEGES 模式
// 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;
// Privileges of roles granted to an auth rule [2026.09]
SHOW AUTH RULES salesRule PRIVILEGES AS COMMANDS;
// 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;
8. 内置角色(不要删除)
| 角色 | 范围 |
|---|---|
admin | 完整 DBMS 权限 + 所有数据库 |
architect | 所有数据库上的架构更改 + 写入权限 |
publisher | 所有数据库上的写入权限 |
editor | 写入权限,不包括架构更改 |
reader | 所有数据库上的只读权限 |
public | 所有用户隐式拥有;默认主数据库访问权限 |
分配内置角色:GRANT ROLE reader TO alice;
9. 身份验证提供方配置参考(运维 — 非 Cypher)
原生(默认)
dbms.security.auth_enabled=true
dbms.security.auth_max_failed_attempts=3 # lockout threshold
LDAP
dbms.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" = admin
OIDC / SSO(Okta、Auth0、Entra ID)
dbms.security.oidc.<alias>.display_name=Okta
dbms.security.oidc.<alias>.auth_flow=pkce # `implicit` deprecated 2026.06, removal planned — keep 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" = admin
配置更改需要重启服务。映射中引用的角色必须已存在于 Neo4j 中(原生角色或通过 Cypher 创建的角色)。
清单 — 新角色设置
- 确定所需操作:读取 / 写入 / 管理
- 确定目标数据库和图范围(所有标签还是特定标签)
- 确定必须隐藏的属性(→ DENY READ)
- 创建角色:
CREATE ROLE ... IF NOT EXISTS - 授予数据库的 ACCESS 权限
- 按需授予 MATCH / TRAVERSE / WRITE 权限
- 对受限属性应用 DENY
- 运行
SHOW ROLE ... PRIVILEGES AS COMMANDS进行验证 - 分配给用户:
GRANT ROLE ... TO ... - 使用
SHOW USER ... PRIVILEGES AS COMMANDS进行测试
完整权限语法 → references/privilege-reference.md