Files
test-doc/Gitea知识库/公司共享 Context MCP-first 身份与审计方案 v1.1.md
T
2026-08-11 15:40:11 +08:00

384 lines
17 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.
---
title: 公司共享 Context MCP-first 身份与审计方案 v1.1
date: 2026-08-10
type: 设计spec
status: draft
content_status: discussion
owner: Verlit
last_updated_at: 2026-08-10
last_updated_by: Codex
hash: sha256:5f9ec680322a53a9e79d9e838d74c5472ac3ca63dab25dbf1fa530e852e96199
hash_scope: Markdown 正文(从一级标题开始至文件末尾)的 UTF-8 SHA-256
belongs_to:
- "[[3-业务线/Gitea知识库/_context|Gitea知识库]]"
based_on:
- "[[3-业务线/Gitea知识库/公司共享 Context 项目仓库发布方案 v1|公司共享 Context 项目仓库发布方案 v1]]"
source_refs:
- "0-收集箱/临时待归属/2026-08-03-公司共享Context发布与AI协同框架/2026-08-03-05-MCP工具路由与外部系统连接.md"
- "0-收集箱/临时待归属/2026-08-03-公司共享Context发布与AI协同框架/2026-08-03-06-分层身份权限与凭据模型.md"
- "0-收集箱/临时待归属/2026-08-03-公司共享Context发布与AI协同框架/2026-08-03-08-AI权限控制与人机协同.md"
- "0-收集箱/临时待归属/2026-08-03-公司共享Context发布与AI协同框架/2026-08-03-09-安全隐私审计与事故响应.md"
- "https://modelcontextprotocol.io/docs/2026-07-28/learn/architecture"
- "https://modelcontextprotocol.io/specification/2025-11-25/basic/index"
---
# 公司共享 Context MCP-first 身份与审计方案 v1.1
## 1. 版本定位
本文是 `公司共享 Context 项目仓库发布方案 v1` 的差量设计覆盖层,不复制或重写 v1 全文。应用顺序为:
```text
v1 基线
+ v1.1 本文明确列出的覆盖项
= 当前目标设计
```
v1 中未被本文明确覆盖的内容继续有效。本文进入 `confirmed` 前保持草案状态;即使本文确认,也不表示代码开发、部署或真实实施已经开始。
## 2. 为什么不重新生成整套设计
现有 v1 已经具备以下可直接继承能力:
- 一项目一私有 Context 仓库;
- 发布网关唯一写受保护 `main`
- `main/current` 唯一默认读取面;
- `discussion / confirmed` 内容状态与 release 事务状态分离;
- Selection、Artifact、Validation、Release、Current、Readback 和 Audit 契约;
- 幂等、`base_current` CAS、原子导出、读回、撤权、备份和恢复;
- 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 写入 | 默认 A2A3/A4 后续按项目开放 | Agent 可代表已登录用户提交受控发布请求 | 远端生效仍由网关服务身份完成 |
| 审计主体 | 人、Agent、服务主体分层但未强制逐调用 | 每次 MCP 调用记录 humanagentservice 行为链 | 新增强制审计中间件和事件 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. 总体架构
```mermaid
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 登录与会话流程
1. 用户在 Agent Host 发起飞书登录。
2. 登录完成后,身份服务使用飞书稳定标识查找或创建内部 `user_id`
3. MCP 连接获得用户绑定、短期、不可转交的访问令牌。
4. MCP Server 验证 issuer、audience、resource、expiry、client、subject 和 scope。
5. 服务端从令牌解析 `user_id`,再加载 AgentSession、ProjectGrant 和账户绑定。
6. 工具参数中的 `user_id`、role、project grant 和 review mode 均不具备权威性。
7. 会话过期、用户停用、绑定失效或权限版本变化后,新调用立即失败。
飞书 token、MCP access token 和 Gitea token 互不透传。MCP Server 调用 Gitea 时使用自己的项目级凭据或受控 Gitea 适配器。
## 7. 双层权限
```text
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_identity`
- `list_authorized_projects`
- `get_my_project_roles`
### 8.2 Current 读取
- `get_current_manifest`
- `read_artifact`
- `search_current`
- `verify_release_hash`
### 8.3 构建与预览
- `create_selection`
- `build_preview`
- `validate_release_request`
- `preview_release_diff`
这些工具不产生远端状态,可以在用户授权来源范围内由 Agent 执行。
### 8.4 发布
- `submit_discussion_release`
- `submit_confirmed_release`
- `get_release_status`
- `cancel_precommit_release`
提交工具必须绑定用户、项目、action、candidate hash、`base_current`、AgentSession 和精确人类确认。MCP 只提交受控请求;发布网关读取服务端策略并执行事务。
### 8.5 审计查询
- `list_my_actions`
- `get_action_detail`
- `trace_release`
- `trace_correlation`
- `list_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 审计事件字段
```yaml
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 中间件自动执行:
```text
验证连接身份
→ 写 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_current` CAS、幂等、原子切换和发布后读回;
- 试点审核 `forced_off`
- 恢复旧内容必须形成新 release;
- 未授权项目、历史、staging、私人来源和控制面不进入 Agent Context
- 飞书只承担身份,不在本版本承担内容来源、审批平台或知识库真源。
## 14. 实施与迁移原则
1. 先实现身份绑定、MCP Gateway 骨架和强制审计,再开放业务工具。
2. 先开放 `get_my_identity` 和只读 current 工具,验证逐用户身份和双层权限。
3. 再开放构建、验证和 diff 等无远端状态工具。
4. 最后开放发布请求工具;每次写请求需要精确人类确认、网关事务和读回。
5. 不提供从 MCP 失败自动回退到共享 CLI、通用 Gitea token 或直接 shell 的路径。
6. 不要求普通成员迁移到自建 Web 系统;Agent Host 是唯一日常入口。
## 15. 验收标准
- 两名不同飞书用户通过同一 Agent Host 调用工具时,审计主体、项目列表和权限结果不同且正确。
- 用户不能通过工具参数冒充其他 `user_id`、role、project grant 或 AgentSession。
- 内部权限允许但 Gitea 权限拒绝、以及相反场景,均 fail closed 并产生 `permission_mismatch`
- 每次 read/search/build/validate/publish/cancel/denied 都能查到 humanagentservice 行为链。
- 发布 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、权限数据库或审计生产资源。