Skip to content

fix(mcp): 修复 Data MCP 身份注入链路 - #917

Open
yousay123 wants to merge 7 commits into
deepcoldy:masterfrom
yousay123:barry/data-mcp-identity-origin-merge
Open

fix(mcp): 修复 Data MCP 身份注入链路#917
yousay123 wants to merge 7 commits into
deepcoldy:masterfrom
yousay123:barry/data-mcp-identity-origin-merge

Conversation

@yousay123

Copy link
Copy Markdown

改动内容

  • 增加 trusted turn / trusted caller 链路,避免 Data MCP 身份通过模型可见参数传入。
  • 增加 trusted stdio proxy、metadata query 入口和 Data MCP 只读查询链路支持。
  • 更新 Codex adapter、worker、daemon 相关透传逻辑,并补充单测覆盖。

为什么改

Data MCP 查询需要绑定当前真实用户身份,但身份字段不应暴露给模型,也不能依赖模型传参。该改动把身份注入收敛到 Botmux 可信 turn / gateway 链路,降低伪造和串用风险。

影响范围

  • 影响 Codex / Codex App 会话中的 MCP 身份注入与元数据查询路径。
  • 涉及 worker、daemon、CLI adapter、metadata query、trusted turn store 等公共路径。
  • 不涉及授权写操作、删除类操作或发版流程。

验证

  • pnpm build
  • pnpm test -- trusted-turn-store trusted-mcp trusted-caller metadata-query

备注

  • PR 来自 fork 分支:yousay123:barry/data-mcp-identity-origin-merge
  • Allow edits by maintainers 保持勾选,方便维护者直接调整。

@yousay123
yousay123 requested a review from deepcoldy as a code owner August 18, 2026 12:10
@deepcoldy

Copy link
Copy Markdown
Owner

感谢这个 PR,把 Data MCP 的身份从「模型可见参数」收敛到 Botmux 可信 turn 通道、用飞书盖章的 open_id/union_id 做信任根、并做 fail-closed,这个方向是对的,代码组织和测试覆盖也很用心(本地 pnpm build 通过,相关 6 个测试文件 520/520 全绿,merge-tree 对 master 无冲突)。

不过在自动化复核里发现 3 个建议在合入前先解决的问题(附实际验证):

1)可信身份文件在同一 OS 用户下可被模型进程改写(最关键)
trusted-turns/<sessionId>.json 用 0600 保存,但它只隔离「其他 Unix 用户」,隔离不了同 UID 的 Codex/shell 进程。Codex 默认带 --dangerously-bypass-approvals-and-sandbox,模型知道 SESSION_DATA_DIR + BOTMUX_SESSION_ID 后即可直接覆盖该文件。运行时探针复现:写入一个同 UID 伪造文件(union_id=on_FORGED),proxy 会正确删除模型内联传入的身份字段,但会忠实注入文件里的伪造 union_id——即 per-user 权限/审计身份可被冒充。建议:可信身份保留在 daemon/worker 宿主内存,由宿主侧 MCP gateway 在调用时注入,不要落到模型同 UID 可写的文件。

2)ksher 专属 MCP 被无条件注入进公共 Codex 适配器
src/adapters/cli/codex.tsmcp_servers.platform-ksher-agent-data-mcp(指向 ~/.config/ksher-agent-data-mcp/launcher.sh)硬编码进了「每一个 Codex TUI 会话」,没有任何 config gate / per-bot opt-in。由于 botmux 是公共 npm 包,非 ksher 环境每次开 Codex 都会多出一个指向不存在 launcher 的坏 MCP server,并可能覆盖用户自带的同名配置。建议:改为显式 per-bot opt-in,租户私有的 launcher 路径/工具名移出公共适配器。

3)metadata query 的 SQL guard 可绕过
validateMetadataSql 对不带反引号的 url('...') / remote(...) 能拦下,但加反引号的表函数会绕过——运行时复现:... a JOIN \url`('http://.../','JSON') b ...与逗号形, `url`(...) 均被判为 ALLOW,可在 ClickHouse 侧形成 SSRF / 访问外部数据源;dictGetString('arbitrary_dictionary', ...)` 也被放行。建议不要只补正则,改为 AST 级校验 + ClickHouse 侧最小权限只读账号 + 函数白名单;这条 host 命令同样建议加 feature gate。

