#3167 明确 defer 的最后一块安全项(PR #3217 / #3228 的 PR-B 均已合入)。矩阵行 mcp-stdio-authority 目前 experimental,note 里写着 ADMISSION REQUIREMENT:长驻 stdio bridge 走裸 metadataService + dataEngine(record_by_id resource 直接 dataEngine.findOne(...),无 ExecutionContext → 绕过 RLS/FLS/租户)。本 issue 落地该准入,决策记录见 ADR-0101 (随实现 PR 提交,Proposed)。
决策摘要(详见 ADR-0101)
D1 — stdio 必须携带一个后端 principal,形态为 API key :OS_MCP_STDIO_API_KEY=osk_...,经 @objectstack/core 的共享验证链(resolveApiKeyPrincipal / resolveAuthzContext,与 HTTP 面同一条路)解析成 ExecutionContext;resource 读改走 ql.find(..., { context }),RLS/FLS/租户按该身份生效。逐调用重解析 ,吊销即时生效于存活的 stdio 会话。
D2 — fail-closed :开了 stdio auto-start(OS_MCP_STDIO_ENABLED=true / autoStart)但 key 缺失/无效 → 拒绝启动 stdio (响亮的配置错误,指明如何 mint key);HTTP 面不受影响。
D3 — 不提供 system 旁路模式 (rejected alternative):要"满权"就给平台管理员/专用 service 身份 mint 一个 key——供给凭据,而不是绕过身份。理由:可审计(归属真实身份)、可吊销、可轮换、走 posture 规则;OS_MCP_STDIO_IDENTITY=system 是刚在 feat(mcp): #3167 PR-B — stdio/HTTP off-switch split + os dev connect UX + exposure-policy docs #3217 修掉的 footgun 换名重现。
行业对齐:MCP 规范(stdio 不做传输认证、后端凭据从 env 供给)、Postgres/GitHub MCP server(按供给凭据 scope)、Anthropic agent-identity 模型(admin 预置的 scoped service 身份)。
v1 范围(实现 PR)
v2(后续,不阻塞 v1)
os dev 便利:用已 seed 的 dev-admin 自动 mint 一个本地专用、可撤的 dev key 并在启动打印(scoped key,非旁路,方向一致)
命名 service 身份 / 受限权限集 + key 轮换指引(对齐"静态 token 是主要失败模式"的行业共识)
Refs
#3167 明确 defer 的最后一块安全项(PR #3217 / #3228 的 PR-B 均已合入)。矩阵行
mcp-stdio-authority目前experimental,note 里写着 ADMISSION REQUIREMENT:长驻 stdio bridge 走裸metadataService+dataEngine(record_by_idresource 直接dataEngine.findOne(...),无 ExecutionContext → 绕过 RLS/FLS/租户)。本 issue 落地该准入,决策记录见 ADR-0101(随实现 PR 提交,Proposed)。决策摘要(详见 ADR-0101)
OS_MCP_STDIO_API_KEY=osk_...,经@objectstack/core的共享验证链(resolveApiKeyPrincipal/resolveAuthzContext,与 HTTP 面同一条路)解析成 ExecutionContext;resource 读改走ql.find(..., { context }),RLS/FLS/租户按该身份生效。逐调用重解析,吊销即时生效于存活的 stdio 会话。OS_MCP_STDIO_ENABLED=true/autoStart)但 key 缺失/无效 → 拒绝启动 stdio(响亮的配置错误,指明如何 mint key);HTTP 面不受影响。system旁路模式(rejected alternative):要"满权"就给平台管理员/专用 service 身份 mint 一个 key——供给凭据,而不是绕过身份。理由:可审计(归属真实身份)、可吊销、可轮换、走 posture 规则;OS_MCP_STDIO_IDENTITY=system是刚在 feat(mcp): #3167 PR-B — stdio/HTTP off-switch split +os devconnect UX + exposure-policy docs #3217 修掉的 footgun 换名重现。行业对齐:MCP 规范(stdio 不做传输认证、后端凭据从 env 供给)、Postgres/GitHub MCP server(按供给凭据 scope)、Anthropic agent-identity 模型(admin 预置的 scoped service 身份)。
v1 范围(实现 PR)
@objectstack/mcpplugin.start():读OS_MCP_STDIO_API_KEY→ 经 core 共享链解析 → 构造 EC(镜像 runtimeresolve-execution-context的映射);缺失/无效 → 拒启 stdio + 清晰报错bridgeResources系列改 principal-bound:record_by_id等数据读携带{ context }(逐调用重解析,吊销即时生效)mcp-stdio-authority:experimental→enforced,enforcement 指向新 gate;bridgeResources(unscoped-stdio)探针键随实现更新(会触发 STALE → 重分类,即本次)environment-variables.mdx增OS_MCP_STDIO_API_KEY;connect-mcp.mdxstdio 节更新@objectstack/mcpminor,若 types 增解析器则一并)v2(后续,不阻塞 v1)
os dev便利:用已 seed 的 dev-admin 自动 mint 一个本地专用、可撤的 dev key 并在启动打印(scoped key,非旁路,方向一致)Refs
os devconnect UX + exposure-policy docs #3217 / feat(cli): make optional-plugin loading intent-driven, fail-fast on declared-but-missing (#1597) #3228(已合)· feat(connector-mcp): policy-gate declarative stdio transports — default-deny + host allowlist (ADR-0097 security follow-up) #3055(消费侧 stdio spawn 策略门——同一信任讨论的另一半)packages/qa/dogfood/test/authz-conformance.matrix.ts(mcp-stdio-authority行)