Files
AI-Secretary/docs/contracts/安全权限日志约定.md
T
2026-06-22 17:30:59 +08:00

137 lines
8.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 安全权限日志约定
本文件是第一版安全、权限、日志脱敏、回调验签、幂等和访问边界的唯一事实源。涉及这些规则时,代码、接口、测试和 Review 结论应以本文件为准。
本文件不展开完整 RBAC、安全合规体系或审计平台,只卡住最小闭环里 AI 和后端最容易写错的硬规则。
## 1. 核心底线
1. AI 只能生成草稿、追问或回复,不能绕过人工确认直接创建事项、创建提醒或发送通知。
2. 业务权限以平台 `users.role`、启用状态和必要白名单为准;飞书身份只用于登录认证、身份匹配和操作人追溯。
3. 权限必须在 DRF permission class 和 service 层同时校验,不能只靠前端隐藏按钮或飞书卡片按钮。
4. 飞书登录回调、事件回调和卡片回调必须验签;验签失败不得执行业务动作。
5. 通知、飞书事件、卡片点击、草稿转换和提醒调度必须幂等。
6. 密钥、token、完整手机号、完整邮箱、一次性操作 token 和回调验签密钥不得进入普通日志。
7. 权限失败、验签失败、通知失败、回调失败、AI 解析失败、模型失败、未授权机器人访问和调度失败必须可复盘。
## 2. 身份边界
| 身份来源 | 可用于 | 不可用于 |
| --- | --- | --- |
| 平台用户 `users` | 登录态、角色、权限、数据范围 | 自然语言称呼解析 |
| `person_mappings` | 称呼、别名、飞书身份、第一批试用人员映射 | 替代平台登录和角色权限 |
| 飞书 open_id / user_id / union_id | 登录认证、消息接收人、回调操作人追溯 | 直接绕过平台权限 |
| AI 对话记忆表 | 上下文恢复、追问、草稿修订辅助 | 替代正式业务表、权限判断和人工确认 |
同一个真实人员如果可以登录平台,应在 `person_mappings.user_id` 绑定对应 `users.id`。飞书身份同步失败时写入 `failure_records`,不得静默降级成“默认有权限”。
## 3. 角色权限
| 动作 | 老板 | 程经理 | 普通员工 | 管理员 / AI 团队 |
| --- | --- | --- | --- | --- |
| 飞书登录 / 平台登录 | 可用 | 可用 | 可用 | 可用 |
| 飞书机器人私聊 AI 秘书 | 可用 | 不开放 | 不开放 | 仅测试或排查 |
| 确认、取消、补充自己的 AI 草稿 | 可用 | 仅待自己确认的复杂事项 | 不开放 | 仅排查,不代替业务确认 |
| 创建事项 | 可用 | 可用 | 不开放给别人 | 可测试或维护 |
| 创建自己的提醒 | 可用 | 可用 | 可用 | 可用 |
| 给别人创建提醒 | 可用 | 可用 | 不开放 | 可测试或维护 |
| 反馈事项或提醒 | 仅自己相关 | 仅自己相关 | 仅自己作为接收人 | 可测试,不代替业务反馈 |
| 查看失败记录原始信息 | 必要业务摘要 | 必要业务摘要 | 不开放 | 可用 |
| 维护人员映射和提示词版本 | 不开放 | 不开放 | 不开放 | 可用 |
普通员工给别人创建事项或提醒、非接收人反馈、非老板使用机器人入口,都必须拒绝并记录。
## 4. 人工确认边界
1. `task` / `reminder` AI 输出必须先生成可确认草稿。
2. 草稿确认前必须校验发起人、草稿状态、缺失字段、接收人映射和当前有效卡片。
3. `note` / `unknown` / `qa` / `realtime_qa` / `need_more_info` / `unsupported` 不得进入事项、提醒或通知闭环。
4. 复杂事项在老板确认后创建 `tasks.status=pending_manager_confirm` 的事项壳,由程经理补齐接收人、内容并触发通知。
5. 草稿、任务、提醒、通知的状态流转必须走 service 层;非法跳转返回 `state_conflict`
## 5. 飞书安全和幂等
1. 飞书回调必须先验签,再解析和执行业务动作。
2. `feishu_events.event_id` 应尽量唯一;没有稳定 `event_id` 时,用 `operator_open_id + action_value + notification_id + target_id` 生成 `idempotency_key` 并唯一约束。
3. 同一飞书事件只处理一次;重复事件只返回既有处理结果,不重复创建草稿、事项、提醒、反馈或通知。
4. 草稿确认类卡片必须匹配 `ai_drafts.active_card_notification_id`
5. 旧卡片、失效卡片、已取消草稿、已替代草稿、已过期草稿和已转换草稿的回调只记录 `feishu_events`,返回“该卡片已失效,请以最新卡片或平台详情为准”,不得写业务对象。
6. 接收人反馈类卡片重复点击必须幂等;是否覆盖最新反馈状态由 feedback service 明确处理,但每次有效点击都应可追溯。
7. 程经理待确认提醒在飞书里只跳转平台,不通过机器人对话分发事项。
## 6. 通知和操作 token
1. `notifications.idempotency_key` 必须按 `purpose` 生成并设置唯一约束。
2. 草稿确认卡片、程经理确认提醒、事项通知、提醒触发通知和补发通知应使用不同 `purpose`
3. 平台反馈页或一次性操作链接只能保存 token hash,例如 `action_token_hash`,不得保存明文 token。
4. 卡片或操作链接过期时写 `expires_at`,被新卡片替代或业务取消时写 `invalidated_at`
5. `expires_at``invalidated_at` 已生效后,回调不得继续确认、转换、通知或反馈,只能记录事件和提示失效。
## 7. 日志脱敏
普通应用日志、`operation_logs.summary``operation_logs.metadata``failure_records.raw_error` 和列表页摘要不得包含:
1. 阿里百炼 API Key。
2. 飞书 App Secret、tenant access token、user access token。
3. 飞书回调验签密钥。
4. OAuth code 和 OAuth state 的完整值。
5. 平台反馈页一次性操作 token 明文。
6. 完整手机号和完整邮箱。
7. 数据库账号密码和连接串密码。
8. 飞书原始 payload 中的敏感字段。
9. 模型 prompt 中的敏感全文或过长背景库全文。
手机号和邮箱在普通日志中只能脱敏展示。密钥、token、OAuth code/state、一次性操作 token 原文只能存在请求处理内存或安全配置中,不得落普通业务表。
## 8. 访问范围
| 信息 | 普通员工 | 老板 | 程经理 | 管理员 / AI 团队 |
| --- | --- | --- | --- | --- |
| 自己相关事项、提醒、反馈 | 可看摘要 | 可看相关记录 | 可看管理范围 | 可排查 |
| 失败记录列表 | 不可见 | 必要摘要 | 必要摘要 | 可见 |
| `model_call_logs` 原始请求和响应 | 不可见 | 不可见 | 不可见 | 可排查 |
| `feishu_events.raw_payload` | 不可见 | 不可见 | 不可见 | 可排查 |
| 完整手机号、邮箱 | 默认不可见 | 默认脱敏 | 默认脱敏 | 维护页按需可见 |
| 操作 token 明文 | 不可见 | 不可见 | 不可见 | 不可见 |
模型日志和飞书原始 payload 可以为排查保存必要结构,但必须通过接口权限和 Admin 权限限制访问,普通列表页默认只展示摘要。
## 9. 必须写失败记录的情况
1. AI 输出无法解析或不符合 schema。
2. 百炼或模型网关重试后仍失败。
3. PostgreSQL AI 记忆、消息或 BotContext 保存/读取失败。
4. 草稿确认后转换事项或提醒失败。
5. 缺少人员映射且阻断确认。
6. 普通员工越权创建事项或提醒。
7. 非接收人提交反馈。
8. 飞书登录失败、验签失败、事件格式异常或回调处理失败。
9. 飞书通知发送失败或补发失败。
10. 定时提醒触发失败或重复触发被跳过需要留痕。
11. 有问题反馈缺少原因。
如果 AI 解析失败时无法创建最小 `parse_failed` 草稿,`failure_records.target_type` 可以使用 `model_call_log` 并关联对应模型调用日志。
## 10. 必须测试的真实约束
每个 plan 完成前,必须说明新增或修改了哪些测试,以及这些测试覆盖了哪些 spec / contract 约定。第一版至少用测试卡住:
1. 权限:普通员工不能给别人创建事项或提醒。
2. 权限:非接收人不能反馈事项或提醒。
3. AI:AI 输出只能生成草稿,不能绕过人工确认直接执行。
4. AI`note` / `unknown` 不创建事项、提醒或通知。
5. 状态:草稿、事项、提醒不能非法跳转。
6. 飞书:回调必须验签,重复事件和重复点击必须幂等。
7. 飞书:旧卡片或失效卡片只记录事件,不写业务对象。
8. 定时:同一个提醒、同一触发时间、同一接收人、同一渠道不能重复触发通知。
9. 事务:通知失败时不能留下被误判为已通知的业务状态。
10. 日志:密钥、token、完整手机号、完整邮箱和一次性操作 token 不进普通日志。
## 11. 第一版不做
1. 不做复杂组织架构和多级 RBAC。
2. 不做独立审计平台。
3. 不做复杂安全合规体系。
4. 不让 AI 自动操作交易系统、公司历史数据库、后台管理系统或其他外部业务系统。
5. 不把飞书机器人开放为程经理或普通员工通用派活入口。