另外几个非阻断的小项:src/services/data-agent-client.tsbuildTrustedCallerWithUnionFallback 目前生产代码零引用(前者还保留了把身份写进 prompt 的旧兼容分支,建议删或接上);sandbox 模式下 ~/.config/ksher-agent-data-mcp 被 deny,proxy 的上游 launcher 起不来,因此该能力实际是 non-sandbox-only(沙盒里的 trusted-turn 文件 bind 属于「跑不起来的功能上的防御」,且精确文件 bind + 原子 rename 在跨 turn 时会读到旧身份);Data MCP 目前只有 codex TUI 接了 proxy,codex-app 没有真实消费。

以上是自动化评审的初步意见,可能有理解偏差,最终以维护者审阅为准。辛苦啦 🙏

@yousay123

Copy link
Copy Markdown
Author

已按自动化复核意见补充修复,并同步合并最新 master 解决冲突,当前 PR 分支已更新到最新提交:

  • 4f8e899b fix(mcp): 收紧 Data MCP 默认发布边界
  • 74bc3767 chore(mcp): 合并 master 解决 PR 冲突

本次针对 review 中提到的阻断项做了以下处理:

1. 移除同 UID 可改写的 trusted-turn 文件链路

认可 review 中关于 trusted-turns/<sessionId>.json 的风险判断:0600 只能隔离其他 Unix 用户,不能隔离同一 OS 用户下的 Codex/shell 进程。因此这版不再把可信身份落到模型进程可访问的 per-turn 文件里。

已处理:

  • 删除 src/utils/trusted-turn-store.ts
  • 删除 test/trusted-turn-store.test.ts
  • 移除 worker 侧 publish/clear trusted-turn 文件逻辑
  • mcp-identity-proxy data-agent 不再读取文件注入身份,改为 fail-closed
  • 后续真正启用 Data MCP 身份注入时,应改走 host-owned MCP gateway / worker 宿主侧内存注入,不再依赖模型同 UID 可写文件

2. 移除公共 Codex adapter 中的私有 MCP 默认注入

认可 review 中关于公共 npm 包不应无条件注入租户私有 MCP 的意见。

已处理:

  • src/adapters/cli/codex.ts 移除默认注入的 mcp_servers.*data-mcp* 配置
  • 同步调整 wrapper 参数识别逻辑和测试预期
  • 公共 Codex TUI 会话现在不会默认带私有 Data MCP server

3. 收紧 metadata query 默认发布边界

认可 review 中关于 SQL guard 不能只靠正则补洞的意见。当前先把该 host 命令改成默认关闭,避免公共发布时暴露高风险查询入口。

已处理:

  • botmux metadata query 默认 fail-closed
  • 只有显式设置 BOTMUX_METADATA_QUERY_ENABLED=true 时才会读取 host 凭据并执行
  • 默认 env 路径和默认库名已泛化,不再硬编码私有环境
  • 补充拒绝反引号表函数、外部 table function、dictGet* 的回归测试

4. 额外清理

  • 删除未接入生产主链路、且保留旧 prompt 身份透传说明的 src/services/data-agent-client.ts
  • 补齐 ListCodexAppThreadsOptions.initializeTimeoutMs 类型字段,修复合并后 build 暴露出的类型缺口
  • 合并最新 origin/master 后解决 src/types.tssrc/worker.ts 冲突;解决时保留上游新增的 MojoConfig / MojoLivePatch 字段,同时保留本 PR 所需的 trustedCaller 透传字段

验证

已在本地执行并通过:

  • pnpm build
  • pnpm test -- metadata-query trusted-mcp cli-adapters codex-app-threads
    • 390/390 passed
  • pnpm test -- write-input
    • 136/136 passed
  • pnpm test -- worker-pipe-initial-screen-order worker-durable-expiry-order restart-live-worker-env
    • 57/57 passed
  • git diff --check

另外已复查以下关键字在 src test scripts 下无命中:

  • ksher
  • trusted-turn-store
  • trusted-turns
  • BOTMUX_TRUSTED_TURN_FILE
  • data-agent-client
  • platform-ksher-agent-data-mcp
  • ksher-agent-data-mcp

当前页面还显示 Review required1 workflow awaiting approval,这两项需要 maintainer / code owner 侧审批 workflow 和 review。辛苦再看一下,谢谢。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants