智能体嵌入

安全

嵌入智能体的隔离边界、令牌与来源白名单、哪些内容不是秘密,以及 CSP、SRI 配置。

嵌入把一个智能体放进你的页面,页面的访问者就是智能体的使用者。这一页说明平台替你守住了什么、哪些要你自己守,以及宿主页怎样配置。

责任划分

平台保证你负责
嵌入令牌只能访问一个智能体下自己名下的会话用你自己的登录态确定 external_user_id,不要信浏览器传来的值
越权访问一律返回 404,不透露资源是否存在工具服务端按终端用户鉴权(工具授权)
令牌只在浏览器内存里,短期有效,可以随时撤销保管 API Key,只在后端使用
只接受白名单来源的页面使用令牌配好 allowed_origins,宿主页配好 CSP

隔离边界

  • 令牌的主体是终端用户,不是你的组织。持有令牌的人只能创建和读取自己名下的会话,看不到同一智能体下其他用户的会话,也不能调用签发、撤销、列出令牌这类宿主接口(返回 404)。身份来自令牌,不来自请求参数。
  • 跨用户、跨智能体一律 404,而不是 403:不告诉访问者「这个东西存在但不属于你」。
  • API Key 永远不进浏览器。后端用它签发令牌;浏览器只拿令牌。令牌的签发与撤销见令牌与终端用户。

令牌

  • 令牌有效期 60 到 3600 秒。设短一些:被截获的令牌价值有限。getToken 会在到期前被再次调用,换发时再确认一次用户仍处于登录状态。
  • 令牌只存在于内存,不要自己写进 localStorage、Cookie 或页面 HTML。
  • 发现泄露或用户登出时,按签发记录的 id 撤销,令牌立即失效,进行中的事件流会收到 EMBED_TOKEN_REVOKED 并关闭。
  • 对某个用户启用封禁(blocked_end_users),他就拿不到新令牌。

来源白名单

嵌入策略里的 allowed_origins 限定哪些页面来源可以使用令牌。签发令牌时可以再收窄(传 allowed_origins,必须是策略白名单的子集)。来源不在名单上时,请求返回 EMBED_ORIGIN_NOT_ALLOWED(403)。

  • 只接受 https 来源;https://*.example.com 形式的通配只匹配一级子域名,不含端口。
  • 本地开发才打开 allow_localhost,上线前关掉。
  • 来源由浏览器写入请求,它挡住的是别的网站拿你的令牌去用,挡不住拿到令牌的非浏览器客户端。令牌本身仍要妥善保管。

哪些不是秘密

下面这些内容,模型可能被用户要求复述,请当作公开信息对待:

  • 智能体的指令(Console 里写的 instructions)。
  • 覆盖指令(agent_override.system)。
  • system.message 里的宿主上下文。
  • 页面上下文和前端工具的返回值。
  • 工具的名字、描述和输入结构。

所以不要在这些地方放密钥、内部规则、不想让用户看到的话术或别人的数据。需要保密的数据放在你的工具服务端,用终端用户身份控制谁能取到。

提示注入与不可信上下文

智能体读到的内容里,凡是来自浏览器或第三方的,都可能含有试图操纵它的指令:用户输入、页面上下文、网页内容、工具返回的文本。

  • 页面上下文是不可信的。服务端把它放进附在本轮用户消息末尾的 <page_context untrusted="true"> 块里,不进系统提示,也不延续到下一轮。值里的 <、>、& 和引号会被转义,不能伪造出新的标签。详见前端工具与页面上下文。
  • 可信事实走 system.message。只有持有 API Key 的后端能写入它,终端用户令牌不能。
  • 不要靠指令里的「不要……」守住边界。真正要禁止的事,在工具一侧不提供,或者在服务端拒绝。
  • 智能体可以调用的工具越少越安全:只为这个场景开需要的工具,写入类工具保留 always_ask,并在服务端校验。

iframe 与 Hosted

iframe 页的 frame-ancestors 来自智能体的来源白名单;白名单为空时禁止所有网站嵌入。Hosted 是独立页面,使用 frame-ancestors 'none'。平台托管的 chat 页从自身可信来源请求 API;宿主来源由 iframe 策略和跨窗口通信校验。

使用一行加载器时,宿主 CSP 还需在 frame-src 放行 https://chat-develop.praxisusercontent.com。加载器同时校验跨窗口消息的来源和发送窗口。Hosted 凭证只能使用一次,见嵌入令牌。

Shadow DOM

<praxis-agent> 渲染在 open Shadow DOM 里:宿主页的样式不会漏进对话,对话的样式也不会影响宿主页。这是样式隔离,不是安全边界:open 的 Shadow DOM 可以被页面脚本读取,同一页面上的任何脚本都能访问对话内容。不要把智能体嵌入你不信任的第三方脚本也在运行的页面里,需要强隔离时使用 iframe。

内容安全策略(CSP)

如果你的页面设置了 CSP,需要放行 Kit 脚本所在的来源,以及 Kit 连接 API 的来源。

环境脚本来源(script-src)连接来源(connect-src)
develophttps://kit-develop.praxisusercontent.comhttps://api-develop.deepraxis.com
生产https://kit.praxisusercontent.comhttps://api.deepraxis.com
Content-Security-Policy:
  default-src 'self';
  script-src 'self' https://kit-develop.praxisusercontent.com;
  connect-src 'self' https://api-develop.deepraxis.com;
  frame-src https://chat-develop.praxisusercontent.com;

要点:

  • connect-src 里的 API 地址要和 setOptions 的 api.url 一致,也就是签发令牌的那个环境。
  • 如果你自己托管 Kit 的构建(如快速开始里的 /praxis-kit.js),script-src 'self' 就够了,不需要放行 CDN。
  • Kit 会向 Shadow DOM 里插入 <style> 元素(用于主题)。设置了严格 style-src 的页面,需要允许内联样式,例如 style-src 'self' 'unsafe-inline'。
  • 头像、启动图片等你通过选项传入的图片地址,要放行 img-src。
  • 宿主页面被别人嵌入的保护由宿主自己的 frame-ancestors 决定。

子资源完整性(SRI)

从 CDN 加载时,用不可变路径并加上 integrity,浏览器会校验文件内容,CDN 被篡改时拒绝执行:

<script
  type="module"
  src="https://kit-develop.praxisusercontent.com/v0.1.0/praxis-kit.js"
  integrity="sha384-…"
  crossorigin="anonymous"
></script>
  • integrity 的值(sha384-…)由发布 Kit 版本时给出,路径里的版本号(v0.1.0)对应一次不可变的发布,内容不会改变。
  • 必须带 crossorigin="anonymous",否则浏览器不会校验。
  • 浮动路径 https://kit-develop.praxisusercontent.com/v1/praxis-kit.js 会随新版本更新内容,不要配 integrity,配了会在下次发布后加载失败。需要锁定内容时请用不可变路径。

上线前检查清单

  • API Key 只在后端,页面和仓库里找不到。
  • external_user_id 来自你的登录态。
  • allowed_origins 只有你的站点,生产环境没有开 allow_localhost。
  • 令牌有效期合理,登出时撤销令牌。
  • 指令和 system.message 里没有秘密。
  • 工具服务端按 X-Praxis-External-User-Id 鉴权,并认证调用方。
  • 页面 CSP 放行了 Kit 与 API,CDN 加载使用不可变路径和 SRI。

相关:工具授权 · 令牌与终端用户 · 限制与错误

导出

本页内容