# 保护嵌入接入 (/docs/developers/agent/embed/security)



把嵌入智能体接到网站时，用宿主登录态确定用户，用来源白名单限制浏览器接入，并在工具服务端检查权限。本页配置这些边界；测试情境与上线验收分别见[测试嵌入接入](/docs/developers/agent/embed/testing)和[上线检查清单](/docs/developers/agent/embed/go-live)。

## 准备与责任 [#prepare]

你需要能管理服务智能体的控制台账号、宿主网站的后端，以及修改网站响应头的权限。先完成嵌入策略和[令牌签发](/docs/developers/agent/embed/tokens)，再按下面的责任检查接入。

| 平台边界                 | 宿主必须完成的工作                               |
| -------------------- | --------------------------------------- |
| 嵌入用户只能访问所属智能体下自己的会话  | 从已验证登录态取得 `external_user_id`，拒绝浏览器自报的身份 |
| 跨用户、跨智能体资源访问返回 404   | API Key 仅放后端，签发路由验证登录态并防止跨站请求伪造         |
| 浏览器来源校验与 iframe 嵌入限制 | 登记实际网站来源，并限制宿主页可以加载的脚本                  |

## 保管身份与凭据 [#credentials]

后端用 `PRAXIS_API_KEY` 签发短期嵌入令牌，浏览器只接收需要的令牌。每次签发和续期都重新验证宿主登录态；不要让请求体中的 `external_user_id` 决定用户是谁。不要把 API Key、嵌入令牌放进 URL、HTML 或日志。

Kit 的传输层在内存中持有令牌。匿名接入另有 `visitor_secret`，Kit 会尝试保存在 `localStorage` 以延续访客身份，存储不可用时回退到页面内存。`publishableKey` 可公开，`visitor_secret` 不可公开；匿名身份不等于你网站的登录账户。

登出时停止签发、移除聊天组件，并由后端撤销相应凭据；清空页面并不等于撤销。封禁终端用户会阻止新签发并撤销该用户现有令牌。Kit 可在到期前重新取令牌，Hosted 不自动续期；详见[嵌入令牌与用户](/docs/developers/agent/embed/tokens)。

指令、`system_message`、页面上下文与工具结果都可能被模型复述。仅传入当前用户有权知道的信息，不要把密钥或其他用户的数据当作上下文传入。

## 限定页面来源 [#origins]

来源白名单**目前只能在控制台配置**。在当前控制台打开「服务智能体 → 你的智能体 → 接入与配置 → 配置 → 安全」，点击「添加来源」，填写例如 `https://shop.example.com`，然后点击「保存安全设置」。&#x2A;*预期：** 显示「已保存，不产生新版本」。

`allowed_origins` 最多 50 项，只填来源，不含路径、查询参数或片段。普通来源须为 HTTPS；`https://*.example.com` 只匹配一级子域，不匹配根域名或多级子域，且不支持端口。「允许 localhost」只用于本地 HTTP 调试，默认关闭。

签发时可以用 `allowed_origins` 选择策略中的非空子集，条目必须与策略完全一致。不要传空数组来表达「禁止所有来源」：令牌校验会回退读取策略白名单。修改策略也不等于撤销已签发令牌，需要立即收回访问时执行撤销。

来源不允许时返回 HTTP 403、`EMBED_ORIGIN_NOT_ALLOWED`。先修正来源配置再重新接入。来源检查约束浏览器；没有 Origin 的非浏览器请求不受这项检查保护，所以它不能代替令牌认证。

## 保护工具访问 [#tool-access]

MCP 服务器先验证平台调用凭据，再读取 `X-Praxis-External-User-Id` 作为终端用户身份。平台还会附带 `X-Praxis-Agent-Id` 和 `X-Praxis-Session-Id`；没有终端用户的会话不带这些身份头。

你的服务必须拒绝缺少所需身份的请求，每次查询都限定该用户的数据，修改订单前再验证归属和业务状态。不要相信模型传入的用户 ID，也不要仅凭公网请求带了身份头就信任它。通过 MCP 配置的 `headers` 认证调用方，才能使用平台附带的身份。

工具确认卡帮助确认意图；点击允许不会授予数据访问权。前端工具和页面上下文来自浏览器，不能承担权限校验。

## 配置宿主页保护 [#page-protection]

以下是 Develop 宿主页的响应头示例。适用于初始化脚本放在同源 JavaScript 文件中、Kit 从 CDN 加载的页面；按网站所需资源收窄图片等来源。若保留内联初始化脚本，须另为该脚本配置 CSP nonce 或哈希。

```http
Content-Security-Policy: default-src 'self'; script-src 'self' https://kit-develop.praxisusercontent.com; style-src 'self' 'unsafe-inline' https://kit-develop.praxisusercontent.com; connect-src 'self' https://api-develop.deepraxis.com https://kit-develop.praxisusercontent.com; frame-src https://chat-develop.praxisusercontent.com; font-src 'self' https://kit-develop.praxisusercontent.com data:; img-src 'self' https: data: blob:; frame-ancestors 'none'; base-uri 'self';
```

Kit 主题使用内联样式，因此示例允许内联样式。连接来源要与 `api.url` 一致。`frame-src` 允许加载托管 iframe；`frame-ancestors 'none'` 则禁止其他网站嵌入你的宿主页，两者作用不同。

平台 iframe 的 `frame-ancestors` 来自来源白名单，空白名单禁止嵌入；Hosted 禁止被嵌入。Kit 使用 open Shadow DOM，只隔离样式，同页脚本可以读取它；不要把不可信脚本与聊天组件放在同一页面。

若使用 CDN 完整性校验，复制控制台生成的实际固定版本地址与 `integrity`，保留 `crossorigin="anonymous"`。不要给浮动的 `/v1/` 地址配固定哈希，也不要把示意哈希当作发布值。

## 验证与下一步 [#verify]

保存后从获准的网站重新加载嵌入页，确认能发送消息。用浏览器 Network 检查宿主页响应中的 CSP，Console 中不应出现 Kit 加载或 API 连接被 CSP 阻止的错误。检查签发路由只返回短期凭据，工具日志中的用户范围与登录用户一致。

[测试嵌入接入](/docs/developers/agent/embed/testing) · [上线检查清单](/docs/developers/agent/embed/go-live) · [嵌入限制与错误](/docs/developers/agent/embed/limits-and-errors)。
