卓卓安Claw项目方案库
展示首页/方案库/架构与实现
架构与实现

卓安Claw 用户身份与权限上下文 v1.0

约 6 分钟·卓安Claw · 2026.11
本页目录
  1. 0. 一句话
  2. 1. 登录链路
  3. 2. 身份数据模型
  4. 3. 注入给 Agent 的身份块
  5. 4. 权限模型
  6. 5. 代码落点
  7. 6. 登录后 Agent 的实际表现
  8. 7. 安全边界
  9. 8. 后续

日期:2026-11-13
问题:用户登录后,Agent 怎么知道“我是谁、在哪个省/哪家律所、什么角色、什么数据范围、什么权限”?
结论:身份不靠用户告诉 Agent,也不靠前端传参;服务端每次请求从签名会话解析用户,再把身份/权限块注入 Agent 系统提示,工具再做服务端校验。

0. 一句话

Agent 不是“一个公共聊天机器人”,而是当前登录用户的办案副驾:它知道服务对象的姓名、角色、律所、省份、数据范围与权限,并且只在这个范围内回答和调用工具。

1. 登录链路

企业微信 OIDC / 本地账号登录
  → 服务端校验
  → 签发 zhuoan_session(签名 token,含 uid)
  → 浏览器持有 HttpOnly Cookie
  → 每次 /message 请求
  → get_session_user() 从 token 解析 uid,查 zhuoan_user
  → get_zhuoan_role() 得到角色
  → 组装身份块 + 案件块
  → Agent 系统提示
  → Agent 工具按同一身份做权限校验

关键点:

  • 不以“前端传 role/user”为准。前端只传 case_id、消息文本;身份由服务端从 Cookie 解析。
  • 不是登录时把身份写死在 Agent 里。每次请求重新解析,角色/分所/权限改了立即生效。
  • 演示模式:没有真实会话时保留 zhuoan_role cookie 演示角色,但身份块会明确标注“演示角色,非真实登录”。

2. 身份数据模型

zhuoan_user 现有字段(本次新增 province):

字段 用途
id 用户 ID
username 登录名
display_name 姓名/称呼
wecom_userid 企业微信 userid
role 客服/客户经理/谈案律师/承办律师/管理者
branch 所属律所/分所(成都总所、重庆分所…)
province 省份/区域(可显式填;不填按分所映射)
department 部门
data_scope 本人/部门/分所/全所/案件团队
is_admin 是否管理员
status active/disabled

省份映射(未显式填 province 时):

分所 省份
成都总所 四川
深圳分所 广东
昆明分所 云南
重庆分所 重庆
北京分所 北京
西安分所 陕西
西宁分所 青海

3. 注入给 Agent 的身份块

服务端生成类似下面的系统提示片段(不是用户消息,前端不可伪造):

## 当前用户身份与权限(服务端注入,前端不可伪造)
- 姓名/称呼:李然
- 账号:liran(企业微信:liran)
- 角色:承办律师
- 所属律所:成都总所
- 省份/区域:四川
- 部门:刑事部
- 数据范围:分所(本分所案件)
- 权限:查看案件、查看案卷材料、编辑清单/记录、推进节点/结案归档、使用 Agent、客户与线索、知识库
- 身份规则:
  - 你就是卓安Claw,服务对象是当前用户;不要冒充用户本人、律师或审批人。
  - 只能基于当前用户的数据范围检索、引用和回答;不得跨省/跨所读取未授权案件。
  - 用户问其他省份/分所的数据时,先说明当前范围;需要跨所时提示走平台/管理员。
  - 写操作只能生成“待律师确认”动作,不能直接改案卷、清单、节点或财务。
  - C 类案卷只留在本地/私有云;不得把全文发送外部模型,引用要带文书名+页码。
  - 不确定权限或数据是否存在时,先调用工具校验,不要猜。

案件会话再追加“当前案件上下文(编号/名称/节点/清单/最近记录)”,两个块用空行拼接。

4. 权限模型

角色权限在 channel/web/api/zhuoan.py 的 ROLE_PERMISSIONS 中定义,身份块只展示当前角色为 True 的权限:

权限 含义
case:view 查看案件
case:file 查看案卷材料
case:edit 编辑清单/记录
case:advance 推进节点/结案归档
agent:run 使用 Agent
customer:view 客户与线索
knowledge:view 知识库
cockpit:view 全所驾驶舱
ops:view 经营分析

数据范围独立于角色:

  • 本人:仅本人负责/参与的案件
  • 部门:本部门案件
  • 分所:本分所案件
  • 全所:所有分所案件
  • 案件团队:仅案件团队成员可见的案件

Agent 工具(zhuoan_case、search_docs、search_knowledge)继续用同一套 can_access_case / _can 服务端校验;身份块只负责“让模型知道边界”,不代替工具校验。

5. 代码落点

文件 作用
channel/web/api/zhuoan_auth.py 会话、登录、用户表;新增 province 列与 OIDC 字段
channel/web/api/zhuoan_identity.py 身份 payload、省份映射、权限标签、身份块生成
channel/web/core/channel.py 每次 /message 解析会话,注入 zhuoan_identity_context
bridge/agent_bridge.py 把身份块 + 案件块拼成 extra_system_suffix
agent/tools/zhuoan_case/zhuoan_case.py 新增 whoami,返回当前身份/省份/权限;写操作仍只提议
channel/web/api/zhuoan.py /api/zhuoan/me 增加 identity/permissions

6. 登录后 Agent 的实际表现

用户问:

我是谁?我在哪个省?我能看哪些案件?

Agent 应能回答:

  • 姓名/账号/角色/所属律所/省份/部门;
  • 数据范围(如“仅成都分所案件”);
  • 可用权限(如“可查看案卷材料,但不能看经营分析”);
  • 不知道时调用 zhuoan_case(method=whoami) 校验,而不是猜。

用户问其他省份/分所的案件:

帮我看看重庆分所那个职务侵占案的卷宗。

Agent 应回答:当前账号数据范围是成都分所,无法读取重庆分所案卷;如需跨所,走平台/管理员授权,而不是假装能看到。

7. 安全边界

  • 身份块由服务端生成,前端不能传“我是管理者”。
  • 会话 token 签名、HttpOnly;角色/分所改动下一次请求生效。
  • Agent 工具按同一用户/角色校验;模型说“我是管理员”不改变权限。
  • C 类案卷不出本地/私有云;外部模型只拿必要片段。
  • 写操作只生成待确认动作,律师确认后才落库并写审计。
  • 演示模式明确标注“非真实登录”,避免把演示角色当真实授权。

8. 后续

  1. 企业微信 OIDC 真实凭证联调,把 wecom_userid → 账号映射跑通。
  2. 管理后台增加“省份”字段与数据范围可视化;分所管理员只能管本所账号。
  3. Agent 回答里显示“当前身份”小卡(姓名/角色/分所/省份),让用户可核对。
  4. 平台层身份:平台管理员/平台运营/连锁总部与律所角色分开,平台不继承律所案卷权限。
  5. 增加“身份切换审计”:谁在什么时候以什么身份看了什么。