Skip to content

安全

本页说明 Qoni 如何通过 OAuth / OIDC token 授权和 Web Agent 浏览器沙盒,让 Agent 在不接触用户密码、不越过授权边界的前提下执行 Web 任务。

安全模型概览

Qoni 的安全模型由两层组成:

  1. 授权层:GenAuth 基于用户身份、Agent 身份和任务范围签发短时授权,让 Agent 只能在明确 scope 内访问资源。
  2. 执行层:Web Agent 在受控浏览器沙盒中执行网页操作,隔离登录态、页面数据和任务上下文。

这两层共同解决一个问题:Agent 可以代表用户完成任务,但不能绕过用户授权、拿走用户密码,或把一次任务中的敏感数据扩散到其他任务。

基于 OAuth / OIDC token 的授权

Qoni 不建议把用户的长期凭证交给 Agent。推荐路径是:

  1. 用户先通过 GenAuth、你的登录系统或企业 OIDC Provider 完成人类身份认证。
  2. 服务端确认用户身份后,为具体 Agent 和具体任务申请一次有限授权。
  3. GenAuth 返回短时委托令牌(delegate token),其中包含允许的 scope、过期时间和 audit 信息。
  4. Web Agent 使用委托令牌执行任务,而不是使用用户密码或长期 refresh token。

委托令牌应只覆盖本次任务需要的最小权限。例如 Email Assistant Agent 可以被允许读取当前可见邮件、创建草稿和查询公开网页,但不应该被允许发送邮件、删除邮件或修改邮箱设置。

ts
const { data } = await qoni.delegateToken({
  mode: 'interactive',
  agent: 'email-assistant',
  scopes: ['webagent.web_search:manage', 'webagent.web_search:read'],
  redirectUri: 'http://localhost:3000/qoni/callback',
  state: 'task-001',
  user: { id: 'user_123' },
  expiresIn: 900, // 秒,按任务时长给
})

scope 只做正向声明

真实契约里没有"拒绝清单"这一项——最小权限靠只申请必要的 scope 来实现,不靠列举禁止项。密钥侧的 allowedScopes / allowedAgents 白名单是第二道闸门。完整语义见 Delegate Token 与缩权

Agent grant 与权限边界

Agent grant 是 Qoni 中把“用户同意”转化为“智能体可执行权限”的边界。生产环境中,每个 grant 都应至少包含:

字段作用
userId谁授权了这次任务。
agentKey 或 Agent Profile哪个智能体可以使用这次授权。
scopes智能体被允许执行的动作。
有效期 expiresIn授权多久后自动失效(秒,60–86400)。给短不给长。
auditId后续审计、排查和用户确认使用的记录。

如果任务需要新的权限,应重新让用户确认并签发新的 grant。不要把一个宽泛 grant 复用于多个无关任务。

浏览器沙盒安全

Web Agent 在受控浏览器沙盒中执行网页任务。沙盒最敏感的地方有两个:用户可能需要把密码输入到云端浏览器里;登录后,云端浏览器可能看到邮箱、后台系统、SaaS 页面等私有数据。因此沙盒的目标不是让 Agent 拥有完整浏览器权限,而是把密码输入、登录态、页面数据和视频流都限制在明确的任务边界内。

浏览器沙盒应满足以下原则:

  • 登录态只在受控会话或 profile 边界内使用。
  • 网页脚本、页面内容和下载文件不应直接进入应用的长期存储。
  • Agent 只能读取任务需要的页面区域和字段。
  • 任务结束后,临时页面状态应按策略清理或隔离。
  • 当任务需要用户登录、MFA 或 OAuth consent 时,由用户在 actionUrl 中完成。

Web Agent 可以在用户完成登录后继续任务,但它继续执行的能力仍受委托令牌和任务策略限制。

密码输入与登录态安全

Qoni 的推荐集成不要求 Agent 接收用户密码。用户需要登录第三方网页时,应通过 Web Agent 提供的 actionUrl 进入受控浏览器会话,并在目标站点或身份提供方页面中完成登录、MFA 或 OAuth consent。

