status: done created: 2026-07-12 complexity: 🔴复杂 parent-stage: Forge AI 中枢阶段 2.1 — 受控写入
mcp-user-delegation-identity 已归档,MCP 每个请求都能建立可信 USER/SERVICE 双身份,并实时计算 Token scope、客户端 grant、用户权限、租户和当前组织交集。当前 MCP 仍只发布 capability.ping,不能安全发现或执行业务写动作。
本变更交付阶段 2.1 的最小可用闭环:把低代码应用中已经发布的、显式允许 AI 调用的业务动作发布为 BUSINESS_ACTION 能力,通过固定元工具 capability.search、capability.describe、capability.invoke 动态发现和调用。写入必须经过发布快照、授权、字段白名单、幂等和 MCP elicitation 人工确认,不能退化为任意 CRUD、任意 Mapper、任意 SQL、任意 URL 或任意代码执行。
/mcp Streamable HTTP;固定发布 capability.ping/search/describe/invoke,不动态创建顶层业务 Tool;capability.search/describe 只返回当前 client grant、当前用户权限、tenant/activeOrg 同时允许的已发布业务动作;ai_business_object_design_version.publish_status=PUBLISHED 的不可变快照解析,禁止读取已变更草稿作为执行定义;UPDATE_FIELD、CREATE_RECORD 及其安全组合;拒绝 START_FLOW、SEND_MESSAGE、DOMAIN_ACTION、外部 HTTP/URL、脚本和任意 SQL;policy_snapshot.allowedFields、grant field_policy.allowedFields 和目标发布模型字段;additionalProperties=false;capability.invoke 强制 16~128 位幂等键;相同键与相同请求返回已有结果,相同键与不同请求指纹拒绝;ACCEPT;DECLINE/CANCEL 或客户端不支持 elicitation 时不产生业务副作用;create_by/update_by/create_dept、业务动作日志和 Capability 调用审计记录 A/client/serviceUser/tenant/org;forge-plugin-capability-secure-actions 组合模块;forge-ai-hub-flow-actions;DOMAIN_ACTION、库存数量台账等领域副作用;/mcp Streamable HTTP
-> fdu Bearer + ExecutionIdentity
-> fixed tools: capability.search / describe / invoke
-> SecureActionCatalogService
-> ai_capability + version + grant(控制面)
-> published BusinessObjectDesignVersion(发布快照)
-> action permission + tenant/org
-> SecureActionPolicy(版本白名单 ∩ grant 白名单 ∩ 发布模型字段)
-> MCP elicitation ACCEPT
-> BusinessActionExecutionService.executePublished(...)
-> ai_business_action_execution_log + ai_capability_invocation_log
forge-plugin-mcp 只增加协议级 McpToolContributor 聚合扩展点,不依赖 Generator 或控制面。Secure Actions 模块负责把 MCP、控制面、Identity 和 Generator 组合起来;Generator 不反向依赖 Capability,避免循环依赖。
source_type=BUSINESS_ACTION;source_key={suiteCode}/{objectCode}/{actionCode},每段只允许 [A-Za-z0-9_-];source_version={publishVersion};behavior=ACTION;risk_level=MEDIUM;visibility=DISCOVERABLE;policy_snapshot 至少保存 allowedFields、requiredFields、allowedStepTypes、confirmationMode=MCP_ELICITATION、publishedObjectVersion;recordId、idempotencyKey 和 arguments,其中 arguments.properties 由字段白名单生成且 additionalProperties=false。| Tool | 行为 | 注解 |
|---|---|---|
capability.search |
查询当前调用方可发现动作,limit 1~50 | readOnly=true, destructive=false, idempotent=true |
capability.describe |
返回已授权版本、输入/输出 Schema、风险和确认要求 | readOnly=true, destructive=false, idempotent=true |
capability.invoke |
校验并执行一个已授权动作 | readOnly=false, destructive=true, idempotent=true |
工具结果同时提供文本 JSON 和 structuredContent。业务错误作为 Tool result isError=true 返回;协议级认证仍由 HTTP 401/403/503 处理。
capability.invoke 只接受能力编码、可选版本、记录 ID、幂等键和 arguments;suite/object/action、tenant/user/org/client 只能从服务端 source binding 与可信身份获得;USER_DELEGATION_REQUIRED;UPDATE_FIELD、CREATE_RECORD;嵌套/未知步骤失败关闭;ACCEPT 只对当前同步调用有效,不签发可重放确认 Token;新增 V1.0.23__add_secure_business_action_capabilities.sql:
capability_request_id/client_id/service_user_id/actor_type,便于双日志关联;/mcp Streamable HTTP;forge-ai-hub-flow-actions。forge.capability.secure-actions.enabled=false 关闭三个元工具和业务动作发布 API,保留 ping 与身份底座;mcp-user-delegation-identity 并开始新阶段开发;review-date: 2026-07-12 conclusion: NEEDS_FIX
已满足:单 /mcp Streamable HTTP、固定元工具、USER 委托身份、发布快照、ACTION/MEDIUM、MCP elicitation、幂等请求摘要、结构化结果、禁用旧 SSE/SAS/Sa-Token OAuth2 及 V1.0.23 静态迁移约束均已落地。
存在六个 Spec 不合规项:
SecureActionCatalogService 计算了能力版本与 grant 的 allowedFields 交集,但 SecureActionDescriptor.inputSchema 仍直接使用能力版本原始 Schema;SecureActionMcpHandler 只用该原始 Schema 校验 arguments,没有再按交集检查字段。因此被 grant 排除、但仍存在于版本 Schema 的字段仍可进入业务动作执行,违反 §2、§6.4 和 HARD-GATE。SecureActionCatalogMapper.xml 从 ai_capability_version v 选择授权版本和策略,却从 ai_capability c 返回当前 source_key/source_version。能力升级或重绑定后,PINNED grant 会混用“旧版本 Schema/策略 + 当前动作 binding”;版本号不同时异常失效,版本号碰巧相同时可能执行错误动作,违反 §6.8。SecureActionStepValidator 只检查 actionConfig.steps 的顶层 stepType,没有递归检查 stepList、嵌套 steps、childSteps 或步骤配置中的未知步骤,违反 §6.3 和 HARD-GATE。BusinessException 后映射为 INVALID_ARGUMENT,普通 Mapper/数据库异常映射为 EXECUTION_FAILED;两者都不能表达目录/授权/审计基础设施不可用,且前者会把平台故障伪装成调用参数错误,违反 §6.9。requestId + idempotencyKey 生成,不包含 capability/version/recordId/arguments,不能作为 §6.5 所要求的请求指纹。reviewed_with_findings,不得归档或进入 Flow Actions;/fix forge-ai-hub-secure-actions,优先顺序固定为 R1 → R2 → R3 → R4/R5 → R6;fix-date: 2026-07-12 conclusion: FIXED_PENDING_REVIEW
arguments.properties/required 裁剪到版本策略与 grant 策略交集;invoke 同时显式拒绝交集之外的字段,指定发布模型仍作为第三道校验。ai_capability_version 读取 source_key/source_version/risk_level,并要求 capability/version 同时满足 BUSINESS_ACTION/ACTION/MEDIUM/DISCOVERABLE,PINNED/FOLLOW_MAJOR 不再混用主表当前 binding。steps/stepList,任意 childSteps、嵌套 steps/stepList、未知或禁用步骤全部失败关闭。CATALOG_UNAVAILABLE、AUTHORIZATION_UNAVAILABLE、AUDIT_UNAVAILABLE,日志只记录 requestId、错误码和异常类型。EXECUTION_PENDING 审计;最终结果只能按相同身份更新。预留失败不进入执行,最终审计失败返回 AUDIT_UNAVAILABLE 并保留待完成记录,幂等重试可补齐最终状态。Fix 验证:Secure Actions 27/27、Control Plane 27/27、Generator 专项 7/7、MCP 16/16、Identity 35/35、Admin 40/40 聚合通过;Mapper XML 和静态安全扫描通过。当前状态为 fixed_pending_review,等待再次 Review,复审通过前不归档或进入 Flow Actions。
review-date: 2026-07-12 conclusion: PASS
arguments Schema 与显式字段校验均使用能力版本、grant 和发布模型字段交集,PASS;ai_capability_version,PASS;steps/stepList/childSteps、未知和禁用步骤均失败关闭,PASS;CATALOG_UNAVAILABLE、AUTHORIZATION_UNAVAILABLE、AUDIT_UNAVAILABLE,PASS;/mcp Streamable HTTP、USER 委托身份、发布快照、幂等和禁用旧传输/认证依赖边界保持,PASS。SecureActionCatalogMapper.xml 解析、V1.0.23 Flyway placeholder 扫描和相关 git diff --check PASS;forge-ai-hub-flow-actions。