Skip to content

test(authz): e2e-prove the MCP HTTP surface is identity-admitted; upgrade the matrix row to high-risk (#3167) - #3225

Merged
os-zhuang merged 1 commit into
mainfrom
claude/adr-0096-mcp-dev-wiring
Jul 18, 2026
Merged

test(authz): e2e-prove the MCP HTTP surface is identity-admitted; upgrade the matrix row to high-risk (#3167)#3225
os-zhuang merged 1 commit into
mainfrom
claude/adr-0096-mcp-dev-wiring

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

#3167PR-B。实现过程中前提再次变化——而且这次是个好消息:接线早已存在

关键发现:决策 A/B/C 早已 ship

serve.tsisMcpServerEnabled() 为真时 requires.push('mcp'),与 dispatcher /mcp 路由同一决策点自动加载 MCPServerPlugin;os dev spawn os serve --dev 继承之;stdio 仍 opt-in。也就是说我们"批准"的三个决策——dev 默认开、仅 HTTP、off-switch 统一——平台早就实现了(甚至 serve/prod 也默认开,因为准入已强制所以安全)。我 #3167 里"从未接线"的判断是过时误读(当初 grep 了不存在的 packages/tools/cli,实际在 packages/cli)。已在 #3167 更新说明。

所以 PR-B 唯一真正缺的,是 mcp-http-identity 行(#3202)明确延后的那块——端到端证明

本 PR:补上端到端证明 + 升级矩阵行

showcase-mcp-http-identity.dogfood.test.ts 启动真实 showcase + 安全栈 + MCPServerPlugin,经真实 HTTP + RLS 栈驱动 POST /api/v1/mcp:

  1. 匿名 tools/call → 401(任何工具执行之前 fail-closed);
  2. 成员的 query_records over owner-private showcase_private_note → 只返回自己的行,两个成员对称——若工具跑在无 scope/system(即 stdio 姿态)下,另一 owner 的行就会泄漏,所以这是 RLS-穿透-MCP 的承重断言;
  3. tool discovery(tools/list)同样受已准入身份门控。

mcp-http-identity 行升级为 HIGH_RISK + proof,关掉 #3202 在该行留的延后注记。dispatcher 层单元覆盖(http-dispatcher.mcp.test.ts 的 401 + EC-传-bridge;.mcp-oauth.test.ts 的 scope 403)本已存在;本 proof 补上单元 mock 无法展示的整栈授权结果

范围与验证

  • 纯测试 + 私有 @objectstack/dogfood 门包加一个 @objectstack/mcp dev-dep;不动运行时、不改任何默认(接线本就在 main 上)→ 无 changeset。
  • 本地:authz-conformance + 新 proof 13/13 绿;checkLedger 校验通过(high-risk 有 proof、proof 文件存在、基线 sound);eslint 干净。

剩余可选项(未纳入本 PR,保持聚焦):dev 启动打印 MCP 连接指引(URL / skill / connect-UI)——纯 DX 补充,值得单独小改。

Refs #3167(PR-B)、ADR-0096、ADR-0056 D10、#3202#2698

🤖 Generated with Claude Code

https://claude.ai/code/session_01Pbmw3pMqNJfPbkvwh9Fkjs


Generated by Claude Code

…rade the matrix row to high-risk (#3167)
PR-B of #3167. During implementation the premise shifted: the CLI ALREADY
auto-loads MCPServerPlugin in `os serve`/`dev` when isMcpServerEnabled()
(serve.ts — requires.push('mcp')), on the SAME decision point that gates the
dispatcher /mcp route, with stdio staying opt-in. So decisions A/B/C (dev
default-on, HTTP-only, unified off-switch) were already shipped — my #3167
"wired nowhere" claim was a stale read (a grep of the wrong path). The one
genuinely-missing piece was the end-to-end proof the mcp-http-identity row
(#3202) explicitly deferred.
This lands that proof: showcase-mcp-http-identity.dogfood.test.ts boots the
real showcase + security + MCPServerPlugin and drives POST /api/v1/mcp through
the real HTTP + RLS stack:
- an anonymous MCP tools/call is 401 before any tool runs (fail-closed);
- a member's query_records over the owner-private showcase_private_note returns
ONLY their own rows, symmetric across two members — if the tool had run
unscoped/system (the stdio posture, mcp-stdio-authority) the other owner's
rows would leak, so this is the load-bearing RLS-through-MCP assertion;
- tool discovery (tools/list) is gated on the same admitted identity.
The mcp-http-identity matrix row is upgraded to HIGH_RISK with this proof,
closing the deferral noted on it in #3202. Dispatcher-level unit coverage
(http-dispatcher.mcp.test.ts 401 + EC-to-bridge; .mcp-oauth.test.ts scope 403)
already existed; this adds the whole-stack authorization outcome the unit
mocks cannot show.
Test-only + a dev-dep on @objectstack/mcp in the private @objectstack/dogfood
gate — no runtime change, no changeset. authz-conformance + the new proof:
13/13 green locally.
Refs #3167, ADR-0096, ADR-0056 D10, #3202, #2698.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pbmw3pMqNJfPbkvwh9Fkjs
@vercel

vercelBot commented Jul 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
specBuildingBuildingPreview, CommentJul 18, 2026 3:08pm

Request Review

@github-actionsgithub-actionsBot added size/m dependencies Pull requests that update a dependency file tests labels Jul 18, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): packages/qa.

2 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/permissions/authorization.mdx(via packages/qa)
  • content/docs/permissions/delegated-administration.mdx(via packages/qa)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

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

Labels

dependenciesPull requests that update a dependency filesize/mtests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-zhuang@claude