密码链路应按下面的方式处理:

  • actionUrl 应是短时有效的 HTTPS 链接,并且只绑定到当前任务和当前用户操作。
  • 用户打开 actionUrl 后,密码输入发生在受控浏览器登录页面中,而不是 prompt、任务参数或后端 API 请求里。
  • 用户到 Qoni 受控浏览器入口、受控浏览器到目标站点或身份提供方之间都应使用 HTTPS / TLS 传输。
  • Qoni 不持久化保存用户密码。密码不应写入任务结果、ReAct trace、GUMem、audit 正文、回调事件或应用日志。
  • Agent 只知道“用户完成了登录 / MFA / consent”,不应该把密码作为可见文本、工具参数或 Memory 读取。
  • 登录成功后产生的 cookie、session storage 或 OAuth 登录态只在受控会话或 profile 边界内使用,不应导出给无关任务。

这也是为什么推荐优先使用 OAuth / OIDC:当目标系统支持授权码、consent 和短时 access token 时,Agent 不需要接触账号密码,只需要在委托令牌允许的范围内使用已授权的任务能力。

如果必须接入账号密码类旧系统,应把密码输入限制在受控登录页面中,并避免把密码写入日志、Memory、回调事件或任务结果。

不要在 prompt、任务参数、回调 URL、日志或长期配置中传递用户密码。

数据和视频流回传安全

Web Agent 登录后可能看到私有页面数据。Qoni 会把任务结果、ReAct 轨迹、浏览器视频帧或截图通过 SDK stream、SSE、回调或临时资源 URL 返回给你的应用。这条回传链路同样需要被当作敏感数据处理。

回传链路的安全边界包括:

  • 结果、事件和视频帧应通过 HTTPS / TLS 传输,避免被公网链路旁路读取。
  • SDK stream 和 API 调用需要项目级鉴权,例如 API key、Bearer token 或后端服务身份。
  • callbackUrl 必须使用 HTTPS,并且应指向你的服务端端点,而不是公开可写的第三方地址。
  • 视频帧、截图和抽取结果应绑定到具体 taskId、project 和用户会话;前端展示前应由你的后端确认当前用户有权查看该任务。
  • 如果使用临时资源 URL 返回帧或文件,URL 应短时有效,不应作为长期公开链接保存。
  • Qoni 不会把浏览器视频作为公开资源发布。你的应用也不应把视频帧、截图或私有页面正文写入公开日志、分析系统或长期 Memory。
  • 对用户不可见的内部 trace 不应包含隐藏 chain-of-thought;面向用户展示的 trace 应只包含可解释的摘要、动作和观察结果。

别人不能直接拿到这些数据,依赖的是三层控制:传输层用 HTTPS / TLS 防止网络窃听;访问层用 API key、Bearer token、project 和 task ownership 校验调用者;资源层用短时 URL、任务绑定和不公开发布策略限制视频帧、截图和抽取结果的传播。

数据最小化

Agent 处理网页和私有应用数据时,应遵循最小化原则:

  • 只抽取完成任务需要的字段,不保存完整页面快照。
  • 不把整封邮件、验证码、临时 token、cookie、密码或一次性链接写入 GUMem。
  • audit 记录应保留任务、scope、来源和关键动作,而不是无边界保存敏感正文。
  • 前端只展示用户需要确认的草稿、来源和风险提示。
  • 公开网页搜索任务不应携带私密邮件正文、内部文档内容或用户登录态。

如果某个字段只是本次任务的中间结果,应保存在任务状态中,而不是写入长期 Memory。

开发者接入检查清单

上线前检查以下事项:

  • 每个 Agent 都有稳定的 agentKey 或 Agent Profile。
  • 每次任务都使用短时 grant,不复用长期宽权限 token。
  • scopes 已按最小必要集合申请,未包含任务不需要的动作。
  • 用户登录、MFA 和 OAuth consent 通过 actionUrl 完成。
  • actionUrl、SDK stream、SSE、callback 和临时资源 URL 都走 HTTPS。
  • 后端日志不会记录密码、cookie、验证码、access token 或 refresh token。
  • 视频帧、截图和抽取结果只对有权查看该 task 的用户开放。
  • GUMem 只保存长期有价值的偏好和规则,不保存敏感凭证。
  • audit 记录能回答“谁授权、哪个智能体、做了什么、用了哪些权限”。

下一步

继续阅读 快速开始 了解 grant、Web Agent 和 GUMem 如何在一个最小智能体服务中协作。