控制模型
控制模型回答“谁可以在什么条件下做什么”。它与能力模型分开:能力描述业务操作,控制决定这次调用能否执行。协议只承载已经验证的控制结论,不代替登录、授权或业务审批。
主体
一次外部调用至少涉及四个主体:
- 用户:拥有业务账户的自然人或组织成员;
- Agent:具有厂商、版本、实例或客户端身份的调用方;
- 应用:由 origin、租户和页面会话标识的站点;
- 业务后端:最终授权并执行写入的系统。
用户身份与 Agent 身份不得合并。审计必须能同时回答“谁授权”和“谁执行”。
会话
主机必须先验证调用方,再向 Surface 提供会话对象:
interface SurfaceSession {
agentId: string;
sessionId: string;
userId: string;
expiresAt: number;
scope: readonly string[] | ((id: string) => boolean);
delegationId?: string;
revokedAt?: number;
}scope 是本次委托的能力上限。站点级 expose 与 scope 必须取交集。sessionId 必须绑定同一授权状态;权限变化时应使用新 id,避免旧缓存被继续使用。
会话缺失、格式非法、过期或撤销时,协议必须在执行前 fail-closed。凭证解析属于传输层或身份服务;协议对象中不得出现 Cookie、JWT 或原始委托 token。
授权顺序
一次 invoke 的控制顺序应为:
验证传输身份 → 校验协议版本与包络 → 校验会话
→ 校验站点暴露范围 ∩ 会话范围 → 校验能力与记录
→ 检查限流与重复请求 → 交给现有执行器
→ 记录审计结果任何一步失败都不得调用业务处理函数。实现不得先执行再补检查。
确认与人工接力
approval 描述页面确认要求,不是 Agent 可自行批准的选项。需要确认时,页面应向真实用户呈现与本次请求绑定的挑战;Agent 只能看到等待状态或最终结果。
高风险操作可以由业务页面或后端执行,也可以要求人工完成。人工接力的 handoff 原因应可读,并保留与请求的关联。审批 token、回执秘密和内部 hash 不得进入 Agent 响应、审计说明或日志;只有公开的审批关联 id 可以进入审计。
限额与防重放
实现可以在协议边界配置按会话计算的滑动窗口限流。超限必须返回 RATE_LIMITED 和建议等待时间,不得执行业务动作。限流适配器异常时必须拒绝,而不是静默放行。
对 invoke 启用防重放时,同一会话重复使用一个 request.id 必须返回 REPLAY_DETECTED。新逻辑调用必须使用新 id。防重放存储异常同样必须 fail-closed。
审计
审计事件应记录:
- 时间、协议版本与 request id;
- 用户、Agent、会话与可选委托 id;
- 方法、能力 id、目标记录;
- 结果类别、稳定错误码与耗时;
- 可公开的审批关联 id。
审计不得记录原始参数、完整响应、凭证或敏感字段。审计写入失败不应改变业务结果,但必须通过独立告警暴露;生产环境应监控高风险动作的 approval_id = null。
撤销与过期
撤销和过期必须在下一次请求前生效。浏览器端的提前通知只能作为提示,不能作为事实来源;每次关键调用前应重新验证会话或使用短期凭证。
不作出的保证
协议不能阻止拥有浏览器控制权的 Agent 直接点击页面,也不能保证业务后端一定正确授权。它提供的是明确的暴露范围、会话绑定、结构化结果和可审计的调用链。后端授权、风控和人工复核仍是独立控制。

