Skip to content

用户管理系统 #24

Description

@lzq986

一、核心模型
你的组织关系可以这样理解:
集团 / 租户 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 层,不要混在一起。

  1. 组织管理权限
  2. Agent 使用权限
  3. 数据源权限
  4. 表 / 字段 / 指标可见性权限
  5. 查询执行权限与结果权限
    这样做的好处是:管理员可以管理 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,我建议先做这些:
  1. 组织树:org + org_closure
  2. 用户组织关系:user_org_member
  3. 角色授权:role_assignment
  4. Agent 使用授权:agent_grant
  5. 表字段权限:permission_grant
  6. SQL AST 校验:禁止未授权表字段
  7. 只读查询执行:只允许 SELECT
  8. 审计日志:query_audit_log
    第二阶段再加:
  9. 行级权限
  10. 字段脱敏
  11. 审批流
  12. 临时权限
  13. 指标语义层
  14. 导出权限
  15. 多数据源联合查询限制
    十四、我建议的整体方向
    这个系统最合适的设计不是纯 RBAC,而是:
    RBAC + 组织继承 + 资源级 ACL + 行列级 ABAC + SQL 强制校验
    简单说:
    RBAC 管“你是什么角色”
    组织继承管“你属于哪个部门范围”
    ACL 管“你能访问哪些 agent / 表 / 字段”
    ABAC 管“在什么条件下可以访问”
    SQL 校验管“agent 生成的查询是否真的守规矩”

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions