17 KiB
title, date, type, status, content_status, owner, last_updated_at, last_updated_by, hash, hash_scope, belongs_to, based_on, source_refs
| title | date | type | status | content_status | owner | last_updated_at | last_updated_by | hash | hash_scope | belongs_to | based_on | source_refs | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 公司共享 Context MCP-first 身份与审计方案 v1.1 | 2026-08-10 | 设计spec | draft | discussion | Verlit | 2026-08-10 | Codex | sha256:5f9ec680322a53a9e79d9e838d74c5472ac3ca63dab25dbf1fa530e852e96199 | Markdown 正文(从一级标题开始至文件末尾)的 UTF-8 SHA-256 |
|
|
|
公司共享 Context MCP-first 身份与审计方案 v1.1
1. 版本定位
本文是 公司共享 Context 项目仓库发布方案 v1 的差量设计覆盖层,不复制或重写 v1 全文。应用顺序为:
v1 基线
+ v1.1 本文明确列出的覆盖项
= 当前目标设计
v1 中未被本文明确覆盖的内容继续有效。本文进入 confirmed 前保持草案状态;即使本文确认,也不表示代码开发、部署或真实实施已经开始。
2. 为什么不重新生成整套设计
现有 v1 已经具备以下可直接继承能力:
- 一项目一私有 Context 仓库;
- 发布网关唯一写受保护
main; main/current唯一默认读取面;discussion / confirmed内容状态与 release 事务状态分离;- Selection、Artifact、Validation、Release、Current、Readback 和 Audit 契约;
- 幂等、
base_currentCAS、原子导出、读回、撤权、备份和恢复; - Agent 角色隔离、内容面与控制面隔离;
- 项目级权限、凭据分离和追加审计原则。
需要改变的是入口、身份承载和审计强度,不是底层发布模型。因此使用差量设计能保留 v1 追溯关系,并避免出现两套近似但互相冲突的仓库、状态机和发布方案。
3. v1 到 v1.1 的偏差与覆盖
| 设计项 | v1 当前口径 | v1.1 当前目标 | 处理方式 |
|---|---|---|---|
| 产品入口 | HTTPS/CLI 优先,MCP 可选 | 全员 Agent 工作,MCP 是唯一用户业务入口 | 覆盖 D11、EXE-09、DEV-90 定位 |
| 自建 Web 页面 | 驾驶舱可选 | 不建设任何自定义业务 Web 页面 | 明确关闭驾驶舱;Agent Host 是交互界面 |
| 用户身份 | Gitea/项目身份,飞书身份后置 | 飞书登录用户映射内部主体,并绑定 Gitea 账户 | 将身份映射提升为首期必需能力 |
| 权限判断 | 项目角色与 Gitea 权限 | 内部权限数据库第一层+Gitea 项目权限第二层 | 新增双层授权决策 |
| Agent 写入 | 默认 A2;A3/A4 后续按项目开放 | Agent 可代表已登录用户提交受控发布请求 | 远端生效仍由网关服务身份完成 |
| 审计主体 | 人、Agent、服务主体分层但未强制逐调用 | 每次 MCP 调用记录 human+agent+service 行为链 | 新增强制审计中间件和事件 schema |
| 审计接口 | 事件记录与查询未固定入口 | 审计查询统一走只读 MCP;审计生成由服务端自动完成 | 禁止把审计写入暴露为普通工具 |
| MCP 传输 | 可选适配器 | 生产目标使用远程 MCP;STDIO 仅限本地开发 | 多用户入口统一 |
| 运维接口 | HTTP/CLI/MCP 混合 | 用户业务接口走 MCP;部署、备份、密钥和迁移不开放为普通 MCP | 保留独立运维控制面 |
4. 目标与非目标
4.1 目标
- 每位员工通过自己的飞书身份登录 Agent,不共享企业机器人身份代替个人身份。
- Agent 只使用用户绑定的 MCP 会话调用知识读取、构建、检查、发布和审计查询工具。
- MCP Server 在服务端完成身份验证、双层授权、策略判断、业务执行和自动审计。
- 每次操作都可解释“谁提出、哪个 Agent 代办、哪个服务身份真正执行、为什么允许、结果是什么”。
- 普通成员不需要进入自定义 Web 管理系统,也不需要处理 Git 分支、PR/MR 和凭据。
- Gitea 继续作为项目仓库、Git 历史和第二层权限边界。
4.2 非目标
- 不把飞书文档作为 v1.1 的内容来源;当前只使用飞书身份。
- 不建设独立企业管理后台、发布驾驶舱或自定义审核页面。
- 不把通用 Gitea Admin、SSH、数据库、备份、密钥、部署和历史重写能力开放给普通 Agent。
- 不把 MCP 当作权限真源、审计真源或发布事务真源。
- 不把 Skill Registry 纳入本版本;它继续保持独立版本候选。
- 不用一个共享机器人 token 将所有员工行为记录成同一主体。
5. 总体架构
flowchart LR
U[飞书用户] --> H[Agent Host]
H -->|用户绑定访问令牌| M[MCP Gateway]
M --> I[Identity Binding]
I --> P[Permission DB]
P --> GP[Gitea Permission Check]
M --> RR[Reader Tools]
M --> BB[Build/Validate Tools]
M --> PW[Publish Gateway Tools]
M --> AQ[Audit Query Tools]
RR --> C[Business Core]
BB --> C
PW --> C
C --> G[Gitea Project Repo]
G --> E[current Export/Readback]
M --> A[Append-only Audit Store]
C --> A
E --> A
MCP 是用户业务边界,不是业务核心的替代品。Selection、构建、检查、事务、Gitea 写入、current 导出和读回仍由确定性服务端模块执行。
6. 身份模型
6.1 稳定主体
| 对象 | 关键字段 | 作用 |
|---|---|---|
UserIdentity |
user_id、状态、显示名 |
内部稳定人类主体,显示名变化不改 ID |
FeishuBinding |
tenant_key、open_id、user_id、绑定状态 |
飞书登录身份映射,不保存飞书 token 明文 |
GiteaBinding |
gitea_user_id、username、user_id、绑定状态 |
第二层账户映射 |
ProjectGrant |
user_id、project_id、角色、动作、有效期 |
内部权限数据库第一层授权 |
AgentSession |
session_id、agent_id、user_id、client、expiry |
记录哪个 Agent 代表哪个用户 |
ServiceIdentity |
service_id、project scope、action scope |
网关、导出、读取、审计等服务身份 |
6.2 登录与会话流程
- 用户在 Agent Host 发起飞书登录。
- 登录完成后,身份服务使用飞书稳定标识查找或创建内部
user_id。 - MCP 连接获得用户绑定、短期、不可转交的访问令牌。
- MCP Server 验证 issuer、audience、resource、expiry、client、subject 和 scope。
- 服务端从令牌解析
user_id,再加载 AgentSession、ProjectGrant 和账户绑定。 - 工具参数中的
user_id、role、project grant 和 review mode 均不具备权威性。 - 会话过期、用户停用、绑定失效或权限版本变化后,新调用立即失败。
飞书 token、MCP access token 和 Gitea token 互不透传。MCP Server 调用 Gitea 时使用自己的项目级凭据或受控 Gitea 适配器。
7. 双层权限
Allow = AuthenticatedFeishuUser
∩ ActiveInternalIdentity
∩ AgentSession
∩ InternalProjectGrant
∩ ActionPolicy
∩ ResourceScope
∩ Content/SensitivityPolicy
∩ GiteaProjectPermission
∩ HumanConfirmationWhenRequired
7.1 第一层:内部权限数据库
判断用户是否属于业务线和项目、承担什么角色、可以执行哪些 MCP action、是否到期或已撤权。它是用户业务权限的第一层真源。
7.2 第二层:Gitea 项目权限
读取前复核用户绑定的 Gitea 账户是否仍具备目标项目读取资格。发布时复核用户仍是目标项目成员并具有 publisher 业务角色;真正写 main 的仍是项目级 publish-gateway 服务身份。
Gitea 不需要允许普通用户直接写 main。commit、release 和审计记录必须保留 human/agent/service 三主体归因,不能把服务账号误记为业务发起人。
7.3 失败策略
- 任一层拒绝均 fail closed;不能改用共享账号或更高权限 MCP。
- 内部数据库与 Gitea 权限不一致时,按拒绝处理并记录
permission_mismatch。 - 用户从项目撤权后,MCP 读取、搜索、构建和发布未来访问同时失效。
- 不能先跨项目检索后在模型端过滤;必须先服务端鉴权再查询。
8. MCP 工具面
8.1 身份与项目
get_my_identitylist_authorized_projectsget_my_project_roles
8.2 Current 读取
get_current_manifestread_artifactsearch_currentverify_release_hash
8.3 构建与预览
create_selectionbuild_previewvalidate_release_requestpreview_release_diff
这些工具不产生远端状态,可以在用户授权来源范围内由 Agent 执行。
8.4 发布
submit_discussion_releasesubmit_confirmed_releaseget_release_statuscancel_precommit_release
提交工具必须绑定用户、项目、action、candidate hash、base_current、AgentSession 和精确人类确认。MCP 只提交受控请求;发布网关读取服务端策略并执行事务。
8.5 审计查询
list_my_actionsget_action_detailtrace_releasetrace_correlationlist_project_audit_events(仅项目维护者/审计角色)verify_audit_event
8.6 明确不暴露
- 审计写入、修改或删除;
- Gitea 全局管理、直接 Git push、历史重写;
- SSH shell、生产部署、服务重启;
- 数据库迁移和任意 SQL;
- 备份删除/恢复;
- 密钥读取、导出和轮换;
- 权限数据库直接写入;
- 审核策略和动作开关修改。
上述能力属于运维或治理控制面,不能因为“全员 Agent”而成为普通 MCP 工具。
9. Agent 能力与人类确认
| 能力 | v1.1 默认 | 人类要求 |
|---|---|---|
| A1 current 读取/搜索 | 允许 | 登录用户已有项目读取权 |
| A2 selection、构建、检查、diff | 允许 | 来源范围由用户明确选择或授权 |
| A3 discussion 发布请求 | 允许受控调用 | 每次绑定目标、hash、项目和确认 |
| A4 confirmed/恢复请求 | 允许调用网关,不允许直接生效 | 精确确认;内容审核和高风险授权继续分开 |
| A5 成员、密钥、删除、策略、全局管理 | 禁止 | 不向普通 Agent 暴露 |
Agent 不是发布凭据持有者。Agent 的作用是代表已登录用户调用受控 MCP 工具,不能自授角色、切换用户或改变确认内容。
10. 强制审计
10.1 三主体行为链
每次操作必须分别记录:
human_actor:发起操作的内部用户和飞书绑定;agent_actor:Agent、Host、client、session 和运行配置;service_actor:实际执行读取、网关、Gitea、导出或审计写入的服务身份。
10.2 审计事件字段
event_id: "evt_<uuid>"
event_type: "mcp.tool.completed"
occurred_at: "<RFC3339>"
correlation_id: "<id>"
session_id: "<agent-session>"
human_actor:
user_id: "human:<id>"
feishu_tenant: "<tenant>"
feishu_open_id_hash: "sha256:<hash>"
agent_actor:
agent_id: "agent:<id>"
mcp_client_id: "<client>"
runtime_version: "<version>"
service_actor:
service_id: "service:<id>"
business_line_id: "<stable-id>"
project_id: "<project>"
tool_name: "<mcp-tool>"
action: "read | search | build | validate | publish | cancel | audit_read"
resource:
type: "<type>"
id: "<id>"
request_hash: "sha256:<hash>"
policy_version: "<version>"
authorization_result: "allowed | denied"
confirmation_id: "<nullable>"
release_id: "<nullable>"
remote_version: "<nullable commit/hash>"
result: "completed | denied | failed"
error_code: "<nullable>"
details_hash: "sha256:<hash>"
正文、原始 Prompt、token、cookie、私钥、密码和完整敏感参数不进入审计;只记录资源标识、脱敏摘要和 hash。
10.3 写入机制
审计不是 Agent 主动调用的工具。MCP Gateway 中间件自动执行:
验证连接身份
→ 写 request_received
→ 双层权限和策略判断
→ 写 allowed/denied
→ 执行业务动作
→ postcheck/readback
→ 写 completed/failed
→ 返回 Agent
- 审计存储使用 append-only 接口;普通业务模块无 update/delete 权限。
- 发布、权限、确认、策略和其他写操作在审计不可持久化时 fail closed。
- 读取操作先写可靠本地队列;队列也不可用时拒绝执行,不能产生无审计读取。
- 审计事件写入与业务状态使用 outbox/等价机制关联,避免“动作成功但事件丢失”。
- 审计查询可以通过 MCP,审计写入永不作为普通 MCP tool 暴露。
11. 无自建 Web 页面
v1.1 不建设发布驾驶舱、权限管理后台、审计后台或自定义登录页:
- 日常交互界面:现有 Agent Host;
- 用户身份认证:飞书现有授权/登录页面;
- 敏感工具确认:Agent Host 的确认交互;
- 知识读取、构建、发布和审计查询:MCP;
- 少量技术管理:受控配置、运维任务和 Gitea 自带管理员界面。
“无自建 Web 页面”不表示没有 HTTP。公司全员访问使用远程 MCP transport;开发阶段可使用 STDIO。传输层、OAuth 回调和 Gitea 自带页面不属于本项目自建业务 Web 页面。
12. 运维控制面例外
以下流程不能纳入普通用户 MCP 工具,但仍必须审计:
- 部署、升级、服务启停和数据库迁移;
- 备份、完整恢复和灾难演练;
- 密钥生成、读取、轮换和吊销;
- Gitea 全局管理员动作;
- 审计保留策略和事件销毁;
- 权限规则、动作开关和审核策略变更;
- 敏感历史重写和事故处置。
它们走独立运维/治理任务,产生同一 audit schema 的 operation 事件;普通 Agent 只能查询授权范围内的结果。
13. 保持不变的 v1 原则
- 一项目一私有 Context 仓库;
- 私人来源到企业 current 单向明确发布;
- 发布网关唯一写
main; main/current唯一默认读取面;- 内容状态和 release 状态分离;
base_currentCAS、幂等、原子切换和发布后读回;- 试点审核
forced_off; - 恢复旧内容必须形成新 release;
- 未授权项目、历史、staging、私人来源和控制面不进入 Agent Context;
- 飞书只承担身份,不在本版本承担内容来源、审批平台或知识库真源。
14. 实施与迁移原则
- 先实现身份绑定、MCP Gateway 骨架和强制审计,再开放业务工具。
- 先开放
get_my_identity和只读 current 工具,验证逐用户身份和双层权限。 - 再开放构建、验证和 diff 等无远端状态工具。
- 最后开放发布请求工具;每次写请求需要精确人类确认、网关事务和读回。
- 不提供从 MCP 失败自动回退到共享 CLI、通用 Gitea token 或直接 shell 的路径。
- 不要求普通成员迁移到自建 Web 系统;Agent Host 是唯一日常入口。
15. 验收标准
- 两名不同飞书用户通过同一 Agent Host 调用工具时,审计主体、项目列表和权限结果不同且正确。
- 用户不能通过工具参数冒充其他
user_id、role、project grant 或 AgentSession。 - 内部权限允许但 Gitea 权限拒绝、以及相反场景,均 fail closed 并产生
permission_mismatch。 - 每次 read/search/build/validate/publish/cancel/denied 都能查到 human+agent+service 行为链。
- 发布 commit 使用网关服务身份执行,但可追溯到精确用户确认和 AgentSession。
- 停用用户、解除飞书绑定、移除项目授权或撤销 Gitea 成员后,未来 MCP 访问立即失败。
- 普通用户无法调用审计写入/删除、权限写入、Gitea Admin、SSH、部署、备份和密钥工具。
- MCP 不可用时不会回退到更高权限通道。
- 不建设自定义业务 Web 页面,真实成员仍能通过 Agent 完成身份确认、读取、构建、发布和查询自己的审计记录。
- 原 v1 的唯一 current、CAS、幂等、原子切换、状态语义和读回测试继续全部通过。
16. 进入代码开发前仍需确认
以下是 C1 技术选择,不影响本文架构成立:
- 全员使用的 Agent Host 与其飞书登录集成方式;
- MCP Server 编程语言、官方/兼容 SDK 和最低协议版本;
- 远程 MCP transport、OAuth/身份代理和 token 生命周期;
- 身份权限数据库与 audit store 的具体技术产品;
- Agent Host 对 A3/A4 工具确认的交互能力;
- 审计保留期限、查询范围、脱敏规则和安全责任人;
- Gitea 权限复核使用 API、缓存和失效机制;
- 断网、飞书不可用、MCP 不可用时允许的只读降级策略。
这些事项确认前可以继续完善设计,但不能创建真实身份绑定、远程 MCP、权限数据库或审计生产资源。