Skip to content

信任、授权与审计 ​

Alice 在订单运营团队工作。她让一个外部 Agent 批准订单 SO-1002,金额 48,000 元。订单页面上有「批准」按钮,Alice 也已经登录。

这两个事实仍然不能推出「这次批准应该发生」。系统还需要回答:当前代表哪位用户、由哪个 Agent 执行、请求属于哪个应用会话、这个会话被允许使用什么、当前金额是否还需要另一位审批人,以及事后能留下什么记录。

Agent 能找到按钮,不等于获得了使用它的权限。只有当这些问题都有明确答案时,信任才真正开始。

一次外部操作涉及哪些主体 ​

一次外部写操作至少涉及四个主体。把它们合成一个“已登录用户”,会掩盖各自的责任。

主体它回答的问题宿主可以依赖的证据
用户使用的是谁的业务身份和授权SSO 或应用会话
Agent是哪个程序在行动Agent 标识、客户端身份或委托记录
应用会话这个 Agent 可以在哪里、在什么时间范围内行动origin、租户、session id、能力范围和有效期
业务后端这次操作是否允许作用于当前资源角色、归属、限额、审批与事务规则

委托不是第五种身份。它记录的是一段关系:用户 U 允许 Agent G 在应用 A 中,在时间 T 之前使用能力集合 C。权限仍属于用户,执行者仍是 Agent。审计必须同时保留两者。

声明、暴露与授权 ​

“Agent 可以批准订单”实际上混合了三个不同判断:

  1. 页面声明了这个动作。 approve_order 存在,并有业务描述、输入、目标和影响范围。
  2. 当前会话暴露了这个动作。 站点级暴露策略和本次会话作用域都允许它。
  3. 后端允许这一次具体执行。 当前用户有权批准这张订单、这个金额,而且是在这个时间点。

第一件事描述软件结构;第二件事描述某一次 Agent 会话的边界;第三件事才是业务权限。

Pling 可以建立前两件事,并把结果交给页面执行器。它不能替代第三件事。页面声明不是授权,会话作用域也不能覆盖后端决定。

在当前 Surface 实现中,宿主提供的是已经验证过的会话。可调用能力取站点级暴露策略与该会话作用域的交集。有效期和撤销状态属于会话边界检查;请求限流和防重放是另外的保护。无论这些检查是否通过,页面都不会因此成为最终授权者。

同意、确认与审批 ​

这几种机制回答不同的问题,生命周期也不同。

机制它回答的问题典型生命周期
委托同意是否允许这个 Agent 在这段时间内使用这组能力一个会话,或一段有明确上限的较长期授权
操作确认用户现在是否想执行这个动作单次动作,或用户明确选择的短期许可
后端审批是否有有权的人批准了这次具体的高风险操作,且后端能够验证一次业务操作

确认弹窗可以表达用户意愿,但它本身不是后端可验证的审批。如果操作需要第二审批人、金额限制或可归档回执,这个决定属于业务后端。页面可以收集用户响应,并通过受信任的宿主流程传递;Agent 自己声称“已经批准”不能作为证据。

反过来也成立。有效的长期委托,不意味着每个已暴露动作都可以不再确认。高风险动作即使处于有效委托中,也可能需要用户当场重新决定。

动作声明中的 confirm 会与风险等级合成为确认策略。省略 confirm 时,默认由风险等级决定;危险动作会要求确认,而不是因为配置遗漏被静默放行。页面确认是否足够、是否需要后端审批,仍由应用决定。

审批材料不能进入 Agent 上下文 ​

当后端批准了一次具体操作,这份批准应当绑定到一组不能被悄悄替换的事实:

  • 用户与 Agent;
  • 应用会话;
  • 能力与目标记录;
  • 执行参数的规范化 hash;
  • 请求 id 和失效时间。

回执 token 或校验密钥只在受信任的页面流程与审批后端之间流转。它不能返回给 Agent,不能进入模型上下文,不能写入普通日志,也不能被另一条请求复用。

Surface 协议可以在内部带上一个公开的审批关联 id 供审计使用。执行器报告这个 id 后,协议把它写入审计事件,并从返回给 Agent 的响应中移除。这样既保留审批与执行之间的关联,也不让 Agent 成为审批材料的传递者。

审计需要回答什么 ​

审计事件应当能够重建授权与执行链,而不必复制业务载荷。一个实用的最小集合是:

字段组用途
用户、Agent、会话、委托确认谁在什么关系下行动
请求 id、能力、记录确认尝试了哪项操作
结果、错误码、耗时区分成功、业务拒绝、权限拒绝和系统失败
审批关联 id把高风险执行连接到企业自己的审批记录

原始参数、响应正文、Cookie、JWT 和审批 token 不应进入默认审计流。它们可能包含个人数据或密钥,保留要求也因地区和业务而不同。应用若需要参数级证据,应由自己的后端定义、加密并控制访问。

当前 Surface 实现提供只接收元数据的审计 sink。@plingjs/server 对模型请求遵循同样原则:默认记录请求元数据和结果,不保存提示词或响应正文。事件写到哪里、保留多久、谁能查看,仍由宿主负责。

失败时只能拒绝,不能顺手扩权 ​

信任最容易在信息缺失或状态冲突时失效。安全响应是拒绝执行,而不是推断出一个相近的权限。

情况应有行为
没有经过验证的会话拒绝请求
会话已过期或已撤销立即拒绝,要求重新授权
能力不在暴露范围内拒绝,不扩大白名单
目标记录已不存在报告目标缺失,不选择相似记录
用户拒绝确认停止,不换一种提示词重试
后端拒绝业务操作保留业务错误和可行动上下文
审计投递失败不改变业务结果,但必须发出运维告警

这就是 fail-closed:未知、过期、无法验证或彼此冲突的事实,都应导致拒绝。成功响应应当意味着所有必要检查都已通过。

应用落地时先回答五个问题 ​

  1. 哪些动作会改变业务状态,哪些只读取数据?
  2. 每个动作的目标记录如何稳定标识?
  3. 哪些动作必须确认,哪些还需要后端审批或人工接力?
  4. 会话绑定哪个用户、Agent、租户和能力范围,何时失效?
  5. 审计需要保存哪些元数据,哪些原始数据必须排除?

这五个问题可以先在低风险流程中落实,再逐步扩展到退款、审批、发布等不可逆操作。简单场景不应被复杂流程拖慢;高风险场景也不应被一个弹窗伪装成已经解决。

当前实现的边界 ​

当前 Surface 实现只接受已经验证的会话,取站点暴露范围与会话 scope 的交集,拒绝过期或撤销的会话,支持请求限流与防重放,输出只含元数据的审计事件,并从 Agent 可见响应中移除审批材料。

@plingjs/delegation 是可选参考包,用于短时、限定范围的 Agent 凭证。它支持签发、检查、轮换和撤销,token 只在签发或刷新时返回,参考存储仅保留 hash。身份提供方、持久存储、事件投递、SSO、租户政策和审计保留仍由应用实现。

Pling 不定义企业 RBAC/ABAC 模型,不提供生产审批服务,不替应用保存审计记录,也不认证某个部署合规。它提供的是一条共同的页面边界:哪些能力被暴露,哪次执行发生,以及随结果返回了哪些可核对的信息。

继续阅读 ​

如果页面需要与独立客户端交换能力,下一章从单站点集成到开放协议会说明一个私有桥何时需要变成协议。

部署前的威胁清单和检查项见安全与信任中心;页面能力与外部客户端的实现边界见什么是 Agent Surface。