一、核心模型
你的组织关系可以这样理解:
集团 / 租户 Tenant
└── 一级组织 Org
└── 部门 Org
└── 小组 Org
└── 用户 User
建议把组织设计成树形结构,但权限计算时不要只靠 parent_id 递归,后期会慢。可以用:
org:组织表,存 id、parent_id、name、type
org_closure:组织闭包表,存 ancestor_id、descendant_id、depth
user_org_member:用户属于哪些组织
role_assignment:某人在某个组织上拥有什么角色
用户可以属于多个组织,但每次使用 agent 时,最好要求有一个 当前工作组织 active_org。否则同一个用户跨多个部门时,权限边界会非常模糊。
二、权限分层
我建议把权限拆成 5 层,不要混在一起。
- 组织管理权限
- Agent 使用权限
- 数据源权限
- 表 / 字段 / 指标可见性权限
- 查询执行权限与结果权限
这样做的好处是:管理员可以管理 agent,不代表他可以看所有数据;用户可以使用 agent,也不代表 agent 可以访问所有表。
三、组织管理员的设计
每个组织可以有管理员,但管理员也要分级。
常见角色:
TenantOwner 租户超级管理员
OrgAdmin 组织管理员
AgentAdmin Agent 管理员
DataSteward 数据权限管理员 / 数据负责人
Analyst 分析用户
Viewer 只读用户
关键点:
OrgAdmin 只能管理自己组织及子组织,不能管理父组织。
OrgAdmin 可以给子组织用户分配角色,但不能授予自己没有的权限。
AgentAdmin 可以配置 agent,但不一定能看业务数据。
DataSteward 可以配置表、字段、指标、脱敏策略。
管理权限和数据读取权限必须分开。
举例:
销售部管理员:
- 可以给销售部员工开通 DataAgent
- 可以配置销售部数据表的可见性
- 不可以查看财务部数据
- 不可以给别人授予财务数据权限
四、Agent 使用权限
Agent 本身应该是一个资源,而不是所有人默认可用。
可以有表:
agent
- id
- name
- tenant_id
- type
- status
agent_grant
- agent_id
- subject_type: USER / ORG / ROLE
- subject_id
- permission: USE / CONFIGURE / PUBLISH / MANAGE
- granted_by
- expires_at
权限示例:
USE 可以使用 agent 提问
CONFIGURE 可以配置提示词、工具、数据源绑定
PUBLISH 可以发布给组织
MANAGE 可以授权别人使用
注意:能使用 agent,不等于 agent 能查所有数据。真正查询时还要继续过数据权限。
五、数据源权限
数据源是更底层的资源,比如 MySQL、PostgreSQL、Hive、ClickHouse、BigQuery 等。
data_source
- id
- tenant_id
- name
- type
- connection_config
- credential_mode
权限建议:
CONNECT agent 是否可以连接该数据源
QUERY 是否可以查询
METADATA 是否可以读取库表字段元数据
MANAGE 是否可以管理连接配置
真实系统里,不建议 agent 直接使用数据库超级账号。更好的做法是:
DataAgent 应用账号 + 平台权限过滤 + 数据库侧只读账号
也就是说,数据库账号本身尽量只有只读权限,平台再做细粒度权限控制。
六、表 / 字段可见性
这是 DataAgent 里最重要的一层。因为 agent 生成 SQL 前,需要知道 schema。如果用户无权看到某张表或某个字段,那么:
schema 检索时不能返回它;
prompt 里不能出现它;
SQL 校验时不能允许引用它;
执行结果里不能返回它。
推荐资源层级:
data_source
└── database / schema
└── table
└── column
└── metric / semantic field
权限表可以抽象成统一资源授权:
permission_grant
- id
- tenant_id
- subject_type: USER / ORG / ROLE
- subject_id
- resource_type: DATASOURCE / SCHEMA / TABLE / COLUMN / METRIC / AGENT
- resource_id
- action: VIEW_METADATA / SELECT / MASKED_SELECT / MANAGE_PERMISSION
- effect: ALLOW / DENY
- condition_json
- expires_at
- granted_by
字段权限示例:
销售部可以看 customers 表:
ALLOW ORG:sales TABLE:customers SELECT
销售部不能看手机号:
DENY ORG:sales COLUMN:customers.phone SELECT
销售经理可以看脱敏手机号:
ALLOW ROLE:sales_manager COLUMN:customers.phone MASKED_SELECT
建议规则:
DENY 优先于 ALLOW
字段权限覆盖表权限
用户直接授权优先于组织继承
临时授权必须有过期时间
七、行级权限
只做表字段权限是不够的。真实业务里经常是:
销售只能看自己区域客户
部门经理能看本部门
总部能看全部
这属于行级权限,建议用 policy 表表达:
row_policy
- id
- resource_type: TABLE
- resource_id
- subject_type: USER / ORG / ROLE
- subject_id
- condition_sql_template
- condition_json
例子:
region_id IN (:current_user_region_ids)
或者:
org_id IN (:current_user_org_descendant_ids)
Agent 最终生成 SQL 后,平台要自动追加权限条件:
SELECT ...
FROM orders
WHERE ...
AND orders.org_id IN (...)
不要让 LLM 自己“记得加权限条件”。权限必须由后端 SQL 编译/校验层强制注入。
八、动态 SQL Agent 的安全链路
DataAgent 的一次查询建议走这个流程:
用户提问
↓
识别当前用户、当前组织、可用 agent
↓
加载用户可见的数据目录:只返回有权限的表、字段、指标
↓
Agent 基于受限 schema 生成 SQL
↓
SQL Parser 解析 SQL AST
↓
校验引用的表 / 字段 / 函数 / join 是否授权
↓
注入行级权限、字段脱敏、limit
↓
使用只读账号执行
↓
结果二次检查与脱敏
↓
返回答案并写审计日志
重点是:权限不能只靠 prompt,必须靠 SQL AST 校验和执行前重写。
需要禁止或严格限制:
DROP / DELETE / UPDATE / INSERT / ALTER
SELECT *
跨库查询
未授权 JOIN
危险函数
无限 LIMIT
导出大结果集
查询系统表
九、字段脱敏与敏感等级
字段建议加数据分级:
PUBLIC 公开
INTERNAL 内部
CONFIDENTIAL 敏感
RESTRICTED 高敏
字段元数据:
column_metadata
- table_id
- column_name
- display_name
- data_type
- sensitivity_level
- business_description
- is_visible
- mask_type
脱敏类型:
NONE
PARTIAL_MASK 138****1234
HASH
RANGE 年龄 30-40
NULL
AGGREGATE_ONLY 只能聚合,不能明细
对 DataAgent 来说,AGGREGATE_ONLY 很有用。例如工资、收入、医疗数据等,可以允许:
SELECT department, AVG(salary)
但禁止:
SELECT employee_name, salary
十、管理员编辑“表/字段可见性”的权限
你提到管理员负责编辑表/字段可见性。这里建议把“编辑权限”也做成权限。
例如:
MANAGE_TABLE_VISIBILITY
MANAGE_COLUMN_VISIBILITY
MANAGE_ROW_POLICY
MANAGE_MASK_POLICY
GRANT_DATA_PERMISSION
REVOKE_DATA_PERMISSION
也就是说,组织管理员不一定天然能改所有数据表权限。最好让数据负责人授权。
比如:
销售部 OrgAdmin:
- 能给销售部员工开通 agent
- 能授予销售相关宽表
- 不能改财务表字段权限
数据平台 DataSteward:
- 能维护全局数据目录
- 能设置字段敏感等级
- 能审批高敏字段访问
十一、权限继承策略
组织树权限建议这样设计:
父组织授权可以向子组织继承
子组织授权不会反向影响父组织
显式 DENY 可以阻断继承
用户离开组织后,组织继承权限立即失效
举例:
集团授予所有部门使用基础 DataAgent
销售中心授予销售数据权限
华东销售部额外授予华东区域数据
某员工被 DENY 手机号字段,即使部门允许,也不能看
权限计算时可以得到一个有效权限集合:
用户直接权限
- 显式拒绝权限
- 过期权限
十二、审计与审批
真实系统必须有审计,尤其是动态 SQL agent。
审计内容:
谁在什么时候问了什么问题
使用了哪个 agent
当前组织是什么
生成了什么 SQL
实际执行 SQL 是什么
访问了哪些表和字段
返回了多少行
是否触发脱敏
是否被权限拦截
管理员改了什么权限
高敏操作建议走审批:
申请访问高敏字段
申请导出数据
申请跨部门数据查询
申请临时权限
申请 agent 绑定新数据源
审批通过后生成带过期时间的授权,而不是永久开洞。
十三、推荐的最小可落地版本
如果你现在要先做 MVP,我建议先做这些:
- 组织树:org + org_closure
- 用户组织关系:user_org_member
- 角色授权:role_assignment
- Agent 使用授权:agent_grant
- 表字段权限:permission_grant
- SQL AST 校验:禁止未授权表字段
- 只读查询执行:只允许 SELECT
- 审计日志:query_audit_log
第二阶段再加:
- 行级权限
- 字段脱敏
- 审批流
- 临时权限
- 指标语义层
- 导出权限
- 多数据源联合查询限制
十四、我建议的整体方向
这个系统最合适的设计不是纯 RBAC,而是:
RBAC + 组织继承 + 资源级 ACL + 行列级 ABAC + SQL 强制校验
简单说:
RBAC 管“你是什么角色”
组织继承管“你属于哪个部门范围”
ACL 管“你能访问哪些 agent / 表 / 字段”
ABAC 管“在什么条件下可以访问”
SQL 校验管“agent 生成的查询是否真的守规矩”
一、核心模型
你的组织关系可以这样理解:
集团 / 租户 Tenant
└── 一级组织 Org
└── 部门 Org
└── 小组 Org
└── 用户 User
建议把组织设计成树形结构,但权限计算时不要只靠 parent_id 递归,后期会慢。可以用:
org:组织表,存 id、parent_id、name、type
org_closure:组织闭包表,存 ancestor_id、descendant_id、depth
user_org_member:用户属于哪些组织
role_assignment:某人在某个组织上拥有什么角色
用户可以属于多个组织,但每次使用 agent 时,最好要求有一个 当前工作组织 active_org。否则同一个用户跨多个部门时,权限边界会非常模糊。
二、权限分层
我建议把权限拆成 5 层,不要混在一起。
这样做的好处是:管理员可以管理 agent,不代表他可以看所有数据;用户可以使用 agent,也不代表 agent 可以访问所有表。
三、组织管理员的设计
每个组织可以有管理员,但管理员也要分级。
常见角色:
TenantOwner 租户超级管理员
OrgAdmin 组织管理员
AgentAdmin Agent 管理员
DataSteward 数据权限管理员 / 数据负责人
Analyst 分析用户
Viewer 只读用户
关键点:
OrgAdmin 只能管理自己组织及子组织,不能管理父组织。
OrgAdmin 可以给子组织用户分配角色,但不能授予自己没有的权限。
AgentAdmin 可以配置 agent,但不一定能看业务数据。
DataSteward 可以配置表、字段、指标、脱敏策略。
管理权限和数据读取权限必须分开。
举例:
销售部管理员:
四、Agent 使用权限
Agent 本身应该是一个资源,而不是所有人默认可用。
可以有表:
agent
agent_grant
权限示例:
USE 可以使用 agent 提问
CONFIGURE 可以配置提示词、工具、数据源绑定
PUBLISH 可以发布给组织
MANAGE 可以授权别人使用
注意:能使用 agent,不等于 agent 能查所有数据。真正查询时还要继续过数据权限。
五、数据源权限
数据源是更底层的资源,比如 MySQL、PostgreSQL、Hive、ClickHouse、BigQuery 等。
data_source
权限建议:
CONNECT agent 是否可以连接该数据源
QUERY 是否可以查询
METADATA 是否可以读取库表字段元数据
MANAGE 是否可以管理连接配置
真实系统里,不建议 agent 直接使用数据库超级账号。更好的做法是:
DataAgent 应用账号 + 平台权限过滤 + 数据库侧只读账号
也就是说,数据库账号本身尽量只有只读权限,平台再做细粒度权限控制。
六、表 / 字段可见性
这是 DataAgent 里最重要的一层。因为 agent 生成 SQL 前,需要知道 schema。如果用户无权看到某张表或某个字段,那么:
schema 检索时不能返回它;
prompt 里不能出现它;
SQL 校验时不能允许引用它;
执行结果里不能返回它。
推荐资源层级:
data_source
└── database / schema
└── table
└── column
└── metric / semantic field
权限表可以抽象成统一资源授权:
permission_grant
字段权限示例:
销售部可以看 customers 表:
ALLOW ORG:sales TABLE:customers SELECT
销售部不能看手机号:
DENY ORG:sales COLUMN:customers.phone SELECT
销售经理可以看脱敏手机号:
ALLOW ROLE:sales_manager COLUMN:customers.phone MASKED_SELECT
建议规则:
DENY 优先于 ALLOW
字段权限覆盖表权限
用户直接授权优先于组织继承
临时授权必须有过期时间
七、行级权限
只做表字段权限是不够的。真实业务里经常是:
销售只能看自己区域客户
部门经理能看本部门
总部能看全部
这属于行级权限,建议用 policy 表表达:
row_policy
例子:
region_id IN (:current_user_region_ids)
或者:
org_id IN (:current_user_org_descendant_ids)
Agent 最终生成 SQL 后,平台要自动追加权限条件:
SELECT ...
FROM orders
WHERE ...
AND orders.org_id IN (...)
不要让 LLM 自己“记得加权限条件”。权限必须由后端 SQL 编译/校验层强制注入。
八、动态 SQL Agent 的安全链路
DataAgent 的一次查询建议走这个流程:
用户提问
↓
识别当前用户、当前组织、可用 agent
↓
加载用户可见的数据目录:只返回有权限的表、字段、指标
↓
Agent 基于受限 schema 生成 SQL
↓
SQL Parser 解析 SQL AST
↓
校验引用的表 / 字段 / 函数 / join 是否授权
↓
注入行级权限、字段脱敏、limit
↓
使用只读账号执行
↓
结果二次检查与脱敏
↓
返回答案并写审计日志
重点是:权限不能只靠 prompt,必须靠 SQL AST 校验和执行前重写。
需要禁止或严格限制:
DROP / DELETE / UPDATE / INSERT / ALTER
SELECT *
跨库查询
未授权 JOIN
危险函数
无限 LIMIT
导出大结果集
查询系统表
九、字段脱敏与敏感等级
字段建议加数据分级:
PUBLIC 公开
INTERNAL 内部
CONFIDENTIAL 敏感
RESTRICTED 高敏
字段元数据:
column_metadata
脱敏类型:
NONE
PARTIAL_MASK 138****1234
HASH
RANGE 年龄 30-40
NULL
AGGREGATE_ONLY 只能聚合,不能明细
对 DataAgent 来说,AGGREGATE_ONLY 很有用。例如工资、收入、医疗数据等,可以允许:
SELECT department, AVG(salary)
但禁止:
SELECT employee_name, salary
十、管理员编辑“表/字段可见性”的权限
你提到管理员负责编辑表/字段可见性。这里建议把“编辑权限”也做成权限。
例如:
MANAGE_TABLE_VISIBILITY
MANAGE_COLUMN_VISIBILITY
MANAGE_ROW_POLICY
MANAGE_MASK_POLICY
GRANT_DATA_PERMISSION
REVOKE_DATA_PERMISSION
也就是说,组织管理员不一定天然能改所有数据表权限。最好让数据负责人授权。
比如:
销售部 OrgAdmin:
数据平台 DataSteward:
十一、权限继承策略
组织树权限建议这样设计:
父组织授权可以向子组织继承
子组织授权不会反向影响父组织
显式 DENY 可以阻断继承
用户离开组织后,组织继承权限立即失效
举例:
集团授予所有部门使用基础 DataAgent
销售中心授予销售数据权限
华东销售部额外授予华东区域数据
某员工被 DENY 手机号字段,即使部门允许,也不能看
权限计算时可以得到一个有效权限集合:
用户直接权限
十二、审计与审批
真实系统必须有审计,尤其是动态 SQL agent。
审计内容:
谁在什么时候问了什么问题
使用了哪个 agent
当前组织是什么
生成了什么 SQL
实际执行 SQL 是什么
访问了哪些表和字段
返回了多少行
是否触发脱敏
是否被权限拦截
管理员改了什么权限
高敏操作建议走审批:
申请访问高敏字段
申请导出数据
申请跨部门数据查询
申请临时权限
申请 agent 绑定新数据源
审批通过后生成带过期时间的授权,而不是永久开洞。
十三、推荐的最小可落地版本
如果你现在要先做 MVP,我建议先做这些:
第二阶段再加:
十四、我建议的整体方向
这个系统最合适的设计不是纯 RBAC,而是:
RBAC + 组织继承 + 资源级 ACL + 行列级 ABAC + SQL 强制校验
简单说:
RBAC 管“你是什么角色”
组织继承管“你属于哪个部门范围”
ACL 管“你能访问哪些 agent / 表 / 字段”
ABAC 管“在什么条件下可以访问”
SQL 校验管“agent 生成的查询是否真的守规矩”