test(authz): register MCP execution-surface identity admission in the ADR-0096 matrix (#3167)#3202
Merged
Merged
Conversation
… ADR-0096 matrix (#3167) The authz conformance matrix (ADR-0056 D10 / ADR-0096 D4) pins every execution surface's identity posture with a CI ratchet, but the MCP server — a live tool- execution surface — had no row of its own (only an incidental mention in the readonly-strip row). This adds two rows + three probe pins, one per transport, after auditing the actual code: - mcp-http-identity (ENFORCED): /api/v1/mcp already admits the caller — handleMcp denies anonymous (401), OAuth-scope-gates the tool families (#2698), and buildMcpBridge(context) threads the caller ExecutionContext so handleHttpRequest's per-request McpServer runs every tool under RLS/FLS/tenant exactly like REST /data. Pinned by probes on (UNCLASSIFIED tripwire for a new sibling MCP data handler) and (STALE if the threading is dropped). This CORRECTS #3167's premise that the HTTP admission was missing — it is wired; it was just unpinned. Its e2e dogfood proof is deferred to the dev-wiring follow-up (PR-B), so it is not marked high-risk yet — noted on the row. - mcp-stdio-authority (EXPERIMENTAL): the opt-in stdio transport (autoStart / OS_MCP_SERVER_ENABLED=true) bridges the RAW metadata service + data engine onto the long-lived server with NO per-request principal, so a stdio client reads unscoped (no RLS/FLS/tenant). Safe only as a single- operator local tool (the operator already owns the process + dev DB), and deliberately not default. This is the REAL admission gap. The row states the requirement before stdio is ever promoted to default-on / multi-user: thread a principal into the long-lived bridge. Pinned by a probe on the raw-service bridging (STALE forces re-classification when it changes). Bite tests (f)(g) prove both new pins fire. Baseline stays sound: the three new probe keys are covered exactly by the two new rows. Test-only change in the private @objectstack/dogfood gate — no changeset. Refs #3167, ADR-0096, ADR-0056 D10, #2698. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pbmw3pMqNJfPbkvwh9Fkjs
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 2 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
os-zhuang
marked this pull request as ready for review
July 18, 2026 09:24
This was referenced Jul 18, 2026
feat(mcp): #3167 PR-B — stdio/HTTP off-switch split +
os dev connect UX + exposure-policy docs
#3217
Merged
os-zhuang
added a commit
that referenced
this pull request
Jul 18, 2026
…rade the matrix row to high-risk (#3167) (#3225) showcase-mcp-http-identity.dogfood.test.ts boots the real showcase + security + MCPServerPlugin and drives POST /api/v1/mcp: anonymous tools/call is 401 before any tool runs, and a member's query_records over the owner-private showcase_private_note returns only their own rows (cross-owner would leak if it ran unscoped — the stdio posture). The mcp-http-identity matrix row is upgraded to HIGH_RISK with this proof, closing the deferral from #3202. Also documents that serve/dev already auto-load MCPServerPlugin on the unified isMcpServerEnabled switch (decisions A/B/C were already shipped). Test-only in the private dogfood gate.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#3167 的 PR-A(记账 + 钉子,非默认接线)。给 ADR-0096 的鉴权准入矩阵补上 MCP 这个执行面的身份姿态——并在审计代码后纠正了 #3167 的一个错误前提。
审计结论:HTTP 面早已准入,真缺口在 stdio
矩阵(ADR-0056 D10 / ADR-0096 D4)用 CI 绊线钉住每个执行面的身份姿态,但 MCP 这个活的工具执行面此前没有自己的行(只在 readonly-strip 行里被顺带提及)。逐路径读代码后,两条传输的姿态确实不同:
/api/v1/mcphandleMcp拒匿名(401)、OAuth scope 裁剪工具族(#2698)、buildMcpBridge(context)把 caller EC 线进每个callData(..., ec);handleHttpRequest每请求new McpServer+ principal-bound bridge → RLS/FLS/租户与 REST/data完全一致OS_MCP_SERVER_ENABLED=true才起)MCPServerPlugin.start()把裸 metadata 服务 + data engine 桥到长驻 server(bridgeResources(metadataService, dataEngine)),无 per-request principal → stdio 客户端无 scope 读取这直接推翻 #3167 决策 1 的"身份准入缺失、fall-open = 满权限"表述:HTTP 面根本没 fall-open,它拒匿名并线了身份;只是从没被矩阵钉住。真正的缺口是 opt-in 的 stdio(裸权限),而它本就非默认(
shouldStart门)。变更:两行 + 三个探针钉子
mcp-http-identity(enforced) —— covershandleMcp(新增同类 MCP 数据 handler → UNCLASSIFIED 绊线)+buildMcpBridge(context)(丢线程 → STALE → 红 CI)。未标 high-risk:不是因为它 latent(它是活路由),而是它的端到端 dogfood 证明(匿名→401、principal→RLS 裁剪结果)留给 dev 接线跟进 PR-B——行里注明了。mcp-stdio-authority(experimental) —— coversbridgeResources裸桥;note 写清姿态(仅单操作者本地安全:能 attach stdio 的人本就拥有进程+dev 库)、与 HTTP 路径的对比、以及准入要求:stdio 被提升为默认开 / 多用户 / 托管场景前,必须给长驻 bridge 线一个 principal。三个探针来自真实源码匹配;bite 测试 (f)(g) 证明两个新钉子确实触发。基线保持 sound:3 个新 key 恰好被 2 个新行覆盖。
范围与验证
@objectstack/dogfood门包 → 无 changeset;不动任何运行时代码,不接线os dev(那是 PR-B)。authz-conformance.test.ts本地 9/9 绿(基线 sound + 原有 5 bites + 新 (f)(g));eslint 干净;@objectstack/verify(checkLedger)构建绿。Refs #3167(PR-A;PR-B =
os dev接线 + off-switch 统一 + 连接指引 + dogfood 证明,待方向拍板)、ADR-0096、ADR-0056 D10、#2698。🤖 Generated with Claude Code
https://claude.ai/code/session_01Pbmw3pMqNJfPbkvwh9Fkjs
Generated by Claude Code