部署 Surface 网关
Surface 网关位于外部 Agent 与打开页面之间。它携带协议包络,把页面绑定到用户与租户,签发委托 Agent 会话并转发请求。它不能成为页面业务状态的第二份副本。
仓库中的已鉴权 Todo 示例是参考拓扑,不是托管服务。尤其要说明:surface.plingjs.dev 是演示端点,不是共享客户代理。生产企业应在自己的 origin 运行同样的边界,并接入自己的身份与数据系统。
可用拓扑
外部 Agent
│ MCP 或 HTTPS + Agent bearer token
▼
Surface 网关
│ 页面会话 + 一次性配对
▼
打开的业务页面
│ 通过页面桥 describe / invoke
▼
现有执行器与业务后端页面必须保持打开,因为它是能力投影与真人审批界面的来源。页面不存在时,网关不能自行编造上下文或执行业务逻辑。
凭证隔离
| 凭证 | 持有者 | 用途 |
|---|---|---|
| 应用会话 Cookie | 浏览器与 BFF | 证明已登录用户 |
| Surface 管理 token | 仅 BFF | 服务端到服务端创建页面会话 |
| 页面 token | 打开页面与网关 | 把页面 socket 绑定到租户/用户会话 |
| Agent bearer token | 外部 Agent 与网关 | 授权一次委托 Agent 会话 |
| 审批回执 | 页面审批后端 | 证明一次具体真人决定 |
绝不能把应用管理 token 发给浏览器、把页面 token 发给 Agent,或把 Agent token 发给模型。页面与 Agent 不能因为网关能路由两者,就共用一份凭证。
配对
只有用户明确开启外部访问后,流程才开始。BFF 验证请求,创建短期页面会话,只把页面 token 返回浏览器。页面打开 socket,等待网关确认;只有确认后才能创建一次性配对码。配对码很快过期、只能使用一次,并在服务端换成范围不超过页面白名单的 Agent 会话。
配对不是永久授予所有能力。它创建的是有界会话。页面、BFF 或网关都必须能撤销该会话,而且每次请求都要重新检查其状态。
网关行为
网关应:
- 验证 Agent 请求;
- 验证页面会话与租户;
- 检查请求范围属于已签发范围;
- 转发包络,不改写能力语义;
- 拒绝未知或超限消息;
- 串行
invoke,并在等待审批时允许describe; - 保留请求 id 与审计元数据;
- 页面断连或会话过期时 fail-closed。
它不应解析 DOM、选择业务动作、渲染审批界面或保存业务记录。若确实存储内容,应只保存最小会话元数据与审计数据,并定义清楚的保留策略。
仍需自己完成的部分
参考实现的内存存储与本地 socket 不是生产基础设施。应替换为持久会话存储、真实身份提供方、分布式限流、防重放、审计落库与撤销事件路径。网关还需要租户隔离模型,以及重启、网络分区和时钟偏差的部署方案。
测试那些不漂亮的路径:invoke 期间页面关闭、审批期间网关重启、配对码过期、重复领取、Agent token 被撤销、页面会话属于另一个用户,以及请求试图扩大范围。快乐路径演示成功,不能证明生产网关可用。
参见 身份、同意与委托、撤销访问与审计操作与 参考:Node 网关。

