diff --git a/docs/zh-CN/gateway/configuration-reference.md b/docs/zh-CN/gateway/configuration-reference.md index 550cc043b..bb4558ee6 100644 --- a/docs/zh-CN/gateway/configuration-reference.md +++ b/docs/zh-CN/gateway/configuration-reference.md @@ -2,77 +2,75 @@ read_when: - 你需要精确到字段级别的配置语义或默认值 - 你正在验证渠道、模型、Gateway 网关或工具配置块 -summary: 适用于 OpenClaw 核心键名、默认值以及指向各专用子系统参考文档链接的 Gateway 网关配置参考 +summary: Gateway 网关配置参考,涵盖核心 OpenClaw 键、默认值以及指向专用子系统参考的链接 title: 配置参考 x-i18n: - generated_at: "2026-04-26T06:01:25Z" + generated_at: "2026-04-26T19:16:56Z" model: gpt-5.4 provider: openai - source_hash: b6c6e12c328cfc3de71e401ae48b44343769c4f6b063479c8ffa4d0e690a2433 + source_hash: 2579a59555d480b116955cad0508392240ee6ae4f19cf46b8fc754c0ce48f870 source_path: gateway/configuration-reference.md workflow: 15 --- -`~/.openclaw/openclaw.json` 的核心配置参考。若需面向任务的概览,请参见 [配置](/zh-CN/gateway/configuration)。 +`~/.openclaw/openclaw.json` 的核心配置参考。有关面向任务的概览,请参见 [配置](/zh-CN/gateway/configuration)。 -本页涵盖 OpenClaw 的主要配置面,并在某个子系统拥有更深入的独立参考时提供链接。渠道和插件自有的命令目录,以及更深层的内存 / QMD 调节项,分别位于各自页面,而不在本页中说明。 +本页涵盖主要的 OpenClaw 配置表面,并在某个子系统拥有自己更深入的参考时提供外链。由渠道和插件拥有的命令目录,以及更深层的 memory/QMD 调节项,分别位于各自页面,而不是放在本页。 -代码事实依据: +代码真相: -- `openclaw config schema` 会打印用于校验和 Control UI 的实时 JSON Schema,并在可用时合并内置 / 插件 / 渠道元数据 -- `config.schema.lookup` 会返回单个按路径限定的 schema 节点,供下钻工具使用 -- `pnpm config:docs:check` / `pnpm config:docs:gen` 会根据当前 schema 表面校验配置文档基线哈希 +- `openclaw config schema` 会打印用于验证和 Control UI 的实时 JSON Schema,并在可用时合并内置/插件/渠道元数据 +- `config.schema.lookup` 会返回一个按路径范围限定的 schema 节点,供下钻工具使用 +- `pnpm config:docs:check` / `pnpm config:docs:gen` 会根据当前 schema 表面验证配置文档基线哈希 -智能体查找路径:编辑前,使用 `gateway` 工具动作 `config.schema.lookup` -获取精确到字段级别的文档和约束。面向任务的指导请使用 -[配置](/zh-CN/gateway/configuration),而本页用于查看更广泛的字段映射、默认值以及指向子系统参考的链接。 +智能体查找路径:在编辑前,使用 `gateway` 工具动作 `config.schema.lookup` 获取精确到字段级别的文档和约束。使用 +[配置](/zh-CN/gateway/configuration) 获取面向任务的指导,使用本页获取更广泛的字段映射、默认值以及指向子系统参考的链接。 专用深度参考: -- [内存配置参考](/zh-CN/reference/memory-config),适用于 `agents.defaults.memorySearch.*`、`memory.qmd.*`、`memory.citations`,以及位于 `plugins.entries.memory-core.config.dreaming` 下的 dreaming 配置 +- [Memory 配置参考](/zh-CN/reference/memory-config),适用于 `agents.defaults.memorySearch.*`、`memory.qmd.*`、`memory.citations`,以及位于 `plugins.entries.memory-core.config.dreaming` 下的 dreaming 配置 - [斜杠命令](/zh-CN/tools/slash-commands),查看当前内置 + 捆绑命令目录 -- 各自的渠道 / 插件页面,查看渠道专属命令表面 +- 各自所属的渠道/插件页面,用于渠道特定的命令表面 -配置格式为 **JSON5**(允许注释和尾随逗号)。所有字段均为可选——省略时,OpenClaw 会使用安全的默认值。 +配置格式为 **JSON5**(允许注释 + 尾随逗号)。所有字段都是可选的——省略时,OpenClaw 会使用安全的默认值。 --- ## 渠道 -每个渠道的配置键已移至专门页面——请参见 -[配置 — 渠道](/zh-CN/gateway/config-channels),了解 `channels.*`, -包括 Slack、Discord、Telegram、WhatsApp、Matrix、iMessage 及其他 -内置渠道(身份验证、访问控制、多账号、提及门控)。 +各渠道配置键已移动到专用页面——请参见 +[配置 — 渠道](/zh-CN/gateway/config-channels) 了解 `channels.*`, +其中包括 Slack、Discord、Telegram、WhatsApp、Matrix、iMessage 及其他 +内置渠道(认证、访问控制、多账户、提及门控)。 ## 智能体默认值、多智能体、会话和消息 -已移至专门页面——请参见 +已移动到专用页面——请参见 [配置 — 智能体](/zh-CN/gateway/config-agents),内容包括: -- `agents.defaults.*`(工作区、模型、思考、心跳、内存、媒体、Skills、沙箱) +- `agents.defaults.*`(工作区、模型、思考、心跳、memory、媒体、Skills、沙箱) - `multiAgent.*`(多智能体路由和绑定) - `session.*`(会话生命周期、压缩、清理) -- `messages.*`(消息投递、TTS、Markdown 渲染) +- `messages.*`(消息传递、TTS、Markdown 渲染) - `talk.*`(Talk 模式) - - `talk.speechLocale`:Talk 语音识别在 iOS / macOS 上使用的可选 BCP 47 locale id - - `talk.silenceTimeoutMs`:未设置时,Talk 会在发送转录内容前保持平台默认暂停窗口(`macOS 和 Android 上为 700 ms,iOS 上为 900 ms`) + - `talk.speechLocale`:适用于 iOS/macOS 上 Talk 语音识别的可选 BCP 47 locale id + - `talk.silenceTimeoutMs`:未设置时,Talk 会在发送转录文本前保持平台默认停顿窗口(`macOS 和 Android 上为 700 ms,iOS 上为 900 ms`) ## 工具和自定义提供商 工具策略、实验性开关、由提供商支持的工具配置,以及自定义 -提供商 / base-URL 设置已移至专门页面——请参见 +提供商 / base-URL 设置已移动到专用页面——请参见 [配置 — 工具和自定义提供商](/zh-CN/gateway/config-tools)。 ## MCP 由 OpenClaw 管理的 MCP 服务器定义位于 `mcp.servers` 下,并由嵌入式 Pi 及其他运行时适配器使用。`openclaw mcp list`、 -`show`、`set` 和 `unset` 命令可管理此配置块,而无需在编辑配置时连接到 -目标服务器。 +`show`、`set` 和 `unset` 命令可在编辑配置时管理此配置块,而不会连接到目标服务器。 ```json5 { mcp: { - // 可选。默认值:600000 ms(10 分钟)。设为 0 可禁用空闲清理。 + // 可选。默认值:600000 ms(10 分钟)。设为 0 可禁用空闲驱逐。 sessionIdleTtlMs: 600000, servers: { docs: { @@ -91,15 +89,15 @@ x-i18n: } ``` -- `mcp.servers`:为暴露已配置 MCP 工具的运行时提供命名的 stdio 或远程 MCP 服务器定义。 -- `mcp.sessionIdleTtlMs`:按会话作用域划分的内置 MCP 运行时的空闲 TTL。 - 一次性嵌入式运行会请求在运行结束时清理;此 TTL 是面向 +- `mcp.servers`:为暴露已配置 MCP 工具的运行时提供具名 stdio 或远程 MCP 服务器定义。 +- `mcp.sessionIdleTtlMs`:用于会话范围内内置 MCP 运行时的空闲 TTL。 + 一次性嵌入式运行会在运行结束时请求清理;此 TTL 是 长生命周期会话和未来调用方的兜底机制。 -- `mcp.*` 下的变更会通过释放缓存的会话 MCP 运行时来热应用。 - 下一次工具发现 / 使用时会依据新配置重新创建它们,因此被移除的 +- `mcp.*` 下的更改会通过释放已缓存的会话 MCP 运行时来热应用。 + 下一次工具发现/使用时会根据新配置重新创建它们,因此被移除的 `mcp.servers` 条目会立即回收,而不是等待空闲 TTL 到期。 -运行时行为请参见 [MCP](/zh-CN/cli/mcp#openclaw-as-an-mcp-client-registry) 和 +有关运行时行为,请参见 [MCP](/zh-CN/cli/mcp#openclaw-as-an-mcp-client-registry) 和 [CLI 后端](/zh-CN/gateway/cli-backends#bundle-mcp-overlays)。 ## Skills @@ -117,7 +115,7 @@ x-i18n: }, entries: { "image-lab": { - apiKey: { source: "env", provider: "default", id: "GEMINI_API_KEY" }, // 或纯文本字符串 + apiKey: { source: "env", provider: "default", id: "GEMINI_API_KEY" }, // 或明文字符串 env: { GEMINI_API_KEY: "GEMINI_KEY_HERE" }, }, peekaboo: { enabled: true }, @@ -127,13 +125,14 @@ x-i18n: } ``` -- `allowBundled`:仅对内置 skills 生效的可选允许名单(托管 / 工作区 skills 不受影响)。 -- `load.extraDirs`:额外的共享 skill 根目录(最低优先级)。 -- `install.preferBrew`:为 `true` 时,如果 `brew` 可用,则优先使用 Homebrew 安装器,然后再回退到其他安装器类型。 +- `allowBundled`:仅适用于内置 Skills 的可选允许列表(托管/工作区 Skills 不受影响)。 +- `load.extraDirs`:额外的共享 skill 根目录(优先级最低)。 +- `install.preferBrew`:为 true 时,如果 `brew` 可用,则优先使用 Homebrew 安装器, + 然后再回退到其他安装器类型。 - `install.nodeManager`:用于 `metadata.openclaw.install` - 规范的 Node 安装器偏好(`npm` | `pnpm` | `yarn` | `bun`)。 -- `entries..enabled: false`:即使某个 skill 已内置 / 已安装,也会将其禁用。 -- `entries..apiKey`:为声明主环境变量的 skill 提供的便捷字段(纯文本字符串或 SecretRef 对象)。 + 规范的 node 安装器偏好(`npm` | `pnpm` | `yarn` | `bun`)。 +- `entries..enabled: false`:即使 skill 已内置/已安装,也会禁用该 skill。 +- `entries..apiKey`:为声明主环境变量的 skills 提供的便捷字段(明文字符串或 SecretRef 对象)。 --- @@ -162,39 +161,39 @@ x-i18n: ``` - 从 `~/.openclaw/extensions`、`/.openclaw/extensions` 以及 `plugins.load.paths` 加载。 -- 设备发现支持原生 OpenClaw 插件,以及兼容的 Codex bundles 和 Claude bundles,包括无 manifest 的 Claude 默认布局 bundles。 -- **配置变更需要重启 Gateway 网关。** -- `allow`:可选允许名单(仅加载列出的插件)。`deny` 优先。 -- `plugins.entries..apiKey`:插件级 API key 便捷字段(插件支持时可用)。 +- 设备发现接受原生 OpenClaw 插件,以及兼容的 Codex bundle 和 Claude bundle,包括无 manifest 的 Claude 默认布局 bundle。 +- **配置更改需要重启 Gateway 网关。** +- `allow`:可选允许列表(仅加载列出的插件)。`deny` 优先。 +- `plugins.entries..apiKey`:插件级 API key 便捷字段(在插件支持时)。 - `plugins.entries..env`:插件作用域环境变量映射。 -- `plugins.entries..hooks.allowPromptInjection`:当为 `false` 时,核心会阻止 `before_prompt_build`,并忽略旧版 `before_agent_start` 中会修改提示词的字段,同时保留旧版 `modelOverride` 和 `providerOverride`。适用于原生插件钩子以及受支持的 bundle 提供的钩子目录。 +- `plugins.entries..hooks.allowPromptInjection`:当为 `false` 时,core 会阻止 `before_prompt_build`,并忽略旧版 `before_agent_start` 中会修改提示词的字段,同时保留旧版 `modelOverride` 和 `providerOverride`。适用于原生插件钩子以及受支持的由 bundle 提供的钩子目录。 - `plugins.entries..hooks.allowConversationAccess`:当为 `true` 时,受信任的非内置插件可从 `llm_input`、`llm_output`、`before_agent_finalize` 和 `agent_end` 等类型化钩子中读取原始会话内容。 - `plugins.entries..subagent.allowModelOverride`:显式信任此插件可为后台子智能体运行请求按次运行的 `provider` 和 `model` 覆盖。 -- `plugins.entries..subagent.allowedModels`:受信任子智能体覆盖的规范 `provider/model` 目标的可选允许名单。仅当你确实想允许任意模型时,才使用 `"*"`。 -- `plugins.entries..config`:插件定义的配置对象(可用时由原生 OpenClaw 插件 schema 校验)。 -- 渠道插件的账号 / 运行时设置位于 `channels.` 下,应由所属插件的 manifest `channelConfigs` 元数据描述,而不是由中央 OpenClaw 选项注册表描述。 -- `plugins.entries.firecrawl.config.webFetch`:Firecrawl 网页抓取提供商设置。 - - `apiKey`:Firecrawl API key(接受 SecretRef)。回退到 `plugins.entries.firecrawl.config.webSearch.apiKey`、旧版 `tools.web.fetch.firecrawl.apiKey` 或 `FIRECRAWL_API_KEY` 环境变量。 - - `baseUrl`:Firecrawl API 基础 URL(默认值:`https://api.firecrawl.dev`)。 +- `plugins.entries..subagent.allowedModels`:适用于受信任子智能体覆盖的规范 `provider/model` 目标可选允许列表。仅在你有意允许任意模型时才使用 `"*"`。 +- `plugins.entries..config`:插件定义的配置对象(在可用时由原生 OpenClaw 插件 schema 验证)。 +- 渠道插件账户/运行时设置位于 `channels.` 下,应由所属插件 manifest 的 `channelConfigs` 元数据描述,而不是由中央 OpenClaw 选项注册表描述。 +- `plugins.entries.firecrawl.config.webFetch`:Firecrawl web-fetch 提供商设置。 + - `apiKey`:Firecrawl API key(接受 SecretRef)。会回退到 `plugins.entries.firecrawl.config.webSearch.apiKey`、旧版 `tools.web.fetch.firecrawl.apiKey` 或 `FIRECRAWL_API_KEY` 环境变量。 + - `baseUrl`:Firecrawl API base URL(默认值:`https://api.firecrawl.dev`)。 - `onlyMainContent`:仅提取页面主体内容(默认值:`true`)。 - `maxAgeMs`:最大缓存时长(毫秒)(默认值:`172800000` / 2 天)。 - `timeoutSeconds`:抓取请求超时时间(秒)(默认值:`60`)。 - `plugins.entries.xai.config.xSearch`:xAI X Search(Grok web search)设置。 - `enabled`:启用 X Search 提供商。 - `model`:用于搜索的 Grok 模型(例如 `"grok-4-1-fast"`)。 -- `plugins.entries.memory-core.config.dreaming`:内存 dreaming 设置。阶段和阈值请参见 [Dreaming](/zh-CN/concepts/dreaming)。 - - `enabled`:dreaming 总开关(默认值 `false`)。 +- `plugins.entries.memory-core.config.dreaming`:memory dreaming 设置。有关阶段和阈值,请参见 [Dreaming](/zh-CN/concepts/dreaming)。 + - `enabled`:dreaming 主开关(默认值 `false`)。 - `frequency`:每次完整 dreaming 扫描的 cron 频率(默认值为 `"0 3 * * *"`)。 - 阶段策略和阈值属于实现细节(不是面向用户的配置键)。 -- 完整内存配置位于 [内存配置参考](/zh-CN/reference/memory-config): +- 完整的 memory 配置位于 [Memory 配置参考](/zh-CN/reference/memory-config): - `agents.defaults.memorySearch.*` - `memory.backend` - `memory.citations` - `memory.qmd.*` - `plugins.entries.memory-core.config.dreaming` -- 已启用的 Claude bundle 插件也可以通过 `settings.json` 提供嵌入式 Pi 默认值;OpenClaw 会将其作为已净化的智能体设置应用,而不是作为原始 OpenClaw 配置补丁应用。 -- `plugins.slots.memory`:选择活动内存插件 id,或使用 `"none"` 禁用内存插件。 -- `plugins.slots.contextEngine`:选择活动上下文引擎插件 id;默认值为 `"legacy"`,除非你安装并选择了其他引擎。 +- 已启用的 Claude bundle 插件还可以通过 `settings.json` 提供嵌入式 Pi 默认值;OpenClaw 会将其作为已清洗的智能体设置应用,而不是作为原始 OpenClaw 配置补丁。 +- `plugins.slots.memory`:选择活动 memory 插件 id,或使用 `"none"` 禁用 memory 插件。 +- `plugins.slots.contextEngine`:选择活动 context engine 插件 id;默认值为 `"legacy"`,除非你安装并选择了其他引擎。 请参见 [插件](/zh-CN/tools/plugin)。 @@ -209,7 +208,7 @@ x-i18n: evaluateEnabled: true, defaultProfile: "user", ssrfPolicy: { - // dangerouslyAllowPrivateNetwork: true, // 仅在受信任的私有网络访问场景下启用 + // dangerouslyAllowPrivateNetwork: true, // 仅在受信任的私有网络访问场景下选择启用 // allowPrivateNetwork: true, // 旧版别名 // hostnameAllowlist: ["*.example.com", "example.com"], // allowedHostnames: ["localhost"], @@ -247,47 +246,45 @@ x-i18n: ``` - `evaluateEnabled: false` 会禁用 `act:evaluate` 和 `wait --fn`。 -- `tabCleanup` 会在空闲一段时间后,或当某个 - 会话超过上限时,回收已跟踪的主智能体标签页。将 `idleMinutes: 0` 或 `maxTabsPerSession: 0` 设为 - `0` 可分别禁用这些单独的清理模式。 -- 未设置时,`ssrfPolicy.dangerouslyAllowPrivateNetwork` 默认为禁用,因此浏览器导航在默认情况下会保持严格。 -- 仅当你明确信任私有网络浏览器导航时,才设置 `ssrfPolicy.dangerouslyAllowPrivateNetwork: true`。 -- 在严格模式下,远程 CDP 配置文件端点(`profiles.*.cdpUrl`)在可达性 / 发现检查期间也会受到相同的私有网络拦截限制。 -- `ssrfPolicy.allowPrivateNetwork` 仍然作为旧版别名受支持。 -- 在严格模式下,使用 `ssrfPolicy.hostnameAllowlist` 和 `ssrfPolicy.allowedHostnames` 来设置显式例外。 -- 远程配置文件仅支持附加模式(禁用 start / stop / reset)。 +- `tabCleanup` 会在空闲一段时间后,或当某个会话超过其上限时,回收已跟踪的主智能体标签页。将 `idleMinutes: 0` 或 `maxTabsPerSession: 0` 设为禁用对应的单独清理模式。 +- `ssrfPolicy.dangerouslyAllowPrivateNetwork` 在未设置时处于禁用状态,因此浏览器导航默认保持严格模式。 +- 仅当你有意信任私有网络浏览器导航时,才设置 `ssrfPolicy.dangerouslyAllowPrivateNetwork: true`。 +- 在严格模式下,远程 CDP 配置文件端点(`profiles.*.cdpUrl`)在可达性/发现检查期间也会受到同样的私有网络阻止。 +- `ssrfPolicy.allowPrivateNetwork` 仍作为旧版别名受到支持。 +- 在严格模式下,使用 `ssrfPolicy.hostnameAllowlist` 和 `ssrfPolicy.allowedHostnames` 添加显式例外。 +- 远程配置文件为仅附加模式(禁用 start/stop/reset)。 - `profiles.*.cdpUrl` 接受 `http://`、`https://`、`ws://` 和 `wss://`。 当你希望 OpenClaw 发现 `/json/version` 时,请使用 HTTP(S);当你的提供商直接提供 DevTools WebSocket URL 时,请使用 WS(S)。 -- `remoteCdpTimeoutMs` 和 `remoteCdpHandshakeTimeoutMs` 适用于远程以及 - `attachOnly` CDP 可达性和标签页打开请求。受管的 local loopback - 配置文件会继续使用本地 CDP 默认值。 -- 如果通过 loopback 可以访问某个外部管理的 CDP 服务,请将该 - 配置文件的 `attachOnly: true` 打开;否则 OpenClaw 会将该 loopback 端口视为 +- `remoteCdpTimeoutMs` 和 `remoteCdpHandshakeTimeoutMs` 适用于远程及 + `attachOnly` CDP 可达性,以及标签页打开请求。受管 local loopback + 配置文件继续使用本地 CDP 默认值。 +- 如果外部管理的 CDP 服务可通过 local loopback 访问,请将该 + 配置文件的 `attachOnly: true`;否则 OpenClaw 会将该 loopback 端口视为 本地受管浏览器配置文件,并可能报告本地端口归属错误。 - `existing-session` 配置文件使用 Chrome MCP 而不是 CDP,并且可以附加到 所选主机上,或通过已连接的浏览器节点附加。 - `existing-session` 配置文件可以设置 `userDataDir`,以指定某个特定的 - Chromium 系浏览器配置文件,例如 Brave 或 Edge。 + 基于 Chromium 的浏览器配置文件,例如 Brave 或 Edge。 - `existing-session` 配置文件保留当前 Chrome MCP 路由限制: - 使用 snapshot / ref 驱动的操作,而不是 CSS 选择器定位;仅支持单文件上传 - 钩子;不支持对话框超时覆盖;不支持 `wait --load networkidle`;也不支持 + 使用 snapshot/ref 驱动的操作,而不是 CSS 选择器定位;单文件上传 + 钩子;不支持对话框超时覆盖;不支持 `wait --load networkidle`;并且不支持 `responsebody`、PDF 导出、下载拦截或批量操作。 -- 本地受管的 `openclaw` 配置文件会自动分配 `cdpPort` 和 `cdpUrl`;只有在远程 CDP 场景下才需要显式设置 `cdpUrl`。 -- 本地受管配置文件可以设置 `executablePath`,以覆盖该配置文件的全局 - `browser.executablePath`。你可以借此让一个配置文件运行在 - Chrome 中,而另一个运行在 Brave 中。 -- 本地受管配置文件在进程启动后,会使用 `browser.localLaunchTimeoutMs` 进行 Chrome CDP HTTP - 发现,并使用 `browser.localCdpReadyTimeoutMs` 检查启动后 - CDP websocket 就绪情况。在较慢的主机上,如果 Chrome 能成功启动,但就绪检查和启动过程发生竞争, - 可以适当调高这些值。两个值都必须是 - 不超过 `120000` ms 的正整数;无效配置值会被拒绝。 -- 自动检测顺序:默认浏览器(如果是 Chromium 系)→ Chrome → Brave → Edge → Chromium → Chrome Canary。 -- `browser.executablePath` 和 `browser.profiles..executablePath` 都支持 - 在 Chromium 启动前使用 `~` 和 `~/...` 表示你的操作系统主目录。 - `existing-session` 配置文件中的按配置文件设置的 `userDataDir` 也支持波浪号展开。 -- 控制服务:仅限 loopback(端口由 `gateway.port` 派生,默认值为 `18791`)。 +- 本地受管 `openclaw` 配置文件会自动分配 `cdpPort` 和 `cdpUrl`;仅在远程 CDP 场景下才显式设置 `cdpUrl`。 +- 本地受管配置文件可设置 `executablePath`,以覆盖该配置文件的全局 + `browser.executablePath`。用它可以让一个配置文件运行在 Chrome 中, + 另一个运行在 Brave 中。 +- 本地受管配置文件在进程启动后使用 `browser.localLaunchTimeoutMs` 进行 Chrome CDP HTTP + 发现,并使用 `browser.localCdpReadyTimeoutMs` 检查启动后的 CDP websocket 就绪状态。 + 在较慢的主机上,如果 Chrome 已成功启动但就绪检查与启动过程竞争, + 可提高这些值。两个值都必须是最大不超过 `120000` ms 的正整数; + 无效配置值会被拒绝。 +- 自动检测顺序:默认浏览器(若基于 Chromium)→ Chrome → Brave → Edge → Chromium → Chrome Canary。 +- `browser.executablePath` 和 `browser.profiles..executablePath` 都 + 支持在 Chromium 启动前将 `~` 和 `~/...` 展开为你的操作系统主目录。 + `existing-session` 配置文件中的每配置文件 `userDataDir` 也支持波浪号展开。 +- Control 服务:仅限 loopback(端口派生自 `gateway.port`,默认值为 `18791`)。 - `extraArgs` 会为本地 Chromium 启动附加额外的启动标志(例如 - `--disable-gpu`、窗口大小设置或调试标志)。 + `--disable-gpu`、窗口尺寸设置或调试标志)。 --- @@ -299,14 +296,14 @@ x-i18n: seamColor: "#FF4500", assistant: { name: "OpenClaw", - avatar: "CB", // emoji、短文本、图片 URL 或 data URI + avatar: "CB", // emoji、简短文本、图片 URL 或 data URI }, }, } ``` -- `seamColor`:原生应用 UI 外壳的强调色(Talk Mode 气泡着色等)。 -- `assistant`:Control UI 身份覆盖。会回退到当前激活的智能体身份。 +- `seamColor`:原生应用 UI 外框的强调色(Talk 模式气泡着色等)。 +- `assistant`:Control UI 身份覆盖。会回退到当前活动智能体身份。 --- @@ -341,8 +338,8 @@ x-i18n: // root: "dist/control-ui", // embedSandbox: "scripts", // strict | scripts | trusted // allowExternalEmbedUrls: false, // 危险:允许绝对外部 http(s) 嵌入 URL - // allowedOrigins: ["https://control.example.com"], // 非 loopback Control UI 必填 - // dangerouslyAllowHostHeaderOriginFallback: false, // 危险的 Host 标头 origin 回退模式 + // allowedOrigins: ["https://control.example.com"], // 非 loopback Control UI 必需 + // dangerouslyAllowHostHeaderOriginFallback: false, // 危险的 Host 头 origin 回退模式 // allowInsecureAuth: false, // dangerouslyDisableDeviceAuth: false, }, @@ -357,7 +354,7 @@ x-i18n: allowRealIpFallback: false, nodes: { pairing: { - // 可选。默认未设置 / 禁用。 + // 可选。默认未设置/禁用。 autoApproveCidrs: ["192.168.1.0/24", "fd00:1234:5678::/64"], }, allowCommands: ["canvas.navigate"], @@ -381,57 +378,57 @@ x-i18n: } ``` - + -- `mode`:`local`(运行 Gateway 网关)或 `remote`(连接到远程 Gateway 网关)。只有在 `local` 模式下,Gateway 网关才允许启动。 +- `mode`:`local`(运行 Gateway 网关)或 `remote`(连接到远程 Gateway 网关)。除非为 `local`,否则 Gateway 网关拒绝启动。 - `port`:用于 WS + HTTP 的单一复用端口。优先级:`--port` > `OPENCLAW_GATEWAY_PORT` > `gateway.port` > `18789`。 - `bind`:`auto`、`loopback`(默认)、`lan`(`0.0.0.0`)、`tailnet`(仅 Tailscale IP)或 `custom`。 - **旧版 bind 别名**:请在 `gateway.bind` 中使用 bind 模式值(`auto`、`loopback`、`lan`、`tailnet`、`custom`),不要使用主机别名(`0.0.0.0`、`127.0.0.1`、`localhost`、`::`、`::1`)。 -- **Docker 注意事项**:默认的 `loopback` bind 会在容器内监听 `127.0.0.1`。在 Docker bridge 网络(`-p 18789:18789`)下,流量会到达 `eth0`,因此 Gateway 网关无法访问。请使用 `--network host`,或设置 `bind: "lan"`(或设置 `bind: "custom"` 并配合 `customBindHost: "0.0.0.0"`)以监听所有接口。 -- **身份验证**:默认必需。非 loopback bind 必须启用 Gateway 网关身份验证。实际使用中,这意味着共享 token / password,或使用设置了 `gateway.auth.mode: "trusted-proxy"` 的身份感知反向代理。新手引导向导默认会生成 token。 -- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`(包括 SecretRef),必须显式设置 `gateway.auth.mode` 为 `token` 或 `password`。如果两者都已配置但未设置 mode,启动以及服务安装 / 修复流程都会失败。 -- `gateway.auth.mode: "none"`:显式无认证模式。仅适用于受信任的本地 local loopback 部署;新手引导提示中不会故意提供此选项。 -- `gateway.auth.mode: "trusted-proxy"`:将认证委托给身份感知反向代理,并信任来自 `gateway.trustedProxies` 的身份标头(参见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth))。此模式要求代理来源为**非 loopback**;同主机 loopback 反向代理不满足 trusted-proxy 认证要求。 -- `gateway.auth.allowTailscale`:当为 `true` 时,Tailscale Serve 身份标头可满足 Control UI / WebSocket 认证(通过 `tailscale whois` 验证)。HTTP API 端点**不会**使用该 Tailscale 标头认证;它们仍遵循 Gateway 网关的常规 HTTP 认证模式。此无 token 流程假定 Gateway 网关主机是受信任的。当 `tailscale.mode = "serve"` 时默认值为 `true`。 -- `gateway.auth.rateLimit`:可选的认证失败限速器。按客户端 IP 和认证作用域生效(共享密钥和设备 token 分别独立跟踪)。被阻止的尝试会返回 `429` + `Retry-After`。 - - 在异步 Tailscale Serve Control UI 路径上,针对相同 `{scope, clientIp}` 的失败尝试会在写入失败记录前进行串行化。因此,同一客户端的并发错误尝试可能会在第二个请求时触发限速,而不是两个请求都作为普通不匹配竞争通过。 - - `gateway.auth.rateLimit.exemptLoopback` 默认值为 `true`;如果你明确希望 localhost 流量也受到限速(例如测试环境或严格代理部署),请设为 `false`。 -- 来自浏览器来源的 WS 认证尝试始终会启用限流,并禁用 loopback 豁免(作为针对浏览器发起 localhost 暴力破解的纵深防御)。 -- 在 loopback 上,这些来自浏览器来源的锁定会按规范化后的 `Origin` - 值彼此隔离,因此来自某个 localhost origin 的重复失败 - 不会自动锁定另一个 origin。 -- `tailscale.mode`:`serve`(仅 tailnet,loopback bind)或 `funnel`(公开访问,要求认证)。 -- `controlUi.allowedOrigins`:用于 Gateway 网关 WebSocket 连接的显式浏览器来源允许列表。当预期浏览器客户端来自非 loopback origin 时为必填项。 -- `controlUi.dangerouslyAllowHostHeaderOriginFallback`:危险模式,为有意依赖 Host 标头 origin 策略的部署启用 Host 标头 origin 回退。 -- `remote.transport`:`ssh`(默认)或 `direct`(ws / wss)。对于 `direct`,`remote.url` 必须是 `ws://` 或 `wss://`。 -- `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`:客户端进程环境变量级别的紧急开关覆盖项, - 允许对受信任私有网络 IP 使用明文 `ws://`;默认情况下,明文连接仍仅限 loopback。没有与之对应的 `openclaw.json` - 配置项,且浏览器私有网络配置(例如 - `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork`)也不会影响 Gateway 网关 +- **Docker 注意事项**:默认的 `loopback` bind 会在容器内监听 `127.0.0.1`。在 Docker bridge 网络(`-p 18789:18789`)下,流量会到达 `eth0`,因此 Gateway 网关不可访问。请使用 `--network host`,或设置 `bind: "lan"`(或设置 `bind: "custom"` 并配合 `customBindHost: "0.0.0.0"`)以监听所有接口。 +- **认证**:默认必须启用。非 loopback bind 需要 Gateway 网关认证。实际使用中,这意味着共享 token/password,或使用设置了 `gateway.auth.mode: "trusted-proxy"` 的身份感知型反向代理。新手引导向导默认会生成一个 token。 +- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`(包括 SecretRef),请将 `gateway.auth.mode` 显式设为 `token` 或 `password`。当两者都已配置且未设置 mode 时,启动以及服务安装/修复流程都会失败。 +- `gateway.auth.mode: "none"`:显式无认证模式。仅可用于受信任的本地 local loopback 设置;新手引导提示中不会提供此选项。 +- `gateway.auth.mode: "trusted-proxy"`:将认证委托给身份感知型反向代理,并信任来自 `gateway.trustedProxies` 的身份头(参见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth))。此模式要求代理来源为**非 loopback**;同主机上的 loopback 反向代理不能满足 trusted-proxy 认证要求。 +- `gateway.auth.allowTailscale`:当为 `true` 时,Tailscale Serve 身份头可用于满足 Control UI/WebSocket 认证(通过 `tailscale whois` 验证)。HTTP API 端点**不会**使用该 Tailscale 头认证;它们仍遵循 Gateway 网关的常规 HTTP 认证模式。当 `tailscale.mode = "serve"` 时,默认值为 `true`。 +- `gateway.auth.rateLimit`:可选的认证失败限流器。按客户端 IP 和认证作用域生效(共享密钥和设备 token 分别独立跟踪)。被阻止的尝试会返回 `429` + `Retry-After`。 + - 在异步 Tailscale Serve Control UI 路径上,相同 `{scope, clientIp}` 的失败尝试会在写入失败前被串行化。因此,同一客户端的并发错误尝试可能会在第二个请求时触发限流,而不是两个请求都竞态通过并仅作为普通不匹配处理。 + - `gateway.auth.rateLimit.exemptLoopback` 默认值为 `true`;如果你有意也要对 localhost 流量启用限流(例如用于测试设置或严格代理部署),请将其设为 `false`。 +- 来自浏览器源的 WS 认证尝试始终会启用限流,且不会豁免 loopback(作为针对基于浏览器的 localhost 暴力破解的纵深防御)。 +- 在 loopback 上,这些来自浏览器源的锁定会按规范化后的 `Origin` + 值隔离,因此来自某个 localhost origin 的重复失败不会自动 + 锁定另一个 origin。 +- `tailscale.mode`:`serve`(仅 tailnet,loopback bind)或 `funnel`(公开访问,需要认证)。 +- `controlUi.allowedOrigins`:用于 Gateway 网关 WebSocket 连接的显式浏览器源允许列表。当预期浏览器客户端来自非 loopback origin 时必须设置。 +- `controlUi.dangerouslyAllowHostHeaderOriginFallback`:危险模式,为那些有意依赖 Host 头 origin 策略的部署启用 Host 头 origin 回退。 +- `remote.transport`:`ssh`(默认)或 `direct`(ws/wss)。对于 `direct`,`remote.url` 必须是 `ws://` 或 `wss://`。 +- `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`:客户端进程环境中的紧急放行覆盖, + 允许以明文 `ws://` 连接到受信任的私有网络 IP;默认情况下,明文连接仍仅限 loopback。 + 没有对应的 `openclaw.json` 配置项,且浏览器私有网络配置,例如 + `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork`,不会影响 Gateway 网关 WebSocket 客户端。 -- `gateway.remote.token` / `.password` 是远程客户端凭证字段。它们本身不会配置 Gateway 网关认证。 -- `gateway.push.apns.relay.baseUrl`:官方 / TestFlight iOS 构建在向 Gateway 网关发布基于 relay 的注册后,用于外部 APNs relay 的基础 HTTPS URL。此 URL 必须与编译进 iOS 构建中的 relay URL 一致。 +- `gateway.remote.token` / `.password`:远程客户端凭证字段。它们本身不会配置 Gateway 网关认证。 +- `gateway.push.apns.relay.baseUrl`:外部 APNs relay 的基础 HTTPS URL,供官方/TestFlight iOS 构建在将基于 relay 的注册发布到 Gateway 网关后使用。此 URL 必须与编译进 iOS 构建中的 relay URL 一致。 - `gateway.push.apns.relay.timeoutMs`:Gateway 网关到 relay 的发送超时时间(毫秒)。默认值为 `10000`。 -- 基于 relay 的注册会委派给特定的 Gateway 网关身份。已配对的 iOS 应用会获取 `gateway.identity.get`,在 relay 注册中包含该身份,并将按注册范围限定的发送授权转发给 Gateway 网关。其他 Gateway 网关无法复用该已存储的注册。 -- `OPENCLAW_APNS_RELAY_BASE_URL` / `OPENCLAW_APNS_RELAY_TIMEOUT_MS`:上述 relay 配置的临时环境变量覆盖项。 -- `OPENCLAW_APNS_RELAY_ALLOW_HTTP=true`:仅供开发使用的逃生舱配置,用于 loopback HTTP relay URL。生产 relay URL 应保持使用 HTTPS。 +- 基于 relay 的注册会委托给某个特定的 Gateway 网关身份。已配对的 iOS 应用会获取 `gateway.identity.get`,在 relay 注册中包含该身份,并向 Gateway 网关转发作用域限定为该注册的发送授权。另一个 Gateway 网关不能复用该已存储注册。 +- `OPENCLAW_APNS_RELAY_BASE_URL` / `OPENCLAW_APNS_RELAY_TIMEOUT_MS`:用于覆盖上述 relay 配置的临时环境变量。 +- `OPENCLAW_APNS_RELAY_ALLOW_HTTP=true`:仅用于开发环境的逃生口,允许使用 loopback HTTP relay URL。生产环境 relay URL 应保持为 HTTPS。 - `gateway.channelHealthCheckMinutes`:渠道健康监控间隔(分钟)。设为 `0` 可全局禁用健康监控重启。默认值:`5`。 -- `gateway.channelStaleEventThresholdMinutes`:陈旧 socket 阈值(分钟)。应保持大于或等于 `gateway.channelHealthCheckMinutes`。默认值:`30`。 -- `gateway.channelMaxRestartsPerHour`:按滚动一小时计算,每个渠道 / 账号允许的最大健康监控重启次数。默认值:`10`。 -- `channels..healthMonitor.enabled`:按渠道设置,用于在保持全局监控启用的同时,选择不启用健康监控重启。 -- `channels..accounts..healthMonitor.enabled`:多账号渠道的按账号覆盖项。设置后,其优先级高于渠道级覆盖项。 -- 仅当 `gateway.auth.*` 未设置时,本地 Gateway 网关调用路径才可以将 `gateway.remote.*` 用作回退。 -- 如果通过 SecretRef 显式配置了 `gateway.auth.token` / `gateway.auth.password` 但无法解析,解析会以关闭方式失败(不会用远程回退来掩盖问题)。 -- `trustedProxies`:终止 TLS 或注入转发客户端标头的反向代理 IP。这里只应列出你控制的代理。loopback 条目对于同主机代理 / 本地检测场景仍然有效(例如 Tailscale Serve 或本地反向代理),但它们**不会**使 loopback 请求符合 `gateway.auth.mode: "trusted-proxy"` 的条件。 -- `allowRealIpFallback`:当为 `true` 时,如果缺少 `X-Forwarded-For`,Gateway 网关会接受 `X-Real-IP`。默认值为 `false`,以保持失败即关闭的行为。 -- `gateway.nodes.pairing.autoApproveCidrs`:可选的 CIDR / IP 允许列表,用于自动批准首次节点设备配对,前提是未请求任何作用域。未设置时为禁用。此设置不会自动批准 operator / browser / Control UI / WebChat 配对,也不会自动批准角色、作用域、元数据或公钥升级。 -- `gateway.nodes.allowCommands` / `gateway.nodes.denyCommands`:在完成配对和允许列表评估后,对已声明节点命令进行全局 allow / deny 约束。 -- `gateway.tools.deny`:对 HTTP `POST /tools/invoke` 额外阻止的工具名(扩展默认拒绝列表)。 -- `gateway.tools.allow`:从默认 HTTP 拒绝列表中移除工具名。 +- `gateway.channelStaleEventThresholdMinutes`:陈旧 socket 阈值(分钟)。请确保其大于或等于 `gateway.channelHealthCheckMinutes`。默认值:`30`。 +- `gateway.channelMaxRestartsPerHour`:每个渠道/账户在滚动一小时内的最大健康监控重启次数。默认值:`10`。 +- `channels..healthMonitor.enabled`:在保持全局监控启用的同时,对单个渠道选择退出健康监控重启。 +- `channels..accounts..healthMonitor.enabled`:多账户渠道的逐账户覆盖。设置后,其优先级高于渠道级覆盖。 +- 仅当 `gateway.auth.*` 未设置时,本地 Gateway 网关调用路径才可将 `gateway.remote.*` 用作回退。 +- 如果通过 SecretRef 显式配置了 `gateway.auth.token` / `gateway.auth.password` 但无法解析,则解析会以关闭方式失败(不会被远程回退掩盖)。 +- `trustedProxies`:终止 TLS 或注入转发客户端头的反向代理 IP。只应列出你控制的代理。loopback 条目对于同主机代理/本地检测设置仍然有效(例如 Tailscale Serve 或本地反向代理),但它们**不会**使 loopback 请求具备 `gateway.auth.mode: "trusted-proxy"` 的适用资格。 +- `allowRealIpFallback`:当为 `true` 时,如果缺少 `X-Forwarded-For`,Gateway 网关会接受 `X-Real-IP`。默认值为 `false`,以保持关闭式失败行为。 +- `gateway.nodes.pairing.autoApproveCidrs`:用于自动批准首次节点设备配对的可选 CIDR/IP 允许列表,前提是未请求任何作用域。未设置时即禁用。它不会自动批准 operator/browser/Control UI/WebChat 配对,也不会自动批准角色、作用域、元数据或公钥升级。 +- `gateway.nodes.allowCommands` / `gateway.nodes.denyCommands`:在配对和允许列表评估之后,对已声明节点命令进行全局允许/拒绝整形。 +- `gateway.tools.deny`:对 HTTP `POST /tools/invoke` 额外阻止的工具名称(在默认拒绝列表基础上扩展)。 +- `gateway.tools.allow`:从默认 HTTP 拒绝列表中移除工具名称。 -### OpenAI-compatible endpoints +### OpenAI 兼容端点 - Chat Completions:默认禁用。使用 `gateway.http.endpoints.chatCompletions.enabled: true` 启用。 - Responses API:`gateway.http.endpoints.responses.enabled`。 @@ -439,14 +436,14 @@ x-i18n: - `gateway.http.endpoints.responses.maxUrlParts` - `gateway.http.endpoints.responses.files.urlAllowlist` - `gateway.http.endpoints.responses.images.urlAllowlist` - 空的允许列表会被视为未设置;如需禁用 URL 抓取,请使用 `gateway.http.endpoints.responses.files.allowUrl=false` - 和 / 或 `gateway.http.endpoints.responses.images.allowUrl=false`。 -- 可选响应加固标头: - - `gateway.http.securityHeaders.strictTransportSecurity`(仅对你控制的 HTTPS 来源设置;参见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth#tls-termination-and-hsts)) + 空允许列表会被视为未设置;如需禁用 URL 抓取,请使用 `gateway.http.endpoints.responses.files.allowUrl=false` + 和/或 `gateway.http.endpoints.responses.images.allowUrl=false`。 +- 可选的响应加固头: + - `gateway.http.securityHeaders.strictTransportSecurity`(仅在你控制的 HTTPS origin 上设置;参见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth#tls-termination-and-hsts)) ### 多实例隔离 -在同一主机上运行多个 Gateway 网关时,请使用不同的端口和状态目录: +在同一主机上运行多个 Gateway 网关时,请使用唯一的端口和状态目录: ```bash OPENCLAW_CONFIG_PATH=~/.openclaw/a.json \ @@ -456,7 +453,7 @@ openclaw gateway --port 19001 便捷标志:`--dev`(使用 `~/.openclaw-dev` + 端口 `19001`)、`--profile `(使用 `~/.openclaw-`)。 -请参见 [Multiple Gateways](/zh-CN/gateway/multiple-gateways)。 +请参见 [多个 Gateway 网关](/zh-CN/gateway/multiple-gateways)。 ### `gateway.tls` @@ -474,10 +471,10 @@ openclaw gateway --port 19001 } ``` -- `enabled`:在 Gateway 网关监听器上启用 TLS 终止(HTTPS / WSS)(默认值:`false`)。 -- `autoGenerate`:当未配置显式文件时,自动生成本地自签名 cert / key 对;仅适用于本地 / 开发用途。 +- `enabled`:在 Gateway 网关监听器上启用 TLS 终止(HTTPS/WSS)(默认值:`false`)。 +- `autoGenerate`:当未配置显式文件时,自动生成本地自签名证书/密钥对;仅供本地/开发环境使用。 - `certPath`:TLS 证书文件的文件系统路径。 -- `keyPath`:TLS 私钥文件的文件系统路径;应限制文件权限。 +- `keyPath`:TLS 私钥文件的文件系统路径;应限制权限。 - `caPath`:可选的 CA bundle 路径,用于客户端验证或自定义信任链。 ### `gateway.reload` @@ -494,17 +491,17 @@ openclaw gateway --port 19001 } ``` -- `mode`:控制如何在运行时应用配置编辑。 - - `"off"`:忽略实时编辑;变更需要显式重启。 +- `mode`:控制配置编辑如何在运行时应用。 + - `"off"`:忽略实时编辑;更改需要显式重启。 - `"restart"`:配置变更时始终重启 Gateway 网关进程。 - - `"hot"`:在不重启的情况下于进程内应用变更。 - - `"hybrid"`(默认):先尝试热重载;如有需要则回退为重启。 + - `"hot"`:在不重启的情况下进程内应用更改。 + - `"hybrid"`(默认):先尝试热重载;如有需要再回退到重启。 - `debounceMs`:应用配置变更前的防抖窗口(毫秒)(非负整数)。 -- `deferralTimeoutMs`:可选的最大等待时间(毫秒),用于等待进行中的操作完成,超时后强制重启。省略或设为 `0` 表示无限等待,并定期记录仍在等待中的警告。 +- `deferralTimeoutMs`:可选的最大等待时间(毫秒),用于等待正在进行的操作完成,然后才强制重启。省略或设为 `0` 表示无限等待,并定期记录“仍在等待”的警告。 --- -## Hooks +## 钩子 ```json5 { @@ -538,46 +535,46 @@ openclaw gateway --port 19001 ``` 认证:`Authorization: Bearer ` 或 `x-openclaw-token: `。 -拒绝使用查询字符串中的 hook token。 +拒绝使用查询字符串 hook token。 -校验和安全说明: +验证和安全说明: -- `hooks.enabled=true` 要求 `hooks.token` 为非空值。 -- `hooks.token` 必须与 `gateway.auth.token` **不同**;重用 Gateway 网关 token 会被拒绝。 +- `hooks.enabled=true` 要求 `hooks.token` 为非空。 +- `hooks.token` 必须与 `gateway.auth.token` **不同**;拒绝复用 Gateway 网关 token。 - `hooks.path` 不能为 `/`;请使用专用子路径,例如 `/hooks`。 -- 如果 `hooks.allowRequestSessionKey=true`,请限制 `hooks.allowedSessionKeyPrefixes`(例如 `["hook:"]`)。 -- 如果某个映射或预设使用模板化的 `sessionKey`,请设置 `hooks.allowedSessionKeyPrefixes` 并启用 `hooks.allowRequestSessionKey=true`。静态映射键不需要这一显式启用。 +- 如果 `hooks.allowRequestSessionKey=true`,请约束 `hooks.allowedSessionKeyPrefixes`(例如 `["hook:"]`)。 +- 如果某个 mapping 或 preset 使用模板化的 `sessionKey`,请设置 `hooks.allowedSessionKeyPrefixes` 和 `hooks.allowRequestSessionKey=true`。静态 mapping 键不需要此显式启用。 **端点:** - `POST /hooks/wake` → `{ text, mode?: "now"|"next-heartbeat" }` - `POST /hooks/agent` → `{ message, name?, agentId?, sessionKey?, wakeMode?, deliver?, channel?, to?, model?, thinking?, timeoutSeconds? }` - - 仅当 `hooks.allowRequestSessionKey=true` 时,才接受请求负载中的 `sessionKey`(默认值:`false`)。 + - 仅当 `hooks.allowRequestSessionKey=true` 时,才接受请求载荷中的 `sessionKey`(默认值:`false`)。 - `POST /hooks/` → 通过 `hooks.mappings` 解析 - - 模板渲染得到的映射 `sessionKey` 值会被视为外部提供,因此同样要求 `hooks.allowRequestSessionKey=true`。 + - 通过模板渲染的 mapping `sessionKey` 值会被视为外部提供,因此同样要求 `hooks.allowRequestSessionKey=true`。 - `match.path` 匹配 `/hooks` 之后的子路径(例如 `/hooks/gmail` → `gmail`)。 -- `match.source` 匹配通用路径中的某个负载字段。 -- 类似 `{{messages[0].subject}}` 的模板会从负载中读取。 -- `transform` 可以指向一个返回 hook 动作的 JS / TS 模块。 - - `transform.module` 必须是相对路径,并且必须位于 `hooks.transformsDir` 内(绝对路径和路径穿越会被拒绝)。 -- `agentId` 会路由到特定智能体;未知 ID 会回退到默认值。 +- `match.source` 匹配通用路径的某个载荷字段。 +- 类似 `{{messages[0].subject}}` 这样的模板会从载荷中读取。 +- `transform` 可以指向一个返回 hook 动作的 JS/TS 模块。 + - `transform.module` 必须是相对路径,并且保持在 `hooks.transformsDir` 内(绝对路径和路径穿越会被拒绝)。 +- `agentId` 会路由到指定智能体;未知 ID 会回退到默认值。 - `allowedAgentIds`:限制显式路由(`*` 或省略 = 允许全部,`[]` = 全部拒绝)。 -- `defaultSessionKey`:可选的固定会话键,用于未显式设置 `sessionKey` 的 hook 智能体运行。 +- `defaultSessionKey`:可选的固定会话键,用于没有显式 `sessionKey` 的 hook 智能体运行。 - `allowRequestSessionKey`:允许 `/hooks/agent` 调用方以及模板驱动的映射会话键设置 `sessionKey`(默认值:`false`)。 -- `allowedSessionKeyPrefixes`:用于显式 `sessionKey` 值(请求 + 映射)的可选前缀允许列表,例如 `["hook:"]`。当任意映射或预设使用模板化 `sessionKey` 时,这一项会变为必需。 -- `deliver: true` 会将最终回复发送到某个渠道;`channel` 默认值为 `last`。 -- `model`:覆盖此次 hook 运行使用的 LLM(如果设置了模型目录,则该模型必须在允许范围内)。 +- `allowedSessionKeyPrefixes`:显式 `sessionKey` 值(请求 + 映射)的可选前缀允许列表,例如 `["hook:"]`。当任意映射或 preset 使用模板化 `sessionKey` 时,它会变为必填项。 +- `deliver: true` 会将最终回复发送到某个渠道;`channel` 默认为 `last`。 +- `model` 会覆盖本次 hook 运行的 LLM(如果设置了模型目录,则该模型必须被允许)。 ### Gmail 集成 -- 内置 Gmail 预设使用 `sessionKey: "hook:gmail:{{messages[0].id}}"`。 -- 如果你保留这种按消息路由的方式,请设置 `hooks.allowRequestSessionKey: true`,并将 `hooks.allowedSessionKeyPrefixes` 限制为匹配 Gmail 命名空间,例如 `["hook:", "hook:gmail:"]`。 -- 如果你需要 `hooks.allowRequestSessionKey: false`,请用静态 `sessionKey` 覆盖该预设,而不是使用默认的模板化值。 +- 内置 Gmail preset 使用 `sessionKey: "hook:gmail:{{messages[0].id}}"`。 +- 如果你保留这种按消息路由的方式,请设置 `hooks.allowRequestSessionKey: true`,并约束 `hooks.allowedSessionKeyPrefixes` 以匹配 Gmail 命名空间,例如 `["hook:", "hook:gmail:"]`。 +- 如果你需要 `hooks.allowRequestSessionKey: false`,请用静态 `sessionKey` 覆盖该 preset,而不是使用模板化默认值。 ```json5 { @@ -600,8 +597,8 @@ openclaw gateway --port 19001 } ``` -- 配置后,Gateway 网关会在启动时自动启动 `gog gmail watch serve`。如需禁用,请设置 `OPENCLAW_SKIP_GMAIL_WATCHER=1`。 -- 不要在 Gateway 网关旁边额外运行单独的 `gog gmail watch serve`。 +- 配置后,Gateway 网关会在启动时自动启动 `gog gmail watch serve`。设置 `OPENCLAW_SKIP_GMAIL_WATCHER=1` 可禁用。 +- 不要在 Gateway 网关旁边单独运行另一个 `gog gmail watch serve`。 --- @@ -617,18 +614,18 @@ openclaw gateway --port 19001 } ``` -- 通过 Gateway 网关端口下的 HTTP 提供智能体可编辑的 HTML / CSS / JS 和 A2UI: +- 通过 Gateway 网关端口下的 HTTP 提供由智能体可编辑的 HTML/CSS/JS 和 A2UI: - `http://:/__openclaw__/canvas/` - `http://:/__openclaw__/a2ui/` -- 仅限本地:保持 `gateway.bind: "loopback"`(默认值)。 -- 非 loopback bind:canvas 路由和其他 Gateway 网关 HTTP 表面一样,要求 Gateway 网关认证(token / password / trusted-proxy)。 -- 节点 WebView 通常不会发送认证标头;节点完成配对并连接后,Gateway 网关会为 canvas / A2UI 访问发布按节点作用域限定的能力 URL。 -- 能力 URL 绑定到当前活动的节点 WS 会话,并且会很快过期。不使用基于 IP 的回退。 -- 会向所提供的 HTML 中注入实时重载客户端。 +- 仅限本地:保持 `gateway.bind: "loopback"`(默认)。 +- 非 loopback bind:canvas 路由与其他 Gateway 网关 HTTP 表面一样,要求 Gateway 网关认证(token/password/trusted-proxy)。 +- 节点 WebView 通常不会发送认证头;当某个节点完成配对并连接后,Gateway 网关会为 canvas/A2UI 访问公布节点作用域的 capability URL。 +- capability URL 绑定到当前活动的节点 WS 会话,并且会很快过期。不使用基于 IP 的回退。 +- 会将 live-reload 客户端注入到所提供的 HTML 中。 - 为空时会自动创建初始 `index.html`。 -- 也会在 `/__openclaw__/a2ui/` 下提供 A2UI。 -- 变更需要重启 Gateway 网关。 -- 对于大型目录或出现 `EMFILE` 错误时,请禁用实时重载。 +- 同时也会在 `/__openclaw__/a2ui/` 提供 A2UI。 +- 更改需要重启 Gateway 网关。 +- 对于大型目录或 `EMFILE` 错误,请禁用 live reload。 --- @@ -646,7 +643,7 @@ openclaw gateway --port 19001 } ``` -- `minimal`(默认):在 TXT 记录中省略 `cliPath` + `sshPort`。 +- `minimal`(默认):从 TXT 记录中省略 `cliPath` + `sshPort`。 - `full`:包含 `cliPath` + `sshPort`。 - 主机名默认为 `openclaw`。可通过 `OPENCLAW_MDNS_HOSTNAME` 覆盖。 @@ -660,7 +657,7 @@ openclaw gateway --port 19001 } ``` -会在 `~/.openclaw/dns/` 下写入单播 DNS-SD 区域。对于跨网络设备发现,请配合 DNS 服务器(推荐 CoreDNS)+ Tailscale split DNS。 +会在 `~/.openclaw/dns/` 下写入单播 DNS-SD 区域。对于跨网络设备发现,请搭配 DNS 服务器(推荐 CoreDNS)+ Tailscale split DNS。 设置:`openclaw dns setup --apply`。 @@ -685,14 +682,14 @@ openclaw gateway --port 19001 } ``` -- 仅当进程环境中缺少某个键时,才会应用内联环境变量。 -- `.env` 文件:当前工作目录下的 `.env` + `~/.openclaw/.env`(两者都不会覆盖现有变量)。 +- 仅当进程环境中缺少该键时,才会应用内联环境变量。 +- `.env` 文件:当前工作目录 `.env` + `~/.openclaw/.env`(两者都不会覆盖现有变量)。 - `shellEnv`:从你的登录 shell 配置文件中导入缺失的预期键名。 - 完整优先级请参见 [环境](/zh-CN/help/environment)。 ### 环境变量替换 -可以在任意配置字符串中使用 `${VAR_NAME}` 引用环境变量: +可在任意配置字符串中使用 `${VAR_NAME}` 引用环境变量: ```json5 { @@ -703,39 +700,39 @@ openclaw gateway --port 19001 ``` - 仅匹配大写名称:`[A-Z_][A-Z0-9_]*`。 -- 缺失 / 为空的变量会在配置加载时抛出错误。 +- 缺失/空变量会在配置加载时抛出错误。 - 使用 `$${VAR}` 可转义为字面量 `${VAR}`。 - 适用于 `$include`。 --- -## Secrets +## 密钥 -SecretRef 是增量式的:纯文本值仍然可用。 +SecretRef 采用增量方式:明文值仍然可用。 ### `SecretRef` -使用如下对象结构: +使用以下对象形状: ```json5 { source: "env" | "file" | "exec", provider: "default", id: "..." } ``` -校验规则: +验证规则: - `provider` 模式:`^[a-z][a-z0-9_-]{0,63}$` - `source: "env"` 的 id 模式:`^[A-Z][A-Z0-9_]{0,127}$` -- `source: "file"` 的 id:绝对 JSON 指针(例如 `"/providers/openai/apiKey"`) +- `source: "file"` 的 id:绝对 JSON pointer(例如 `"/providers/openai/apiKey"`) - `source: "exec"` 的 id 模式:`^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$` -- `source: "exec"` 的 id 不得包含以斜杠分隔的 `.` 或 `..` 路径段(例如 `a/../b` 会被拒绝) +- `source: "exec"` 的 id 不得包含 `.` 或 `..` 这样的斜杠分隔路径段(例如 `a/../b` 会被拒绝) ### 支持的凭证表面 - 规范矩阵:[SecretRef 凭证表面](/zh-CN/reference/secretref-credential-surface) -- `secrets apply` 会作用于受支持的 `openclaw.json` 凭证路径。 -- `auth-profiles.json` 中的引用也包含在运行时解析和审计覆盖范围内。 +- `secrets apply` 以受支持的 `openclaw.json` 凭证路径为目标。 +- `auth-profiles.json` 引用已纳入运行时解析和审计覆盖范围。 -### Secret 提供商配置 +### 密钥提供商配置 ```json5 { @@ -765,14 +762,14 @@ SecretRef 是增量式的:纯文本值仍然可用。 说明: -- `file` 提供商支持 `mode: "json"` 和 `mode: "singleValue"`(在 singleValue 模式下,`id` 必须为 `"value"`)。 -- 当 Windows ACL 校验不可用时,file 和 exec 提供商路径会以关闭方式失败。仅当路径受信任且无法校验时,才设置 `allowInsecurePath: true`。 -- `exec` 提供商要求 `command` 为绝对路径,并通过 stdin / stdout 上传输协议负载。 -- 默认情况下,符号链接命令路径会被拒绝。设置 `allowSymlinkCommand: true` 后,可允许符号链接路径,同时仍会校验其解析后的目标路径。 -- 如果配置了 `trustedDirs`,受信任目录检查会作用于解析后的目标路径。 -- `exec` 子进程环境默认最小化;所需变量请通过 `passEnv` 显式传递。 -- Secret 引用会在激活时解析为内存快照,之后请求路径只会读取该快照。 -- 激活期间会应用活动表面过滤:启用表面上的未解析引用会导致启动 / 重载失败,而非活动表面会被跳过并记录诊断信息。 +- `file` 提供商支持 `mode: "json"` 和 `mode: "singleValue"`(在 singleValue 模式下,`id` 必须是 `"value"`)。 +- 当 Windows ACL 验证不可用时,file 和 exec 提供商路径会以关闭方式失败。仅对那些无法验证但你信任的路径设置 `allowInsecurePath: true`。 +- `exec` 提供商要求 `command` 使用绝对路径,并通过 stdin/stdout 传递协议载荷。 +- 默认情况下,会拒绝符号链接命令路径。设置 `allowSymlinkCommand: true` 可允许符号链接路径,同时仍会验证解析后的目标路径。 +- 如果配置了 `trustedDirs`,则受信任目录检查会应用到解析后的目标路径。 +- `exec` 子进程环境默认最小化;请使用 `passEnv` 显式传递所需变量。 +- SecretRef 会在激活时解析为内存中的快照,此后请求路径仅读取该快照。 +- 激活期间会应用活动表面过滤:启用表面上的未解析引用会导致启动/重载失败,而未激活表面会被跳过并附带诊断信息。 --- @@ -794,13 +791,13 @@ SecretRef 是增量式的:纯文本值仍然可用。 } ``` -- 每个智能体的配置文件存储在 `/auth-profiles.json`。 -- `auth-profiles.json` 支持值级引用(静态凭证模式下,`api_key` 使用 `keyRef`,`token` 使用 `tokenRef`)。 -- OAuth 模式配置文件(`auth.profiles..mode = "oauth"`)不支持由 SecretRef 支持的 auth-profile 凭证。 -- 静态运行时凭证来自已解析的内存快照;发现旧版静态 `auth.json` 条目时会清理。 +- 每个智能体的 profile 存储在 `/auth-profiles.json`。 +- `auth-profiles.json` 支持值级引用(静态凭证模式中,`api_key` 使用 `keyRef`,`token` 使用 `tokenRef`)。 +- OAuth 模式 profile(`auth.profiles..mode = "oauth"`)不支持由 SecretRef 提供支持的 auth-profile 凭证。 +- 静态运行时凭证来自内存中已解析的快照;发现旧版静态 `auth.json` 条目时会进行清理。 - 旧版 OAuth 会从 `~/.openclaw/credentials/oauth.json` 导入。 - 请参见 [OAuth](/zh-CN/concepts/oauth)。 -- Secrets 运行时行为以及 `audit/configure/apply` 工具:请参见 [Secrets Management](/zh-CN/gateway/secrets)。 +- 密钥运行时行为以及 `audit/configure/apply` 工具:参见 [密钥管理](/zh-CN/gateway/secrets)。 ### `auth.cooldowns` @@ -822,20 +819,19 @@ SecretRef 是增量式的:纯文本值仍然可用。 } ``` -- `billingBackoffHours`:当某个配置文件因真实的 - 计费 / 额度不足错误而失败时,使用的基础退避时间(小时)(默认值:`5`)。即使在 `401` / `403` 响应上,显式计费文本 - 仍可能归入此类,但提供商专属的文本匹配器 - 仍然限定在拥有它们的提供商范围内(例如 OpenRouter - `Key limit exceeded`)。可重试的 HTTP `402` 用量窗口或 - organization / workspace 支出上限消息则仍归入 `rate_limit` 路径。 -- `billingBackoffHoursByProvider`:按提供商覆盖计费退避时长(小时)的可选配置。 -- `billingMaxHours`:计费退避指数增长的上限(小时)(默认值:`24`)。 -- `authPermanentBackoffMinutes`:高置信度 `auth_permanent` 失败的基础退避时间(分钟)(默认值:`10`)。 +- `billingBackoffHours`:当某个 profile 因真实的 + 账单/余额不足错误而失败时的基础退避时长(小时)(默认值:`5`)。即使在 `401`/`403` 响应上, + 明确的账单文本仍可能归入这里,但提供商特定的文本匹配器仍只作用于其所属的提供商 + (例如 OpenRouter 的 `Key limit exceeded`)。可重试的 HTTP `402` 使用窗口或 + organization/workspace 支出限制消息仍会归入 `rate_limit` 路径。 +- `billingBackoffHoursByProvider`:可选的逐提供商账单退避时长覆盖(小时)。 +- `billingMaxHours`:账单退避指数增长的上限(小时)(默认值:`24`)。 +- `authPermanentBackoffMinutes`:高置信度 `auth_permanent` 失败的基础退避时长(分钟)(默认值:`10`)。 - `authPermanentMaxMinutes`:`auth_permanent` 退避增长的上限(分钟)(默认值:`60`)。 - `failureWindowHours`:用于退避计数器的滚动时间窗口(小时)(默认值:`24`)。 -- `overloadedProfileRotations`:对于过载错误,在切换到模型回退前,同一提供商 auth-profile 允许轮换的最大次数(默认值:`1`)。诸如 `ModelNotReadyException` 之类的提供商繁忙形态归入此类。 -- `overloadedBackoffMs`:重试过载的提供商 / 配置文件轮换前的固定延迟(毫秒)(默认值:`0`)。 -- `rateLimitedProfileRotations`:对于速率限制错误,在切换到模型回退前,同一提供商 auth-profile 允许轮换的最大次数(默认值:`1`)。该速率限制桶还包括提供商特定文本,例如 `Too many concurrent requests`、`ThrottlingException`、`concurrency limit reached`、`workers_ai ... quota limit exceeded` 和 `resource exhausted`。 +- `overloadedProfileRotations`:在切换到模型回退之前,针对 overloaded 错误允许的同提供商 auth-profile 轮换最大次数(默认值:`1`)。例如 `ModelNotReadyException` 之类的提供商繁忙形态会归入这里。 +- `overloadedBackoffMs`:在重试 overloaded 的提供商/profile 轮换前的固定延迟(默认值:`0`)。 +- `rateLimitedProfileRotations`:在切换到模型回退之前,针对 rate-limit 错误允许的同提供商 auth-profile 轮换最大次数(默认值:`1`)。该 rate-limit 桶包括提供商形态的文本,例如 `Too many concurrent requests`、`ThrottlingException`、`concurrency limit reached`、`workers_ai ... quota limit exceeded` 和 `resource exhausted`。 --- @@ -855,9 +851,10 @@ SecretRef 是增量式的:纯文本值仍然可用。 ``` - 默认日志文件:`/tmp/openclaw/openclaw-YYYY-MM-DD.log`。 -- 设置 `logging.file` 可使用稳定路径。 -- 当使用 `--verbose` 时,`consoleLevel` 会提升为 `debug`。 -- `maxFileBytes`:日志轮转前当前活动日志文件允许的最大大小(字节)(正整数;默认值:`104857600` = 100 MB)。OpenClaw 会在活动文件旁保留最多五个带编号的归档文件。 +- 设置 `logging.file` 可指定稳定路径。 +- 使用 `--verbose` 时,`consoleLevel` 会提升为 `debug`。 +- `maxFileBytes`:轮转前活动日志文件的最大大小(字节)(正整数;默认值:`104857600` = 100 MB)。OpenClaw 会在活动文件旁保留最多五个带编号的归档文件。 +- `redactSensitive` / `redactPatterns`:尽力对控制台输出、文件日志、OTLP 日志记录以及持久化会话转录文本中的敏感信息进行遮蔽。 --- @@ -906,24 +903,24 @@ SecretRef 是增量式的:纯文本值仍然可用。 ``` - `enabled`:instrumentation 输出的总开关(默认值:`true`)。 -- `flags`:用于启用定向日志输出的标志字符串数组(支持通配符,如 `"telegram.*"` 或 `"*"`)。 -- `stuckSessionWarnMs`:当会话持续处于处理状态时,发出卡住会话警告的年龄阈值(毫秒)。 -- `otel.enabled`:启用 OpenTelemetry 导出管线(默认值:`false`)。完整配置、信号目录和隐私模型请参见 [OpenTelemetry 导出](/zh-CN/gateway/opentelemetry)。 +- `flags`:启用定向日志输出的标志字符串数组(支持如 `"telegram.*"` 或 `"*"` 这样的通配符)。 +- `stuckSessionWarnMs`:当某个会话保持在处理状态时,用于发出卡住会话警告的年龄阈值(毫秒)。 +- `otel.enabled`:启用 OpenTelemetry 导出管道(默认值:`false`)。有关完整配置、信号目录和隐私模型,请参见 [OpenTelemetry 导出](/zh-CN/gateway/opentelemetry)。 - `otel.endpoint`:用于 OTel 导出的 collector URL。 -- `otel.tracesEndpoint` / `otel.metricsEndpoint` / `otel.logsEndpoint`:可选的按信号划分的 OTLP 端点。设置后,它们会仅对对应信号覆盖 `otel.endpoint`。 +- `otel.tracesEndpoint` / `otel.metricsEndpoint` / `otel.logsEndpoint`:可选的按信号划分的 OTLP 端点。设置后,它们仅对对应信号覆盖 `otel.endpoint`。 - `otel.protocol`:`"http/protobuf"`(默认)或 `"grpc"`。 -- `otel.headers`:随 OTel 导出请求发送的额外 HTTP / gRPC 元数据标头。 -- `otel.serviceName`:资源属性中的服务名称。 +- `otel.headers`:随 OTel 导出请求发送的额外 HTTP/gRPC 元数据头。 +- `otel.serviceName`:资源属性使用的服务名称。 - `otel.traces` / `otel.metrics` / `otel.logs`:启用 trace、metrics 或 log 导出。 -- `otel.sampleRate`:trace 采样率,范围 `0`–`1`。 +- `otel.sampleRate`:trace 采样率 `0`–`1`。 - `otel.flushIntervalMs`:定期刷新 telemetry 的间隔(毫秒)。 -- `otel.captureContent`:为 OTEL span 属性选择启用原始内容捕获。默认关闭。布尔值 `true` 会捕获非系统消息 / 工具内容;对象形式则允许你显式启用 `inputMessages`、`outputMessages`、`toolInputs`、`toolOutputs` 和 `systemPrompt`。 -- `OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental`:用于启用最新实验性 GenAI span provider 属性的环境变量开关。默认情况下,span 会保留旧版 `gen_ai.system` 属性以保持兼容性;GenAI metrics 使用有界语义属性。 -- `OPENCLAW_OTEL_PRELOADED=1`:用于宿主环境已注册全局 OpenTelemetry SDK 的环境变量开关。此时 OpenClaw 会跳过插件自有 SDK 的启动 / 关闭,同时保持诊断监听器处于活动状态。 -- `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`、`OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` 和 `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT`:当对应配置键未设置时使用的按信号划分端点环境变量。 -- `cacheTrace.enabled`:为嵌入式运行记录缓存跟踪快照(默认值:`false`)。 +- `otel.captureContent`:为 OTEL span 属性选择启用原始内容捕获。默认关闭。布尔值 `true` 会捕获非 system 消息/工具内容;对象形式可让你显式启用 `inputMessages`、`outputMessages`、`toolInputs`、`toolOutputs` 和 `systemPrompt`。 +- `OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental`:用于启用最新实验性 GenAI span provider 属性的环境变量开关。默认情况下,为了兼容性,span 会保留旧版 `gen_ai.system` 属性;GenAI metrics 使用有界语义属性。 +- `OPENCLAW_OTEL_PRELOADED=1`:适用于已注册全局 OpenTelemetry SDK 的主机的环境变量开关。此时 OpenClaw 会跳过插件拥有的 SDK 启动/关闭,同时保持诊断监听器处于活动状态。 +- `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`、`OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` 和 `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT`:当匹配的配置键未设置时使用的按信号划分端点环境变量。 +- `cacheTrace.enabled`:记录嵌入式运行的缓存跟踪快照(默认值:`false`)。 - `cacheTrace.filePath`:缓存跟踪 JSONL 的输出路径(默认值:`$OPENCLAW_STATE_DIR/logs/cache-trace.jsonl`)。 -- `cacheTrace.includeMessages` / `includePrompt` / `includeSystem`:控制缓存跟踪输出中包含的内容(默认均为 `true`)。 +- `cacheTrace.includeMessages` / `includePrompt` / `includeSystem`:控制缓存跟踪输出中包含的内容(默认值均为 `true`)。 --- @@ -945,12 +942,12 @@ SecretRef 是增量式的:纯文本值仍然可用。 } ``` -- `channel`:适用于 npm / git 安装的发布渠道——`"stable"`、`"beta"` 或 `"dev"`。 -- `checkOnStart`:Gateway 网关启动时检查 npm 更新(默认值:`true`)。 +- `channel`:用于 npm/git 安装的发布渠道——`"stable"`、`"beta"` 或 `"dev"`。 +- `checkOnStart`:在 Gateway 网关启动时检查 npm 更新(默认值:`true`)。 - `auto.enabled`:为 package 安装启用后台自动更新(默认值:`false`)。 -- `auto.stableDelayHours`:稳定渠道自动应用前的最小时延(小时)(默认值:`6`;最大值:`168`)。 -- `auto.stableJitterHours`:稳定渠道额外的发布扩散时间窗口(小时)(默认值:`12`;最大值:`168`)。 -- `auto.betaCheckIntervalHours`:beta 渠道检查的运行频率(小时)(默认值:`1`;最大值:`24`)。 +- `auto.stableDelayHours`:stable 渠道自动应用前的最小延迟(小时)(默认值:`6`;最大值:`168`)。 +- `auto.stableJitterHours`:stable 渠道额外的发布分散窗口(小时)(默认值:`12`;最大值:`168`)。 +- `auto.betaCheckIntervalHours`:beta 渠道执行检查的频率(小时)(默认值:`1`;最大值:`24`)。 --- @@ -983,23 +980,23 @@ SecretRef 是增量式的:纯文本值仍然可用。 } ``` -- `enabled`:全局 ACP 功能门控(默认值:`true`;设为 `false` 可隐藏 ACP 调度和 spawn 入口)。 -- `dispatch.enabled`:ACP 会话轮次调度的独立门控(默认值:`true`)。设为 `false` 可在保留 ACP 命令可用的同时阻止执行。 -- `backend`:默认 ACP 运行时后端 id(必须匹配已注册的 ACP 运行时插件)。 - 如果设置了 `plugins.allow`,请将后端插件 id(例如 `acpx`)包含在内,否则内置默认插件将不会加载。 -- `defaultAgent`:当 spawn 未指定显式目标时使用的 ACP 默认目标智能体 id。 -- `allowedAgents`:允许用于 ACP 运行时会话的智能体 id 允许列表;为空表示不增加额外限制。 -- `maxConcurrentSessions`:同时处于活动状态的 ACP 会话最大数量。 +- `enabled`:全局 ACP 功能门控(默认值:`true`;设为 `false` 可隐藏 ACP dispatch 和 spawn 相关入口)。 +- `dispatch.enabled`:ACP 会话轮次 dispatch 的独立门控(默认值:`true`)。设为 `false` 可在保留 ACP 命令可用的同时阻止执行。 +- `backend`:默认 ACP 运行时后端 id(必须与已注册的 ACP 运行时插件匹配)。 + 如果设置了 `plugins.allow`,请包含该后端插件 id(例如 `acpx`),否则内置默认插件将不会加载。 +- `defaultAgent`:当 spawn 未指定显式目标时,ACP 目标智能体 id 的回退值。 +- `allowedAgents`:允许用于 ACP 运行时会话的智能体 id 允许列表;空值表示无额外限制。 +- `maxConcurrentSessions`:同时活动的 ACP 会话最大数量。 - `stream.coalesceIdleMs`:流式文本的空闲合并刷新窗口(毫秒)。 -- `stream.maxChunkChars`:在拆分流式分块投影之前允许的最大分块大小。 -- `stream.repeatSuppression`:按轮次抑制重复的状态 / 工具行(默认值:`true`)。 -- `stream.deliveryMode`:`"live"` 表示增量流式输出;`"final_only"` 表示缓冲到轮次终止事件后再输出。 -- `stream.hiddenBoundarySeparator`:隐藏工具事件后、可见文本前的分隔符(默认值:`"paragraph"`)。 -- `stream.maxOutputChars`:每个 ACP 轮次投影的智能体输出最大字符数。 -- `stream.maxSessionUpdateChars`:投影 ACP 状态 / 更新行的最大字符数。 -- `stream.tagVisibility`:记录标签名称到布尔可见性覆盖项的映射,用于流式事件。 -- `runtime.ttlMinutes`:ACP 会话工作线程在可被清理前的空闲 TTL(分钟)。 -- `runtime.installCommand`:在引导 ACP 运行时环境时运行的可选安装命令。 +- `stream.maxChunkChars`:拆分流式分块投影前的最大 chunk 大小。 +- `stream.repeatSuppression`:按轮次抑制重复的状态/工具行(默认值:`true`)。 +- `stream.deliveryMode`:`"live"` 表示增量流式传输;`"final_only"` 表示缓冲直到轮次终止事件。 +- `stream.hiddenBoundarySeparator`:隐藏工具事件之后、可见文本之前使用的分隔符(默认值:`"paragraph"`)。 +- `stream.maxOutputChars`:每个 ACP 轮次投影的最大助手输出字符数。 +- `stream.maxSessionUpdateChars`:投影的 ACP 状态/更新行的最大字符数。 +- `stream.tagVisibility`:用于流式事件的标签名到布尔可见性覆盖的记录。 +- `runtime.ttlMinutes`:ACP 会话工作进程在符合清理条件前的空闲 TTL(分钟)。 +- `runtime.installCommand`:在引导 ACP 运行时环境时执行的可选安装命令。 --- @@ -1015,11 +1012,11 @@ SecretRef 是增量式的:纯文本值仍然可用。 } ``` -- `cli.banner.taglineMode` 控制横幅标语样式: - - `"random"`(默认):轮换的有趣 / 季节性标语。 - - `"default"`:固定的中性标语(`All your chats, one OpenClaw.`)。 - - `"off"`:不显示标语文本(仍显示横幅标题 / 版本)。 -- 如需隐藏整个横幅(而不仅仅是标语),请设置环境变量 `OPENCLAW_HIDE_BANNER=1`。 +- `cli.banner.taglineMode` 控制 banner 标语样式: + - `"random"`(默认):轮换显示有趣/季节性标语。 + - `"default"`:固定中性标语(`All your chats, one OpenClaw.`)。 + - `"off"`:不显示标语文本(仍显示 banner 标题/版本)。 +- 如需隐藏整个 banner(不只是标语),请设置环境变量 `OPENCLAW_HIDE_BANNER=1`。 --- @@ -1049,7 +1046,7 @@ SecretRef 是增量式的:纯文本值仍然可用。 ## Bridge protocol(旧版节点,历史参考)(旧版,已移除) -当前构建已不再包含 TCP bridge。节点通过 Gateway 网关 WebSocket 连接。`bridge.*` 键已不再属于配置 schema 的一部分(移除前校验会失败;`openclaw doctor --fix` 可剥离未知键)。 +当前构建不再包含 TCP bridge。节点通过 Gateway 网关 WebSocket 连接。`bridge.*` 键已不再属于配置 schema 的一部分(在移除前,验证会失败;`openclaw doctor --fix` 可以剥离未知键)。 @@ -1078,8 +1075,8 @@ SecretRef 是增量式的:纯文本值仍然可用。 cron: { enabled: true, maxConcurrentRuns: 2, - webhook: "https://example.invalid/legacy", // 已弃用,仅供已存储的 notify:true 作业回退使用 - webhookToken: "replace-with-dedicated-token", // 可选,用于出站 webhook 认证的 bearer token + webhook: "https://example.invalid/legacy", // 已弃用,用于存储的 notify:true 作业的回退项 + webhookToken: "replace-with-dedicated-token", // 出站 webhook 认证的可选 bearer token sessionRetention: "24h", // 时长字符串或 false runLog: { maxBytes: "2mb", // 默认 2_000_000 字节 @@ -1089,11 +1086,11 @@ SecretRef 是增量式的:纯文本值仍然可用。 } ``` -- `sessionRetention`:完成的隔离 cron 运行会话在从 `sessions.json` 中清理前保留的时长。也控制已归档的已删除 cron transcript 的清理。默认值:`24h`;设为 `false` 可禁用。 -- `runLog.maxBytes`:每个运行日志文件(`cron/runs/.jsonl`)在裁剪前允许的最大大小。默认值:`2_000_000` 字节。 -- `runLog.keepLines`:触发运行日志裁剪时保留的最新行数。默认值:`2000`。 -- `webhookToken`:cron webhook `POST` 投递(`delivery.mode = "webhook"`)时使用的 bearer token;若省略,则不会发送认证标头。 -- `webhook`:已弃用的旧版回退 webhook URL(http / https),仅用于仍带有 `notify: true` 的已存储作业。 +- `sessionRetention`:在从 `sessions.json` 中清理前,保留已完成的隔离 cron 运行会话的时长。同时也控制已归档删除的 cron 转录的清理。默认值:`24h`;设为 `false` 可禁用。 +- `runLog.maxBytes`:每个运行日志文件(`cron/runs/.jsonl`)在清理前的最大大小。默认值:`2_000_000` 字节。 +- `runLog.keepLines`:触发运行日志清理时保留的最新行数。默认值:`2000`。 +- `webhookToken`:用于 cron webhook POST 发送(`delivery.mode = "webhook"`)的 bearer token;如省略则不会发送认证头。 +- `webhook`:已弃用的旧版回退 webhook URL(http/https),仅用于仍带有 `notify: true` 的已存储作业。 ### `cron.retry` @@ -1109,11 +1106,11 @@ SecretRef 是增量式的:纯文本值仍然可用。 } ``` -- `maxAttempts`:一次性作业在瞬时错误下允许的最大重试次数(默认值:`3`;范围:`0`–`10`)。 -- `backoffMs`:每次重试尝试对应的退避延迟数组(毫秒)(默认值:`[30000, 60000, 300000]`;1–10 项)。 -- `retryOn`:触发重试的错误类型——`"rate_limit"`、`"overloaded"`、`"network"`、`"timeout"`、`"server_error"`。省略则表示对所有瞬时错误都重试。 +- `maxAttempts`:一次性作业在瞬态错误下的最大重试次数(默认值:`3`;范围:`0`–`10`)。 +- `backoffMs`:每次重试尝试的退避延迟数组(毫秒)(默认值:`[30000, 60000, 300000]`;1–10 个条目)。 +- `retryOn`:触发重试的错误类型——`"rate_limit"`、`"overloaded"`、`"network"`、`"timeout"`、`"server_error"`。省略则表示重试所有瞬态类型。 -仅适用于一次性 cron 作业。周期性作业使用独立的失败处理机制。 +仅适用于一次性 cron 作业。周期性作业使用单独的失败处理方式。 ### `cron.failureAlert` @@ -1132,10 +1129,10 @@ SecretRef 是增量式的:纯文本值仍然可用。 ``` - `enabled`:启用 cron 作业失败告警(默认值:`false`)。 -- `after`:在触发告警前允许的连续失败次数(正整数,最小值:`1`)。 +- `after`:触发告警前允许的连续失败次数(正整数,最小值:`1`)。 - `cooldownMs`:同一作业重复告警之间的最小间隔(毫秒)(非负整数)。 -- `mode`:投递模式——`"announce"` 通过渠道消息发送;`"webhook"` 则发送到已配置的 webhook。 -- `accountId`:用于限定告警投递范围的可选账号或渠道 id。 +- `mode`:发送模式——`"announce"` 通过渠道消息发送;`"webhook"` 会向已配置 webhook 发起 POST。 +- `accountId`:用于限定告警发送范围的可选账户或渠道 id。 ### `cron.failureDestination` @@ -1152,16 +1149,16 @@ SecretRef 是增量式的:纯文本值仍然可用。 } ``` -- 所有作业共用的 cron 失败通知默认目标。 +- 所有作业的 cron 失败通知默认目标。 - `mode`:`"announce"` 或 `"webhook"`;当存在足够的目标数据时,默认值为 `"announce"`。 -- `channel`:announce 投递的渠道覆盖项。`"last"` 会复用上次已知的投递渠道。 -- `to`:显式 announce 目标或 webhook URL。webhook 模式下为必填。 -- `accountId`:投递时使用的可选账号覆盖项。 +- `channel`:announce 发送的渠道覆盖。`"last"` 表示复用最近一次已知的发送渠道。 +- `to`:显式的 announce 目标或 webhook URL。webhook 模式下为必填。 +- `accountId`:可选的发送账户覆盖。 - 每个作业的 `delivery.failureDestination` 会覆盖此全局默认值。 -- 如果既未设置全局失败目标,也未设置每作业失败目标,则那些已通过 `announce` 投递的作业会在失败时回退到其主 announce 目标。 +- 当全局和逐作业失败目标都未设置时,已通过 `announce` 发送的作业在失败时会回退到其主 announce 目标。 - `delivery.failureDestination` 仅对 `sessionTarget="isolated"` 的作业受支持,除非该作业的主 `delivery.mode` 为 `"webhook"`。 -请参见 [Cron Jobs](/zh-CN/automation/cron-jobs)。隔离的 cron 执行会作为[后台任务](/zh-CN/automation/tasks)进行跟踪。 +请参见 [Cron Jobs](/zh-CN/automation/cron-jobs)。隔离的 cron 执行会作为 [后台任务](/zh-CN/automation/tasks) 跟踪。 --- @@ -1169,32 +1166,32 @@ SecretRef 是增量式的:纯文本值仍然可用。 在 `tools.media.models[].args` 中展开的模板占位符: -| Variable | 说明 | -| ------------------ | ---- | -| `{{Body}}` | 完整入站消息正文 | -| `{{RawBody}}` | 原始正文(不含历史记录 / 发送者包装) | +| 变量 | 说明 | +| ------------------ | ------------------------------------------------- | +| `{{Body}}` | 完整入站消息正文 | +| `{{RawBody}}` | 原始正文(无历史记录/发送者包装) | | `{{BodyStripped}}` | 去除群组提及后的正文 | -| `{{From}}` | 发送者标识符 | -| `{{To}}` | 目标标识符 | -| `{{MessageSid}}` | 渠道消息 id | -| `{{SessionId}}` | 当前会话 UUID | -| `{{IsNewSession}}` | 新建会话时为 `"true"` | -| `{{MediaUrl}}` | 入站媒体伪 URL | -| `{{MediaPath}}` | 本地媒体路径 | -| `{{MediaType}}` | 媒体类型(image/audio/document/…) | -| `{{Transcript}}` | 音频转录文本 | -| `{{Prompt}}` | 用于 CLI 条目的已解析媒体提示词 | -| `{{MaxChars}}` | 用于 CLI 条目的已解析最大输出字符数 | -| `{{ChatType}}` | `"direct"` 或 `"group"` | -| `{{GroupSubject}}` | 群组主题(尽力获取) | -| `{{GroupMembers}}` | 群组成员预览(尽力获取) | -| `{{SenderName}}` | 发送者显示名称(尽力获取) | -| `{{SenderE164}}` | 发送者电话号码(尽力获取) | -| `{{Provider}}` | 提供商提示(whatsapp、telegram、discord 等) | +| `{{From}}` | 发送者标识符 | +| `{{To}}` | 目标标识符 | +| `{{MessageSid}}` | 渠道消息 id | +| `{{SessionId}}` | 当前会话 UUID | +| `{{IsNewSession}}` | 创建新会话时为 `"true"` | +| `{{MediaUrl}}` | 入站媒体伪 URL | +| `{{MediaPath}}` | 本地媒体路径 | +| `{{MediaType}}` | 媒体类型(image/audio/document/…) | +| `{{Transcript}}` | 音频转录文本 | +| `{{Prompt}}` | CLI 条目的已解析媒体提示词 | +| `{{MaxChars}}` | CLI 条目的已解析最大输出字符数 | +| `{{ChatType}}` | `"direct"` 或 `"group"` | +| `{{GroupSubject}}` | 群组主题(尽力而为) | +| `{{GroupMembers}}` | 群组成员预览(尽力而为) | +| `{{SenderName}}` | 发送者显示名称(尽力而为) | +| `{{SenderE164}}` | 发送者电话号码(尽力而为) | +| `{{Provider}}` | 提供商提示(whatsapp、telegram、discord 等) | --- -## 配置包含(`$include`) +## 配置 include(`$include`) 将配置拆分为多个文件: @@ -1211,14 +1208,14 @@ SecretRef 是增量式的:纯文本值仍然可用。 **合并行为:** -- 单个文件:替换所在的对象。 +- 单个文件:替换其所在的包含对象。 - 文件数组:按顺序深度合并(后者覆盖前者)。 -- 同级键:在包含内容之后合并(覆盖已包含的值)。 -- 嵌套包含:最多支持 10 层深度。 -- 路径:相对于包含它的文件解析,但必须保持在顶级配置目录(`openclaw.json` 的 `dirname`)内部。仅当绝对路径 / `../` 形式最终仍解析到该边界内时才允许。 -- OpenClaw 自有写入在仅更改由单文件 include 支持的某个顶级区段时,会直接写回该包含文件。例如,`plugins install` 会更新 `plugins: { $include: "./plugins.json5" }` 中的 `plugins.json5`,并保持 `openclaw.json` 不变。 -- 根级 include、include 数组,以及带有同级覆盖项的 include,对 OpenClaw 自有写入来说是只读的;这些写入会以关闭方式失败,而不是将配置拍平。 -- 错误:对于缺失文件、解析错误和循环包含,会给出清晰的错误消息。 +- 同级键:在 include 之后合并(会覆盖 include 的值)。 +- 嵌套 include:最多 10 层。 +- 路径:相对于包含它的文件解析,但必须保持在顶层配置目录(`openclaw.json` 的 `dirname`)内。仅当绝对路径/`../` 形式最终仍解析到该边界内时才允许。 +- 当 OpenClaw 拥有的写入仅更改单个由单文件 include 支持的顶层 section 时,会直接写回该 include 文件。例如,`plugins install` 会更新 `plugins: { $include: "./plugins.json5" }` 中的 `plugins.json5`,并保持 `openclaw.json` 不变。 +- 根 include、include 数组以及带有同级覆盖的 include 对 OpenClaw 拥有的写入来说都是只读的;这些写入会以关闭方式失败,而不是将配置展平。 +- 错误:对缺失文件、解析错误和循环 include 提供清晰消息。 --- diff --git a/docs/zh-CN/gateway/logging.md b/docs/zh-CN/gateway/logging.md index 944192912..9ab4a8bb5 100644 --- a/docs/zh-CN/gateway/logging.md +++ b/docs/zh-CN/gateway/logging.md @@ -2,74 +2,74 @@ read_when: - 更改日志输出或格式 - 调试 CLI 或 Gateway 网关输出 -summary: 日志输出界面、文件日志、WS 日志样式以及控制台格式化 -title: Gateway 网关日志 +summary: 日志展示界面、文件日志、WS 日志样式,以及控制台格式化 +title: Gateway 网关日志记录 x-i18n: - generated_at: "2026-04-26T18:13:21Z" + generated_at: "2026-04-26T19:16:56Z" model: gpt-5.4 provider: openai - source_hash: 52ba93f1a79932609687416014b0b1569a7af25abf650bc5b5dded1c95db9a71 + source_hash: 52b3904ee693bdabc74b56e6dd924f12215ce741496a03eafc15f74258ad036e source_path: gateway/logging.md workflow: 15 --- -# 日志 +# 日志记录 -如需面向用户的概览(CLI + Control UI + 配置),请参阅 [/logging](/zh-CN/logging)。 +如需面向用户的概览(CLI + Control UI + 配置),请参见 [/logging](/zh-CN/logging)。 -OpenClaw 有两个日志“输出界面”: +OpenClaw 有两个日志“展示界面”: -- **控制台输出**(你在终端 / Debug UI 中看到的内容)。 -- **文件日志**(JSON 行),由 Gateway 网关日志记录器写入。 +- **控制台输出**(你在终端 / 调试 UI 中看到的内容)。 +- **文件日志**(JSON 行格式),由 Gateway 网关日志记录器写入。 ## 基于文件的日志记录器 -- 默认滚动日志文件位于 `/tmp/openclaw/` 下(每天一个文件):`openclaw-YYYY-MM-DD.log` - - 日期使用 Gateway 网关宿主机的本地时区。 +- 默认的滚动日志文件位于 `/tmp/openclaw/` 下(每天一个文件):`openclaw-YYYY-MM-DD.log` + - 日期使用 Gateway 网关主机的本地时区。 - 活动日志文件会在达到 `logging.maxFileBytes` 时轮转(默认:100 MB),最多保留五个带编号的归档文件,并继续写入一个新的活动文件。 -- 日志文件路径和级别可通过 `~/.openclaw/openclaw.json` 配置: +- 可以通过 `~/.openclaw/openclaw.json` 配置日志文件路径和级别: - `logging.file` - `logging.level` 文件格式为每行一个 JSON 对象。 -Control UI 的 Logs 选项卡会通过 Gateway 网关对该文件执行 tail(`logs.tail`)。 +Control UI 的 Logs 选项卡会通过 Gateway 网关(`logs.tail`)持续跟踪这个文件。 CLI 也可以执行相同操作: ```bash openclaw logs --follow ``` -**详细模式与日志级别** +**详细输出与日志级别** -- **文件日志** 仅由 `logging.level` 控制。 -- `--verbose` 只影响 **控制台详细程度**(以及 WS 日志样式);它**不会**提升文件日志级别。 -- 若要在文件日志中捕获仅详细模式可见的细节,请将 `logging.level` 设置为 `debug` 或 `trace`。 +- **文件日志**仅由 `logging.level` 控制。 +- `--verbose` 只影响**控制台详细程度**(以及 WS 日志样式);它**不会**提高文件日志级别。 +- 若要在文件日志中捕获仅详细模式下可见的细节,请将 `logging.level` 设置为 `debug` 或 `trace`。 ## 控制台捕获 -CLI 会捕获 `console.log/info/warn/error/debug/trace`,并将其写入文件日志,同时仍然打印到 stdout/stderr。 +CLI 会捕获 `console.log/info/warn/error/debug/trace`,并将其写入文件日志,同时仍然输出到 stdout/stderr。 -你可以通过以下配置独立调节控制台详细程度: +你可以通过以下配置独立调整控制台详细程度: - `logging.consoleLevel`(默认 `info`) - `logging.consoleStyle`(`pretty` | `compact` | `json`) ## 脱敏 -OpenClaw 可以在日志输出离开进程前屏蔽敏感令牌。控制台和文件日志 sink 会应用相同的脱敏策略,因此匹配到的 secret 值会在 JSONL 行写入磁盘前被屏蔽。 +OpenClaw 可以在日志或转录输出离开进程之前屏蔽敏感令牌。同一套脱敏策略会应用到控制台、文件日志、OTLP 日志记录以及会话转录文本输出端,因此匹配到的敏感值会在 JSONL 行或消息写入磁盘之前被屏蔽。 - `logging.redactSensitive`:`off` | `tools`(默认:`tools`) - `logging.redactPatterns`:正则表达式字符串数组(覆盖默认值) - - 使用原始正则表达式字符串(自动附加 `gi`),或者在需要自定义标志时使用 `/pattern/flags`。 - - 匹配内容会保留前 6 个字符 + 后 4 个字符进行屏蔽(长度 >= 18),否则为 `***`。 - - 默认规则涵盖常见的密钥赋值、CLI 标志、JSON 字段、bearer 头、PEM 块以及常见令牌前缀。 + - 使用原始正则字符串(自动附加 `gi`),如果你需要自定义标志,可使用 `/pattern/flags`。 + - 匹配项会保留前 6 个字符和后 4 个字符进行遮罩(长度 >= 18),否则显示为 `***`。 + - 默认规则涵盖常见的密钥赋值、CLI 标志、JSON 字段、bearer 标头、PEM 块以及常见令牌前缀。 ## Gateway 网关 WebSocket 日志 -Gateway 网关以两种模式打印 WebSocket 协议日志: +Gateway 网关会以两种模式打印 WebSocket 协议日志: -- **普通模式(无 `--verbose`)**:只打印“值得关注”的 RPC 结果: +- **普通模式(不使用 `--verbose`)**:仅打印“值得关注”的 RPC 结果: - 错误(`ok=false`) - 慢调用(默认阈值:`>= 50ms`) - 解析错误 @@ -77,11 +77,11 @@ Gateway 网关以两种模式打印 WebSocket 协议日志: ### WS 日志样式 -`openclaw gateway` 支持按 Gateway 网关设置样式切换: +`openclaw gateway` 支持按 Gateway 网关切换样式: -- `--ws-log auto`(默认):普通模式经过优化;详细模式使用紧凑输出 -- `--ws-log compact`:在详细模式下使用紧凑输出(配对的请求/响应) -- `--ws-log full`:在详细模式下使用完整的逐帧输出 +- `--ws-log auto`(默认):普通模式下会进行优化;详细模式下使用紧凑输出 +- `--ws-log compact`:详细模式下使用紧凑输出(配对的请求/响应) +- `--ws-log full`:详细模式下使用完整的逐帧输出 - `--compact`:`--ws-log compact` 的别名 示例: @@ -97,27 +97,27 @@ openclaw gateway --verbose --ws-log compact openclaw gateway --verbose --ws-log full ``` -## 控制台格式化(子系统日志) +## 控制台格式化(子系统日志记录) -控制台格式化器**可感知 TTY**,并打印一致的、带前缀的行。 -子系统日志记录器会让输出保持分组且便于快速浏览。 +控制台格式化器会**感知 TTY**,并输出一致且带前缀的行。 +子系统日志记录器会让输出保持分组并便于快速扫描。 -行为如下: +行为: -- 每一行都有 **子系统前缀**(例如 `[gateway]`、`[canvas]`、`[tailscale]`) -- **子系统颜色**(每个子系统固定)以及级别着色 -- **当输出为 TTY 或环境看起来像富终端时启用颜色**(`TERM`/`COLORTERM`/`TERM_PROGRAM`),并遵循 `NO_COLOR` -- **缩短的子系统前缀**:去掉前导 `gateway/` + `channels/`,保留最后 2 个段(例如 `whatsapp/outbound`) -- **按子系统划分的子日志记录器**(自动添加前缀 + 结构化字段 `{ subsystem }`) +- 每行都有**子系统前缀**(例如 `[gateway]`、`[canvas]`、`[tailscale]`) +- **子系统颜色**(每个子系统颜色稳定)以及级别颜色 +- **当输出为 TTY 或环境看起来像是富终端时启用颜色**(`TERM`/`COLORTERM`/`TERM_PROGRAM`),并遵循 `NO_COLOR` +- **缩短的子系统前缀**:去掉前导 `gateway/` 和 `channels/`,保留最后 2 个段(例如 `whatsapp/outbound`) +- **按子系统划分的子日志记录器**(自动加前缀 + 结构化字段 `{ subsystem }`) - 用于 QR/UX 输出的 **`logRaw()`**(无前缀、无格式化) - **控制台样式**(例如 `pretty | compact | json`) -- 与文件日志级别分离的 **控制台日志级别**(当 `logging.level` 设置为 `debug`/`trace` 时,文件仍保留完整细节) -- **WhatsApp 消息正文** 以 `debug` 级别记录(使用 `--verbose` 可查看) +- **控制台日志级别**与文件日志级别分离(当 `logging.level` 设置为 `debug`/`trace` 时,文件仍保留完整细节) +- **WhatsApp 消息正文**会以 `debug` 级别记录(使用 `--verbose` 才能看到) -这样既能保持现有文件日志稳定,又能让交互式输出更易于快速浏览。 +这样既能保持现有文件日志稳定,又能让交互式输出更便于扫描。 ## 相关内容 -- [日志](/zh-CN/logging) +- [日志记录](/zh-CN/logging) - [OpenTelemetry 导出](/zh-CN/gateway/opentelemetry) - [诊断导出](/zh-CN/gateway/diagnostics) diff --git a/docs/zh-CN/gateway/security/index.md b/docs/zh-CN/gateway/security/index.md index 19ee9d7fe..2b555e667 100644 --- a/docs/zh-CN/gateway/security/index.md +++ b/docs/zh-CN/gateway/security/index.md @@ -4,34 +4,34 @@ read_when: summary: 运行具有 shell 访问权限的 AI Gateway 网关时的安全注意事项和威胁模型 title: 安全性 x-i18n: - generated_at: "2026-04-25T22:27:12Z" + generated_at: "2026-04-26T19:16:54Z" model: gpt-5.4 provider: openai - source_hash: 982a3164178822475c3ac3d871eb83d77c9d7cb0980ad93c781565110755e022 + source_hash: a6365ef1b7afed0392c436adb1e9e24f10c264029d264e82a35a69350dfff7f6 source_path: gateway/security/index.md workflow: 15 --- - **个人助理信任模型。** 本指南假设每个 Gateway 网关对应一个受信任的操作员边界(单用户、个人助理模型)。OpenClaw **并不是** 一个适用于多个对抗性用户共享同一个智能体或 Gateway 网关的敌对多租户安全边界。如果你需要混合信任或对抗性用户场景,请拆分信任边界(单独的 Gateway 网关 + 凭证,理想情况下还应使用单独的操作系统用户或主机)。 + **个人助理信任模型。** 本指南假设每个 Gateway 网关只有一个受信任的操作员边界(单用户、个人助理模型)。OpenClaw **不是** 适用于多个对抗性用户共享同一个智能体或 Gateway 网关的敌对多租户安全边界。如果你需要混合信任或对抗性用户场景,请拆分信任边界(独立的 Gateway 网关 + 凭证,最好再分别使用独立的 OS 用户或主机)。 -## 先明确范围:个人助理安全模型 +## 先界定范围:个人助理安全模型 OpenClaw 的安全指南基于**个人助理**部署模型:一个受信任的操作员边界,可能包含多个智能体。 -- 支持的安全姿态:每个 Gateway 网关对应一个用户/信任边界(每个边界最好对应一个操作系统用户/主机/ VPS)。 -- 不受支持的安全边界:多个彼此不受信任或具有对抗性的用户共享同一个 Gateway 网关/智能体。 -- 如果需要对抗性用户隔离,请按信任边界拆分(单独的 Gateway 网关 + 凭证,理想情况下还应使用单独的操作系统用户/主机)。 -- 如果多个不受信任的用户都可以向同一个启用了工具的智能体发消息,应视为他们共享该智能体的同一组委托工具权限。 +- 支持的安全态势:每个 Gateway 网关对应一个用户/信任边界(最好每个边界使用一个 OS 用户/主机/VPS)。 +- 不受支持的安全边界:多个彼此不信任或具有对抗关系的用户共享同一个 Gateway 网关/智能体。 +- 如果需要对抗性用户隔离,请按信任边界拆分(独立的 Gateway 网关 + 凭证,最好再分别使用独立的 OS 用户/主机)。 +- 如果多个不受信任的用户都可以向同一个启用了工具的智能体发消息,就应视为他们共享该智能体所委托的同一组工具权限。 -本页解释的是**在该模型内部**如何加固。它并不声称单个共享 Gateway 网关能够提供敌对多租户隔离。 +本页说明的是**在该模型内**的加固方式。它并不声称单个共享 Gateway 网关具备敌对多租户隔离能力。 ## 快速检查:`openclaw security audit` -另请参阅:[Formal Verification (Security Models)](/zh-CN/security/formal-verification) +另见:[Formal Verification(安全模型)](/zh-CN/security/formal-verification) -请定期运行此命令(尤其是在更改配置或暴露网络接口之后): +请定期运行此检查(尤其是在修改配置或暴露网络接口后): ```bash openclaw security audit @@ -40,99 +40,102 @@ openclaw security audit --fix openclaw security audit --json ``` -`security audit --fix` 的修复范围被有意保持得很窄:它会将常见的开放群组策略切换为 allowlist,恢复 `logging.redactSensitive: "tools"`,收紧 state/config/include-file 权限,并且在 Windows 上运行时使用 Windows ACL 重置而不是 POSIX `chmod`。 +`security audit --fix` 被有意限制在较小范围内:它会将常见的开放组策略切换为 allowlist,恢复 `logging.redactSensitive: "tools"`,收紧状态/配置/include-file 权限,并且在 Windows 上运行时使用 Windows ACL 重置,而不是 POSIX `chmod`。 -它会标记常见的易踩坑配置(Gateway 网关身份验证暴露、浏览器控制暴露、高权限 allowlist、文件系统权限、过于宽松的 exec 审批,以及开放渠道的工具暴露)。 +它会标记常见的易错配置(Gateway 网关认证暴露、浏览器控制暴露、高权限 allowlist、文件系统权限、宽松的 exec 审批,以及开放渠道的工具暴露)。 -OpenClaw 既是一个产品,也是一个实验:你正在把前沿模型行为接到真实的消息渠道和真实工具上。**不存在“绝对安全”的配置。** 目标是有意识地决定: +OpenClaw 既是一个产品,也是一个实验:你正在把前沿模型行为接入真实的消息表面和真实工具。**不存在“绝对安全”的配置。** 目标是有意识地明确: - 谁可以和你的机器人对话 -- 机器人被允许在哪里执行操作 +- 机器人被允许在什么地方执行操作 - 机器人可以接触什么内容 -先从仍能满足需求的最小访问权限开始,随着信心增加再逐步放宽。 +先从仍能满足需求的最小访问范围开始,随着信心增加再逐步放宽。 ### 部署和主机信任 OpenClaw 假设主机和配置边界是受信任的: -- 如果有人可以修改 Gateway 网关主机状态/配置(`~/.openclaw`,包括 `openclaw.json`),则应将其视为受信任的操作员。 -- 让多个彼此不受信任/具有对抗性的操作员共用一个 Gateway 网关**不是推荐配置**。 -- 对于混合信任团队,请使用单独的 Gateway 网关 来拆分信任边界(或者至少使用单独的操作系统用户/主机)。 -- 推荐默认做法:每个机器/主机(或 VPS)一个用户,该用户一个 Gateway 网关,该 Gateway 网关内有一个或多个智能体。 -- 在单个 Gateway 网关实例内部,经过身份验证的操作员访问属于受信任的控制平面角色,而不是按用户划分的租户角色。 -- 会话标识符(`sessionKey`、session ID、label)是路由选择器,不是授权令牌。 -- 如果几个人都可以向同一个启用了工具的智能体发消息,那么他们每个人都可以驱动这同一组权限。按用户划分的 session/memory 隔离有助于隐私,但不会把共享智能体变成按用户划分的主机授权模型。 +- 如果有人可以修改 Gateway 网关主机状态/配置(`~/.openclaw`,包括 `openclaw.json`),就应视其为受信任的操作员。 +- 让多个彼此不信任/具有对抗关系的操作员共用一个 Gateway 网关**不是推荐的配置**。 +- 对于混合信任团队,应通过独立 Gateway 网关(或至少独立 OS 用户/主机)来拆分信任边界。 +- 推荐的默认方式:每台机器/主机(或 VPS)一个用户,该用户一个 Gateway 网关,该 Gateway 网关中包含一个或多个智能体。 +- 在单个 Gateway 网关实例内,已认证的操作员访问属于受信任的控制平面角色,而不是按用户划分的租户角色。 +- 会话标识符(`sessionKey`、session ID、标签)是路由选择器,不是授权令牌。 +- 如果多个人都可以向同一个启用了工具的智能体发消息,那么他们每个人都可以驱动这同一组权限。按用户隔离 session/Memory 虽然有助于隐私,但并不能把共享智能体变成按用户划分的主机授权边界。 ### 共享 Slack 工作区:真实风险 -如果“Slack 中的所有人都可以给机器人发消息”,核心风险是委托工具权限: +如果“Slack 中的每个人都能给机器人发消息”,核心风险在于委托的工具权限: -- 任何被允许的发送者都可以在智能体策略范围内诱导工具调用(`exec`、浏览器、网络/文件工具); -- 来自某个发送者的提示词/内容注入可能导致影响共享状态、设备或输出的操作; -- 如果某个共享智能体拥有敏感凭证/文件,任何被允许的发送者都可能通过工具使用来驱动数据外泄。 +- 任何被允许的发送者都可以在该智能体策略允许的范围内触发工具调用(`exec`、浏览器、网络/文件工具); +- 来自某个发送者的提示词/内容注入,可能导致影响共享状态、设备或输出的操作; +- 如果某个共享智能体拥有敏感凭证/文件,那么任何被允许的发送者都有可能通过工具使用来驱动数据外泄。 -对于团队工作流,请使用带有最小工具权限的独立智能体/Gateway 网关;涉及个人数据的智能体应保持私有。 +对于团队工作流,请使用工具最少化的独立智能体/Gateway 网关;包含个人数据的智能体应保持私有。 ### 公司共享智能体:可接受模式 -当使用该智能体的所有人都处于同一个信任边界内(例如同一个公司团队),并且该智能体严格限定在业务范围内时,这是可接受的。 +当使用该智能体的所有人都处于同一个信任边界内(例如同一个公司团队),且该智能体严格限定在业务范围内时,这是可接受的。 -- 在专用机器/虚拟机/容器上运行它; -- 为该运行时使用专用操作系统用户 + 专用浏览器/配置文件/账号; -- 不要让该运行时登录你的个人 Apple/Google 账号,也不要登录个人密码管理器/浏览器配置文件。 +- 在专用机器/VM/容器上运行它; +- 为该运行时使用专用 OS 用户 + 专用浏览器/profile/账号; +- 不要让该运行时登录个人 Apple/Google 账号,或个人密码管理器/浏览器 profile。 -如果你在同一个运行时中混用个人身份和公司身份,就会破坏隔离,并增加个人数据暴露风险。 +如果你在同一运行时中混用个人身份和公司身份,就会打破这种隔离,并增加个人数据暴露风险。 -## Gateway 网关与 node 节点的信任概念 +## Gateway 网关和节点信任概念 -应将 Gateway 网关和 node 节点视为同一个操作员信任域中的不同角色: +应将 Gateway 网关和节点视为同一个操作员信任域中的不同角色: -- **Gateway 网关**是控制平面和策略界面(`gateway.auth`、工具策略、路由)。 -- **Node 节点**是与该 Gateway 网关配对的远程执行界面(命令、设备操作、主机本地能力)。 -- 通过身份验证访问 Gateway 网关的调用方,在 Gateway 网关范围内是受信任的。完成配对后,node 节点上的操作属于该 node 节点上的受信任操作员操作。 -- 使用共享 gateway token/password 进行身份验证的直接 loopback 后端客户端,可以在不提供用户设备身份的情况下发起内部控制平面 RPC。这并不是远程或浏览器配对绕过:网络客户端、node 客户端、device-token 客户端以及显式设备身份仍然要经过配对和 scope 升级强制执行。 -- `sessionKey` 是路由/上下文选择键,不是按用户划分的身份验证。 -- Exec 审批(allowlist + 询问)是针对操作员意图的防护栏,而不是敌对多租户隔离机制。 -- OpenClaw 针对受信任单操作员配置的产品默认行为是:允许在 `gateway`/`node` 上执行主机 exec,且无需审批提示(`security="full"`、`ask="off"`,除非你主动收紧)。这是有意设计的 UX 默认值,本身不构成漏洞。 -- Exec 审批会绑定精确的请求上下文以及尽力识别的本地文件操作数;它不会从语义上建模每一种运行时/解释器加载路径。若需要强边界,请使用沙箱隔离和主机隔离。 +- **Gateway 网关**是控制平面和策略表面(`gateway.auth`、工具策略、路由)。 +- **节点**是与该 Gateway 网关配对的远程执行表面(命令、设备操作、主机本地能力)。 +- 经过 Gateway 网关认证的调用方,在 Gateway 网关范围内被视为受信任。完成配对后,节点操作会被视为该节点上的受信任操作员行为。 +- 经过共享 gateway token/password 认证的直接 loopback 后端客户端,可以在不提供用户设备身份的情况下发起内部控制平面 RPC。这并不是远程或浏览器配对绕过:网络客户端、节点客户端、device-token 客户端以及显式设备身份仍然需要经过配对和 scope 升级强制校验。 +- `sessionKey` 是路由/上下文选择键,不是按用户划分的认证机制。 +- Exec 审批(allowlist + 询问)是对操作员意图的防护栏,不是敌对多租户隔离。 +- 对于受信任的单操作员配置,OpenClaw 的产品默认行为是允许在 `gateway`/`node` 上执行主机 exec,而无需审批提示(`security="full"`、`ask="off"`,除非你主动收紧)。这是有意的 UX 默认值,并不天然构成漏洞。 +- Exec 审批会绑定精确的请求上下文和尽力识别的直接本地文件操作数;它并不会对每一种运行时/解释器加载路径进行语义建模。若需要强边界,请使用沙箱隔离和主机隔离。 -如果你需要敌对用户隔离,请按操作系统用户/主机拆分信任边界,并运行单独的 Gateway 网关。 +如果你需要敌对用户隔离,请按 OS 用户/主机拆分信任边界,并运行独立的 Gateway 网关。 ## 信任边界矩阵 -在进行风险分级时,可将其作为快速模型使用: +在评估风险时,可将其作为快速模型: -| 边界或控制项 | 含义 | 常见误解 | -| --------------------------------------------------------- | ------------------------------------------------- | ----------------------------------------------------------------------------- | -| `gateway.auth`(token/password/trusted-proxy/device auth) | 对 Gateway 网关 API 的调用方进行身份验证 | “必须对每一帧消息都做逐条签名才算安全” | -| `sessionKey` | 用于上下文/session 选择的路由键 | “Session key 是用户身份验证边界” | -| 提示词/内容防护栏 | 降低模型滥用风险 | “仅凭 prompt injection 就能证明 auth 绕过” | -| `canvas.eval` / 浏览器 evaluate | 启用后属于有意开放的操作员能力 | “在这个信任模型里,任何 JS eval 原语都会自动构成漏洞” | -| 本地 TUI `!` shell | 由操作员显式触发的本地执行 | “本地 shell 便捷命令就是远程注入” | -| Node 节点配对和 node 节点命令 | 对已配对设备进行操作员级远程执行 | “远程设备控制默认应视为不受信任用户访问” | -| `gateway.nodes.pairing.autoApproveCidrs` | 可选启用的受信任网络 node 节点注册策略 | “默认关闭的 allowlist 也是自动配对漏洞” | +| 边界或控制项 | 它的含义 | 常见误解 | +| ------------------------------------------------- | -------------------------------------------- | --------------------------------------------------------------------------- | +| `gateway.auth`(token/password/trusted-proxy/device auth) | 对 Gateway 网关 API 的调用方进行认证 | “要安全,就必须对每一帧消息都做按消息签名” | +| `sessionKey` | 用于上下文/session 选择的路由键 | “Session key 是用户认证边界” | +| 提示词/内容防护栏 | 降低模型被滥用的风险 | “仅凭提示注入就能证明存在认证绕过” | +| `canvas.eval` / 浏览器 evaluate | 启用后属于有意开放给操作员的能力 | “在这个信任模型中,任何 JS eval 原语都自动属于漏洞” | +| 本地 TUI `!` shell | 明确由操作员触发的本地执行 | “本地 shell 便捷命令属于远程注入” | +| 节点配对和节点命令 | 对已配对设备的操作员级远程执行 | “默认应将远程设备控制视为不受信任用户访问” | +| `gateway.nodes.pairing.autoApproveCidrs` | 选择启用的受信任网络节点注册策略 | “默认关闭的 allowlist 也是自动配对漏洞” | -## 按设计不属于漏洞的问题 +## 按设计不属于漏洞 -以下模式经常被报告,但通常会被判定为无需处理,除非能证明存在真实的边界绕过: +以下模式经常被报告,但除非能证明存在真实的边界绕过,否则通常会被关闭且不采取行动: -- 仅靠 prompt injection 的攻击链,且没有策略、身份验证或沙箱绕过。 -- 假设单个共享主机或配置上存在敌对多租户运行的主张。 -- 将正常的操作员读取路径访问(例如 `sessions.list` / `sessions.preview` / `chat.history`)在共享 Gateway 网关配置中归类为 IDOR 的主张。 -- 仅限 localhost 部署的发现(例如仅 loopback Gateway 网关缺少 HSTS)。 +- 仅有提示注入链路,但没有策略、认证或沙箱绕过。 +- 假设在单个共享主机或共享配置上存在敌对多租户运行。 +- 将正常的操作员读取路径访问(例如 + `sessions.list` / `sessions.preview` / `chat.history`)在共享 Gateway 网关配置中归类为 IDOR。 +- 仅限 localhost 的部署发现(例如仅 loopback Gateway 网关上的 HSTS)。 - 针对本仓库中并不存在的入站路径所提出的 Discord 入站 webhook 签名问题。 -- 将 node 节点配对元数据误认为是 `system.run` 的隐藏式二次逐命令审批层,而实际上真正的执行边界仍然是 Gateway 网关的全局 node 节点命令策略加上 node 节点自身的 exec 审批。 -- 将已配置的 `gateway.nodes.pairing.autoApproveCidrs` 本身视为漏洞的报告。此设置默认关闭,要求显式填写 CIDR/IP 条目,仅适用于首次 `role: node` 配对且未请求 scopes 的情况,并且不会自动批准 operator/browser/Control UI、WebChat、role 升级、scope 升级、metadata 变更、公钥变更或同主机 loopback trusted-proxy header 路径。 -- 将 `sessionKey` 视为 auth token 的“缺少按用户授权”类问题。 +- 将节点配对元数据当作 `system.run` 的隐藏“每条命令二次审批层”,而真实执行边界仍然是 Gateway 网关的全局节点命令策略加上节点自身的 exec + 审批。 +- 将已配置的 `gateway.nodes.pairing.autoApproveCidrs` 本身视为漏洞。该设置默认关闭,需要显式的 CIDR/IP 条目,仅适用于首次 `role: node` 配对且未请求任何 scope 的情况,并且不会自动批准操作员/浏览器/Control UI、 + WebChat、角色升级、scope 升级、元数据变更、公钥变更,或同主机 loopback trusted-proxy header 路径。 +- 将 `sessionKey` 视为认证令牌而提出的“缺少按用户授权”问题。 -## 六十秒内完成的加固基线 +## 60 秒内完成的加固基线 -先使用这个基线,然后再根据受信任智能体的需要有选择地重新启用工具: +先使用这个基线,再按受信任智能体有选择地重新启用工具: ```json5 { @@ -157,122 +160,119 @@ OpenClaw 假设主机和配置边界是受信任的: } ``` -这样会将 Gateway 网关限制为仅本地可访问,隔离私信,并默认禁用控制平面/运行时工具。 +这样会让 Gateway 网关仅限本地使用、隔离私信,并默认禁用控制平面/运行时工具。 ## 共享收件箱快速规则 -如果有不止一个人可以给你的机器人发私信: +如果不止一个人可以给你的机器人发私信: - 设置 `session.dmScope: "per-channel-peer"`(对于多账号渠道,则使用 `"per-account-channel-peer"`)。 - 保持 `dmPolicy: "pairing"` 或使用严格的 allowlist。 -- 不要将共享私信与广泛的工具访问权限组合使用。 -- 这可以加固协作式/共享收件箱,但并不是为共享主机/配置写权限场景下的敌对共租户隔离而设计的。 +- 绝不要把共享私信与广泛的工具访问权限结合使用。 +- 这有助于加固协作式/共享收件箱,但在用户共享主机/配置写权限时,它并不是为敌对共租户隔离而设计的。 ## 上下文可见性模型 -OpenClaw 将两个概念区分开来: +OpenClaw 区分两个概念: -- **触发授权**:谁可以触发智能体(`dmPolicy`、`groupPolicy`、allowlist、mention gate)。 +- **触发授权**:谁可以触发智能体(`dmPolicy`、`groupPolicy`、allowlist、提及门槛)。 - **上下文可见性**:哪些补充上下文会被注入到模型输入中(回复正文、引用文本、线程历史、转发元数据)。 -Allowlists 控制触发和命令授权。`contextVisibility` 设置控制如何过滤补充上下文(引用回复、线程根消息、获取的历史记录): +Allowlist 控制触发和命令授权。`contextVisibility` 设置则控制如何过滤补充上下文(引用回复、线程根消息、已抓取历史): -- `contextVisibility: "all"`(默认)会按接收到的原样保留补充上下文。 +- `contextVisibility: "all"`(默认)会保留收到的全部补充上下文。 - `contextVisibility: "allowlist"` 会将补充上下文过滤为仅包含通过当前 allowlist 检查的发送者内容。 -- `contextVisibility: "allowlist_quote"` 的行为与 `allowlist` 类似,但仍会保留一条显式引用的回复。 +- `contextVisibility: "allowlist_quote"` 的行为类似 `allowlist`,但仍会保留一条显式引用回复。 -可按渠道或按房间/会话设置 `contextVisibility`。配置细节请参阅 [Group Chats](/zh-CN/channels/groups#context-visibility-and-allowlists)。 +你可以按渠道或按房间/会话设置 `contextVisibility`。配置细节请参见 [群聊](/zh-CN/channels/groups#context-visibility-and-allowlists)。 -安全通告分级指导: +安全通告分诊指南: -- 如果报告仅表明“模型可以看到来自非 allowlist 发送者的引用或历史文本”,这属于可通过 `contextVisibility` 处理的加固项,本身并不构成身份验证或沙箱边界绕过。 -- 若要被认定为具有安全影响,报告仍需展示可证明的信任边界绕过(身份验证、策略、沙箱、审批,或其他文档中定义的边界)。 +- 仅能证明“模型可以看到来自非 allowlist 发送者的引用文本或历史文本”的说法,属于可通过 `contextVisibility` 解决的加固发现,本身不构成认证或沙箱边界绕过。 +- 若要构成安全影响,报告仍需证明存在信任边界绕过(认证、策略、沙箱、审批,或其他文档化边界)。 -## 审计会检查什么(高层概述) +## 审计会检查什么(高层概览) - **入站访问**(私信策略、群组策略、allowlist):陌生人能否触发机器人? -- **工具影响半径**(高权限工具 + 开放房间):prompt injection 是否可能演变为 shell/文件/网络操作? +- **工具影响半径**(高权限工具 + 开放房间):提示注入是否可能演变为 shell/文件/网络操作? - **Exec 审批漂移**(`security=full`、`autoAllowSkills`、未启用 `strictInlineEval` 的解释器 allowlist):主机 exec 防护栏是否仍按你的预期工作? - - `security="full"` 是广泛姿态警告,不是漏洞证明。它是受信任个人助理场景下刻意选择的默认值;只有当你的威胁模型需要审批或 allowlist 防护栏时,才需要收紧。 -- **网络暴露**(Gateway 网关 bind/auth、Tailscale Serve/Funnel、弱或过短的身份验证 token)。 -- **浏览器控制暴露**(远程 node 节点、中继端口、远程 CDP 端点)。 -- **本地磁盘卫生**(权限、符号链接、config includes、“同步文件夹”路径)。 -- **插件**(插件在没有显式 allowlist 的情况下加载)。 -- **策略漂移/错误配置**(已配置沙箱 Docker 设置但沙箱模式关闭;无效的 `gateway.nodes.denyCommands` 模式,因为匹配仅针对精确命令名,例如 `system.run`,而不会检查 shell 文本;危险的 `gateway.nodes.allowCommands` 条目;全局 `tools.profile="minimal"` 被按智能体配置覆盖;在宽松工具策略下可访问插件自有工具)。 -- **运行时期望漂移**(例如误以为隐式 exec 仍表示 `sandbox`,而此时 `tools.exec.host` 默认已变为 `auto`;或者显式设置 `tools.exec.host="sandbox"`,但沙箱模式实际上是关闭的)。 -- **模型卫生**(当配置的模型看起来较旧时发出警告;不是硬性阻止)。 + - `security="full"` 是一种广泛的态势警告,不代表已经证明存在漏洞。它是受信任个人助理配置中的默认选择;只有当你的威胁模型需要审批或 allowlist 防护栏时,才应收紧它。 +- **网络暴露**(Gateway 网关绑定/认证、Tailscale Serve/Funnel、弱或过短的认证 token)。 +- **浏览器控制暴露**(远程节点、中继端口、远程 CDP 端点)。 +- **本地磁盘卫生**(权限、符号链接、配置 include、”同步文件夹”路径)。 +- **插件**(插件在没有显式 allowlist 的情况下被加载)。 +- **策略漂移/错误配置**(已配置 sandbox docker 设置但 sandbox 模式关闭;由于匹配仅按精确命令名进行——例如 `system.run`——且不会检查 shell 文本,导致 `gateway.nodes.denyCommands` 模式无效;危险的 `gateway.nodes.allowCommands` 条目;全局 `tools.profile="minimal"` 被每个智能体的 profile 覆盖;在宽松工具策略下可访问的插件自有工具)。 +- **运行时期望漂移**(例如,原以为隐式 exec 仍表示 `sandbox`,但现在 `tools.exec.host` 默认值已是 `auto`;或显式设置了 `tools.exec.host="sandbox"`,但 sandbox 模式处于关闭状态)。 +- **模型卫生**(当配置的模型看起来较旧时发出警告;不是硬性阻断)。 如果你运行 `--deep`,OpenClaw 还会尽力尝试进行一次实时 Gateway 网关探测。 ## 凭证存储映射 -在审计访问权限或决定备份内容时可参考: +在审计访问权限或决定备份内容时,可使用此清单: - **WhatsApp**:`~/.openclaw/credentials/whatsapp//creds.json` -- **Telegram bot token**:config/env 或 `channels.telegram.tokenFile`(仅允许常规文件;拒绝符号链接) -- **Discord bot token**:config/env 或 SecretRef(env/file/exec provider) -- **Slack tokens**:config/env(`channels.slack.*`) -- **Pairing allowlists**: +- **Telegram bot token**:配置/环境变量,或 `channels.telegram.tokenFile`(仅常规文件;拒绝符号链接) +- **Discord bot token**:配置/环境变量,或 SecretRef(env/file/exec 提供商) +- **Slack token**:配置/环境变量(`channels.slack.*`) +- **配对 allowlist**: - `~/.openclaw/credentials/-allowFrom.json`(默认账号) - `~/.openclaw/credentials/--allowFrom.json`(非默认账号) -- **模型 auth profiles**:`~/.openclaw/agents//agent/auth-profiles.json` -- **基于文件的 secrets 负载(可选)**:`~/.openclaw/secrets.json` +- **模型认证 profile**:`~/.openclaw/agents//agent/auth-profiles.json` +- **基于文件的 secret 负载(可选)**:`~/.openclaw/secrets.json` - **旧版 OAuth 导入**:`~/.openclaw/credentials/oauth.json` -## 安全审计清单 +## 安全审计检查清单 当审计输出发现项时,请按以下优先顺序处理: -1. **任何“开放”状态 + 已启用工具**:先收紧私信/群组(pairing/allowlist),然后再收紧工具策略/沙箱隔离。 -2. **公共网络暴露**(LAN bind、Funnel、缺少身份验证):立即修复。 -3. **浏览器控制远程暴露**:将其视为操作员访问(仅限 tailnet、有意识地配对 node 节点、避免公开暴露)。 -4. **权限**:确保 state/config/credentials/auth profiles 不可被 group/world 读取。 -5. **插件**:只加载你明确信任的内容。 -6. **模型选择**:对于任何带工具的机器人,优先使用现代、具备更强指令加固能力的模型。 +1. **任何“开放”+ 已启用工具的配置**:先锁定私信/群组(配对/allowlist),再收紧工具策略/沙箱隔离。 +2. **公共网络暴露**(LAN 绑定、Funnel、缺少认证):立即修复。 +3. **浏览器控制的远程暴露**:应将其视为操作员访问(仅 tailnet、谨慎配对节点、避免公开暴露)。 +4. **权限**:确保状态/配置/凭证/认证信息对组用户或所有用户不可读。 +5. **插件**:只加载你明确信任的插件。 +6. **模型选择**:对于任何启用了工具的机器人,优先使用现代、具备更强指令加固能力的模型。 ## 安全审计术语表 -每个审计发现项都由结构化的 `checkId` 标识(例如 -`gateway.bind_no_auth` 或 `tools.exec.security_full_configured`)。常见的高严重性类别包括: +每个审计发现都使用结构化 `checkId` 作为键(例如 +`gateway.bind_no_auth` 或 `tools.exec.security_full_configured`)。常见的严重级别类别包括: -- `fs.*` — state、config、credentials、auth profiles 的文件系统权限。 -- `gateway.*` — bind 模式、auth、Tailscale、Control UI、trusted-proxy 设置。 -- `hooks.*`、`browser.*`、`sandbox.*`、`tools.exec.*` — 各个界面的加固检查。 -- `plugins.*`、`skills.*` — plugin/skill 供应链和扫描发现项。 -- `security.exposure.*` — 访问策略与工具影响半径交汇的跨域检查。 +- `fs.*` —— 状态、配置、凭证、认证 profile 的文件系统权限。 +- `gateway.*` —— 绑定模式、认证、Tailscale、Control UI、trusted-proxy 设置。 +- `hooks.*`、`browser.*`、`sandbox.*`、`tools.exec.*` —— 各表面的加固项。 +- `plugins.*`、`skills.*` —— 插件/Skills 供应链与扫描发现。 +- `security.exposure.*` —— 访问策略与工具影响半径交汇的跨领域检查。 -完整目录(含严重等级、修复键名和自动修复支持)请参阅 -[Security audit checks](/zh-CN/gateway/security/audit-checks)。 +完整目录(包括严重级别、修复键、自动修复支持)见 +[安全审计检查项](/zh-CN/gateway/security/audit-checks)。 -## 通过 HTTP 访问 Control UI +## 通过 HTTP 使用 Control UI Control UI 需要**安全上下文**(HTTPS 或 localhost)才能生成设备身份。 `gateway.controlUi.allowInsecureAuth` 是一个本地兼容性开关: -- 在 localhost 上,当页面通过非安全 HTTP 加载时,它允许 Control UI 在没有设备身份的情况下进行身份验证。 +- 在 localhost 上,当页面通过非安全 HTTP 加载时,它允许 Control UI 在没有设备身份的情况下进行认证。 - 它不会绕过配对检查。 - 它不会放宽远程(非 localhost)设备身份要求。 -优先使用 HTTPS(Tailscale Serve)或在 `127.0.0.1` 上打开 UI。 +优先使用 HTTPS(Tailscale Serve),或在 `127.0.0.1` 上打开 UI。 -仅在紧急兜底场景下,`gateway.controlUi.dangerouslyDisableDeviceAuth` -会完全禁用设备身份检查。这会严重降低安全性; -除非你正在主动调试并且能快速恢复,否则请保持关闭。 +仅用于紧急兜底场景时,`gateway.controlUi.dangerouslyDisableDeviceAuth` +会完全禁用设备身份检查。这是严重的安全降级;除非你正在主动调试且能够快速恢复,否则请保持关闭。 -与这些危险标志无关,成功启用 `gateway.auth.mode: "trusted-proxy"` -可以允许**操作员**的 Control UI 会话在没有设备身份的情况下接入。这是 -有意设计的 auth 模式行为,而不是 `allowInsecureAuth` 的捷径,并且它仍然 -不适用于 node-role 的 Control UI 会话。 +与这些危险标志分开的是,成功配置 `gateway.auth.mode: "trusted-proxy"` +时,可以在没有设备身份的情况下接纳**操作员**的 Control UI 会话。这是有意的认证模式行为,不是 `allowInsecureAuth` 的捷径,而且它仍然不适用于 node 角色的 Control UI 会话。 -当此设置启用时,`openclaw security audit` 会发出警告。 +当该设置启用时,`openclaw security audit` 会发出警告。 ## 不安全或危险标志摘要 -当已知不安全/危险的调试开关被启用时,`openclaw security audit` 会触发 `config.insecure_or_dangerous_flags`。 -在生产环境中请保持这些开关未设置。 +当已启用已知不安全/危险的调试开关时, +`openclaw security audit` 会触发 `config.insecure_or_dangerous_flags`。在生产环境中请保持这些值未设置。 - + - `gateway.controlUi.allowInsecureAuth=true` - `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true` - `gateway.controlUi.dangerouslyDisableDeviceAuth=true` @@ -289,7 +289,8 @@ Control UI 需要**安全上下文**(HTTPS 或 localhost)才能生成设备 - `gateway.controlUi.dangerouslyDisableDeviceAuth` - `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` - 渠道名称匹配(内置渠道和插件渠道;在适用情况下,`accounts.` 下也可用): + 渠道名称匹配(内置渠道和插件渠道;在适用情况下,也可按 + `accounts.` 配置): - `channels.discord.dangerouslyAllowNameMatching` - `channels.slack.dangerouslyAllowNameMatching` @@ -303,9 +304,9 @@ Control UI 需要**安全上下文**(HTTPS 或 localhost)才能生成设备 网络暴露: - - `channels.telegram.network.dangerouslyAllowPrivateNetwork`(也支持按账号设置) + - `channels.telegram.network.dangerouslyAllowPrivateNetwork`(也支持按账号配置) - 沙箱 Docker(默认值 + 按智能体): + Sandbox Docker(默认值 + 每个智能体): - `agents.defaults.sandbox.docker.dangerouslyAllowReservedContainerTargets` - `agents.defaults.sandbox.docker.dangerouslyAllowExternalBindSources` @@ -316,16 +317,16 @@ Control UI 需要**安全上下文**(HTTPS 或 localhost)才能生成设备 ## 反向代理配置 -如果你在反向代理(nginx、Caddy、Traefik 等)后面运行 Gateway 网关,请配置 -`gateway.trustedProxies`,以便正确处理转发后的客户端 IP。 +如果你在反向代理(nginx、Caddy、Traefik 等)后运行 Gateway 网关,请配置 +`gateway.trustedProxies`,以正确处理转发客户端 IP。 -当 Gateway 网关检测到来自**不在** `trustedProxies` 中地址的代理头时,它**不会**将连接视为本地客户端。如果 gateway auth 被禁用,这些连接会被拒绝。这样可以防止身份验证绕过,因为否则经过代理的连接可能看起来像来自 localhost,从而获得自动信任。 +当 Gateway 网关检测到来自**不在** `trustedProxies` 中地址的代理头时,它将**不会**把这些连接视为本地客户端。如果 gateway 认证已关闭,这些连接会被拒绝。这样可以防止认证绕过——否则被代理的连接可能看起来像来自 localhost,从而自动获得信任。 -`gateway.trustedProxies` 也会用于 `gateway.auth.mode: "trusted-proxy"`,但该 auth 模式更严格: +`gateway.trustedProxies` 也会用于 `gateway.auth.mode: "trusted-proxy"`,但该认证模式更加严格: -- trusted-proxy auth **对来自 loopback 源的代理默认失败关闭** +- trusted-proxy 认证会对 loopback 来源代理**失败即关闭** - 同主机 loopback 反向代理仍可使用 `gateway.trustedProxies` 进行本地客户端识别和转发 IP 处理 -- 对于同主机 loopback 反向代理,请使用 token/password auth,而不要使用 `gateway.auth.mode: "trusted-proxy"` +- 对于同主机 loopback 反向代理,请使用 token/password 认证,而不是 `gateway.auth.mode: "trusted-proxy"` ```yaml gateway: @@ -339,12 +340,10 @@ gateway: password: ${OPENCLAW_GATEWAY_PASSWORD} ``` -当配置了 `trustedProxies` 时,Gateway 网关会使用 `X-Forwarded-For` 来确定客户端 IP。默认会忽略 `X-Real-IP`,除非显式设置 `gateway.allowRealIpFallback: true`。 +当配置了 `trustedProxies` 后,Gateway 网关会使用 `X-Forwarded-For` 来确定客户端 IP。默认情况下会忽略 `X-Real-IP`,除非显式设置了 `gateway.allowRealIpFallback: true`。 -Trusted proxy headers 不会让 node 节点设备配对自动成为受信任操作。 -`gateway.nodes.pairing.autoApproveCidrs` 是单独的、默认关闭的 -操作员策略。即使启用了它,来自 loopback 源的 trusted-proxy header 路径 -也会被排除在 node 节点自动批准之外,因为本地调用方可以伪造这些 headers。 +Trusted proxy 头不会让节点设备配对自动变为受信任。 +`gateway.nodes.pairing.autoApproveCidrs` 是单独的、默认关闭的操作员策略。即使启用它,来自 loopback 的 trusted-proxy header 路径也会被排除在节点自动批准之外,因为本地调用方可以伪造这些头。 良好的反向代理行为(覆盖传入的转发头): @@ -361,50 +360,51 @@ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ## HSTS 和 origin 说明 -- OpenClaw Gateway 网关优先面向本地/loopback。如果你在反向代理处终止 TLS,请在代理所面对的 HTTPS 域名上设置 HSTS。 -- 如果由 Gateway 网关自身终止 HTTPS,你可以设置 `gateway.http.securityHeaders.strictTransportSecurity`,让 OpenClaw 响应中发出 HSTS header。 +- OpenClaw Gateway 网关优先面向本地/local loopback。如果你在反向代理处终止 TLS,请在代理所面向的 HTTPS 域名上设置 HSTS。 +- 如果由 gateway 自身终止 HTTPS,你可以设置 `gateway.http.securityHeaders.strictTransportSecurity`,让 OpenClaw 响应发出 HSTS 头。 - 详细部署指南见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth#tls-termination-and-hsts)。 -- 对于非 loopback 的 Control UI 部署,默认要求设置 `gateway.controlUi.allowedOrigins`。 -- `gateway.controlUi.allowedOrigins: ["*"]` 是显式的允许所有浏览器 origin 的策略,不是加固后的默认值。除非是在严格受控的本地测试中,否则请避免使用。 -- 即使启用了一般性的 loopback 豁免,loopback 上的浏览器 origin 身份验证失败仍会受到限速,但锁定键会按规范化后的 `Origin` 值分别作用,而不是共享一个 localhost 桶。 -- `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true` 会启用基于 Host header 的 origin 回退模式;应将其视为由操作员主动选择的危险策略。 -- 应将 DNS rebinding 和代理 Host header 行为视为部署加固问题;保持 `trustedProxies` 严格收敛,并避免将 Gateway 网关直接暴露到公共互联网。 +- 对于非 loopback 的 Control UI 部署,默认要求配置 `gateway.controlUi.allowedOrigins`。 +- `gateway.controlUi.allowedOrigins: ["*"]` 是显式允许所有浏览器来源的策略,不是加固默认值。除受严格控制的本地测试外,应避免使用。 +- 即使启用了通用 loopback 豁免,loopback 上的浏览器来源认证失败仍会受到速率限制,但锁定键会按规范化后的 `Origin` 值划分,而不是共用一个 localhost 桶。 +- `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true` 会启用 Host 头 origin 回退模式;应将其视为操作员主动选择的危险策略。 +- 应将 DNS 重绑定和代理 Host 头行为视为部署加固问题;保持 `trustedProxies` 严格,并避免将 gateway 直接暴露到公共互联网。 -## 本地 session 日志会落盘保存 +## 本地会话日志存储在磁盘上 -OpenClaw 会将 session 转录记录保存在磁盘上的 `~/.openclaw/agents//sessions/*.jsonl` 中。 -这是实现 session 连续性以及(可选)session memory 索引所必需的,但这也意味着 -**任何具有文件系统访问权限的进程/用户都可以读取这些日志**。应将磁盘访问视为信任 -边界,并收紧 `~/.openclaw` 的权限(见下方审计部分)。如果你需要在不同智能体之间实现 -更强的隔离,请让它们运行在不同的操作系统用户下,或使用不同主机。 +OpenClaw 会将会话记录存储在磁盘上的 `~/.openclaw/agents//sessions/*.jsonl`。 +这对于会话连续性以及(可选的)会话 Memory 索引是必需的,但这也意味着 +**任何拥有文件系统访问权限的进程/用户都可以读取这些日志**。应将磁盘访问视为信任 +边界,并锁定 `~/.openclaw` 的权限(参见下方审计章节)。如果你需要在智能体之间实现更强隔离,请让它们运行在独立的 OS 用户或独立主机下。 -## Node 节点执行(system.run) +## 节点执行(`system.run`) -如果已配对一个 macOS node 节点,Gateway 网关可以在该 node 节点上调用 `system.run`。这就是在该 Mac 上的**远程代码执行**: +如果某个 macOS 节点已配对,Gateway 网关就可以在该节点上调用 `system.run`。这意味着在该 Mac 上进行**远程代码执行**: -- 需要 node 节点配对(审批 + token)。 -- Gateway 网关的 node 节点配对并不是逐命令审批界面。它建立的是 node 节点身份/信任以及 token 发放。 -- Gateway 网关通过 `gateway.nodes.allowCommands` / `denyCommands` 应用粗粒度的全局 node 节点命令策略。 -- 在 Mac 上通过**设置 → Exec 审批**进行控制(security + ask + allowlist)。 -- 每个 node 节点的 `system.run` 策略由该 node 节点自己的 exec 审批文件(`exec.approvals.node.*`)决定,它可以比 Gateway 网关的全局命令 ID 策略更严格,也可以更宽松。 -- 以 `security="full"` 和 `ask="off"` 运行的 node 节点,遵循的是默认的受信任操作员模型。除非你的部署明确要求更严格的审批或 allowlist 策略,否则应将其视为预期行为。 -- 审批模式会绑定精确的请求上下文,并在可能时绑定一个具体的本地脚本/文件操作数。如果 OpenClaw 无法为解释器/运行时命令准确识别出唯一的直接本地文件,那么基于审批的执行会被拒绝,而不是承诺提供完整的语义覆盖。 -- 对于 `host=node`,基于审批的运行还会存储一个规范化的预备 `systemRunPlan`;之后转发已获批准的请求时会复用该存储计划,并且 Gateway 网关验证会拒绝调用方在审批请求创建后对 command/cwd/session 上下文的修改。 -- 如果你不希望允许远程执行,请将 security 设置为 **deny**,并移除该 Mac 的 node 节点配对。 +- 需要节点配对(审批 + token)。 +- Gateway 网关节点配对并不是逐条命令审批表面。它建立的是节点身份/信任以及 token 签发。 +- Gateway 网关通过 `gateway.nodes.allowCommands` / `denyCommands` 应用粗粒度的全局节点命令策略。 +- 在 Mac 上通过**设置 → Exec 审批**控制(security + ask + allowlist)。 +- 每个节点的 `system.run` 策略由该节点自身的 exec 审批文件(`exec.approvals.node.*`)决定,它可以比 gateway 的全局命令 ID 策略更严格,也可以更宽松。 +- 以 `security="full"` 和 `ask="off"` 运行的节点,是在遵循默认的受信任操作员模型。除非你的部署明确要求更严格的审批或 allowlist 策略,否则应将其视为预期行为。 +- 审批模式会绑定精确的请求上下文,并在可能时绑定一个具体的本地脚本/文件操作数。如果 OpenClaw 无法为解释器/运行时命令准确识别唯一一个直接本地文件,那么基于审批的执行会被拒绝,而不是声称具备完整的语义覆盖。 +- 对于 `host=node`,基于审批的运行还会存储一个规范化、已准备好的 + `systemRunPlan`;之后获得批准的转发会复用该已存储计划,而 gateway + 校验会拒绝调用方在审批请求创建后修改命令/cwd/session 上下文。 +- 如果你不希望发生远程执行,请将 security 设为 **deny**,并移除该 Mac 的节点配对。 -这个区分对于分级判断很重要: +这个区别对分诊很重要: -- 已配对 node 节点重连后声明了不同的命令列表,本身并不构成漏洞,只要 Gateway 网关全局策略和 node 节点本地 exec 审批仍然在强制执行真正的执行边界。 -- 将 node 节点配对元数据视为隐藏的第二层逐命令审批机制的报告,通常是策略/UX 理解混淆,而不是安全边界绕过。 +- 一个重新连接的已配对节点宣告了不同的命令列表,如果 Gateway 网关的全局策略和该节点的本地 exec 审批仍然在强制执行真实执行边界,那么这本身并不构成漏洞。 +- 将节点配对元数据视为第二层隐藏的逐命令审批层的报告,通常是策略/UX 理解混淆,而不是安全边界绕过。 -## 动态 Skills(watcher / 远程 nodes) +## 动态 Skills(watcher / 远程节点) OpenClaw 可以在 session 中途刷新 Skills 列表: -- **Skills watcher**:对 `SKILL.md` 的修改可以在下一次智能体轮次中更新 Skills 快照。 -- **远程 nodes**:连接 macOS node 节点后,可能使仅限 macOS 的 Skills 变为可用(基于 bin 探测)。 +- **Skills watcher**:`SKILL.md` 的变更可以在下一次智能体轮次更新 Skills 快照。 +- **远程节点**:连接 macOS 节点后,可以使仅限 macOS 的 Skills 变为可选(基于 bin 探测)。 -应将 skill 文件夹视为**受信任代码**,并限制可修改它们的人。 +请将 skill 文件夹视为**受信任代码**,并限制谁可以修改它们。 ## 威胁模型 @@ -417,45 +417,43 @@ OpenClaw 可以在 session 中途刷新 Skills 列表: 给你发消息的人可以: -- 试图诱骗你的 AI 执行坏操作 -- 通过社会工程学方式获取你的数据访问权限 -- 探测你的基础设施细节 +- 试图诱骗你的 AI 做坏事 +- 通过社会工程方式获取你的数据访问权 +- 探测基础设施细节 ## 核心概念:先做访问控制,再谈智能 -这里的大多数失败并不是花哨的漏洞利用——而是“有人给机器人发了消息,机器人照做了”。 +这里的大多数失败都不是复杂利用,而是“有人给机器人发了消息,而机器人照做了”。 OpenClaw 的立场: -- **身份优先:** 先决定谁可以和机器人对话(私信 pairing / allowlists / 显式 `open`)。 -- **范围其次:** 再决定机器人可以在哪里执行操作(群组 allowlists + mention gating、工具、沙箱隔离、设备权限)。 -- **模型最后:** 假设模型可能被操纵;设计时要让这种操纵的影响半径有限。 +- **身份优先:**先决定谁可以和机器人对话(私信配对 / allowlist / 显式 `open`)。 +- **范围其次:**再决定机器人被允许在哪些地方执行操作(群组 allowlist + 提及门槛、工具、沙箱隔离、设备权限)。 +- **模型最后:**假设模型可能被操纵;设计时应让这种操纵的影响半径受限。 ## 命令授权模型 -Slash commands 和 directives 仅对**已授权发送者**生效。授权来源于 -渠道 allowlists/pairing 加上 `commands.useAccessGroups`(参见 [Configuration](/zh-CN/gateway/configuration) -和 [Slash commands](/zh-CN/tools/slash-commands))。如果某个渠道的 allowlist 为空或包含 `"*"`, +Slash 命令和指令只会对**已授权发送者**生效。授权来源于 +渠道 allowlist/配对,以及 `commands.useAccessGroups`(参见[配置](/zh-CN/gateway/configuration) +和 [Slash 命令](/zh-CN/tools/slash-commands))。如果某个渠道的 allowlist 为空或包含 `"*"`, 那么该渠道上的命令实际上就是开放的。 -`/exec` 是面向已授权操作员的仅 session 内便捷功能。它**不会**写入配置,也**不会** -修改其他 sessions。 +`/exec` 是仅限 session 的便捷功能,供已授权操作员使用。它**不会**写入配置,也**不会** +更改其他 session。 ## 控制平面工具风险 -有两个内置工具可以进行持久性的控制平面更改: +两个内置工具可以进行持久性的控制平面变更: -- `gateway` 可以通过 `config.schema.lookup` / `config.get` 检查配置,也可以通过 `config.apply`、`config.patch` 和 `update.run` 进行持久化修改。 -- `cron` 可以创建调度任务,使其在原始聊天/任务结束后继续运行。 +- `gateway` 可以通过 `config.schema.lookup` / `config.get` 检查配置,也可以通过 `config.apply`、`config.patch` 和 `update.run` 进行持久性修改。 +- `cron` 可以创建计划任务,在原始聊天/任务结束后仍持续运行。 -仅限 owner 的 `gateway` 运行时工具仍然拒绝重写 -`tools.exec.ask` 或 `tools.exec.security`;旧版 `tools.bash.*` 别名也会 -在写入前被规范化为相同的受保护 exec 路径。 -由智能体驱动的 `gateway config.apply` 和 `gateway config.patch` 编辑默认 -采用失败关闭:只有一小部分 prompt、model 和 mention gating 路径允许由智能体调整。 -因此,新的敏感配置树会默认受到保护,除非你有意将其加入 allowlist。 +仅限所有者的 `gateway` 运行时工具仍然拒绝重写 +`tools.exec.ask` 或 `tools.exec.security`;旧版 `tools.bash.*` 别名在写入前 +会被规范化为相同的受保护 exec 路径。 +由智能体驱动的 `gateway config.apply` 和 `gateway config.patch` 编辑默认采用失败即关闭:只有一小部分 prompt、模型和提及门槛路径可由智能体调整。因此,新的敏感配置树默认会受到保护,除非你有意将其加入 allowlist。 -对于任何处理不受信任内容的智能体/界面,默认应拒绝这些工具: +对于任何处理不受信任内容的智能体/表面,默认都应拒绝这些工具: ```json5 { @@ -465,33 +463,33 @@ Slash commands 和 directives 仅对**已授权发送者**生效。授权来源 } ``` -`commands.restart=false` 只会阻止重启动作。它不会禁用 `gateway` 配置/更新操作。 +`commands.restart=false` 只会阻止重启动作。它不会禁用 `gateway` 的配置/更新操作。 ## 插件 -插件以**进程内**方式与 Gateway 网关一起运行。应将它们视为受信任代码: +插件会与 Gateway 网关**在同一进程内**运行。应将其视为受信任代码: -- 仅安装来自你信任来源的插件。 -- 优先使用显式 `plugins.allow` allowlists。 +- 只安装来自你信任来源的插件。 +- 优先使用显式 `plugins.allow` allowlist。 - 启用前审查插件配置。 - 修改插件后重启 Gateway 网关。 - 如果你安装或更新插件(`openclaw plugins install `、`openclaw plugins update `),应将其视为运行不受信任代码: - - 安装路径是当前插件安装根目录下对应插件的目录。 - - OpenClaw 会在安装/更新前运行内置危险代码扫描。`critical` 级发现默认会阻止安装。 - - OpenClaw 使用 `npm pack`,然后在该目录中运行项目本地的 `npm install --omit=dev --ignore-scripts`。继承来的全局 npm 安装设置会被忽略,以确保依赖保留在插件安装路径下。 - - 优先使用固定的精确版本(`@scope/pkg@1.2.3`),并在启用前检查磁盘上解包后的代码。 - - `--dangerously-force-unsafe-install` 仅用于在插件安装/更新流程中应对内置扫描误报的紧急兜底场景。它不会绕过插件 `before_install` hook 策略阻止,也不会绕过扫描失败。 - - 由 Gateway 网关驱动的 skill 依赖安装遵循相同的危险/可疑划分:内置 `critical` 发现默认会阻止,除非调用方显式设置 `dangerouslyForceUnsafeInstall`;而可疑发现仍然只是警告。`openclaw skills install` 仍然是单独的 ClawHub skill 下载/安装流程。 + - 安装路径是当前插件安装根目录下的每插件目录。 + - OpenClaw 会在安装/更新前运行内置危险代码扫描。`critical` 发现默认会阻止操作。 + - OpenClaw 使用 `npm pack`,然后在该目录内运行项目本地的 `npm install --omit=dev --ignore-scripts`。继承的全局 npm 安装设置会被忽略,因此依赖会保持在插件安装路径下。 + - 优先使用固定、精确的版本(`@scope/pkg@1.2.3`),并在启用前检查磁盘上解包后的代码。 + - `--dangerously-force-unsafe-install` 仅用于插件安装/更新流程中,内置扫描出现误报时的紧急兜底场景。它不会绕过插件 `before_install` 钩子策略阻止,也不会绕过扫描失败。 + - 由 Gateway 网关支持的 skill 依赖安装遵循相同的危险/可疑划分:内置 `critical` 发现会阻止安装,除非调用方显式设置 `dangerouslyForceUnsafeInstall`;而可疑发现仍仅发出警告。`openclaw skills install` 仍然是单独的 ClawHub skill 下载/安装流程。 -详情见:[Plugins](/zh-CN/tools/plugin) +详情见:[插件](/zh-CN/tools/plugin) ## 私信访问模型:pairing、allowlist、open、disabled -当前所有支持私信的渠道都支持 DM 策略(`dmPolicy` 或 `*.dm.policy`),它会在处理消息**之前**拦截入站私信: +当前所有支持私信的渠道都支持一个私信策略(`dmPolicy` 或 `*.dm.policy`),用于在消息被处理**之前**控制入站私信: -- `pairing`(默认):未知发送者会收到一个简短配对码,机器人会忽略其消息,直到获得批准。配对码 1 小时后过期;重复发送私信不会重复发送配对码,直到创建新的请求。默认情况下,待处理请求每个渠道最多 **3 个**。 -- `allowlist`:未知发送者会被阻止(没有 pairing 握手)。 -- `open`:允许任何人发送私信(公开)。**要求** 该渠道的 allowlist 包含 `"*"`(显式选择加入)。 +- `pairing`(默认):未知发送者会收到一个简短的配对码,机器人会忽略其消息,直到获得批准。配对码 1 小时后过期;重复发送私信不会重新发送配对码,除非创建了新的请求。默认情况下,待处理请求每个渠道最多 **3 个**。 +- `allowlist`:未知发送者会被阻止(没有配对握手)。 +- `open`:允许任何人发送私信(公开)。**要求**该渠道的 allowlist 包含 `"*"`(显式选择启用)。 - `disabled`:完全忽略入站私信。 通过 CLI 批准: @@ -501,11 +499,11 @@ openclaw pairing list openclaw pairing approve ``` -详情和磁盘文件位置见:[Pairing](/zh-CN/channels/pairing) +详情和磁盘文件位置见:[配对](/zh-CN/channels/pairing) ## 私信 session 隔离(多用户模式) -默认情况下,OpenClaw 会将**所有私信路由到主 session**,这样你的助手就能在设备和渠道之间保持连续性。如果**有多个人**可以给机器人发私信(开放私信或多人 allowlist),请考虑隔离私信 sessions: +默认情况下,OpenClaw 会将**所有私信都路由到主 session**,这样你的助手可以在设备和渠道之间保持连续性。如果**有多个人**可以给机器人发私信(开放私信或多人 allowlist),请考虑隔离私信 session: ```json5 { @@ -513,217 +511,211 @@ openclaw pairing approve } ``` -这样可以防止跨用户上下文泄露,同时仍保持群聊隔离。 +这样可以防止跨用户上下文泄露,同时保持群聊彼此隔离。 -这是消息上下文边界,不是主机管理员边界。如果用户彼此对抗,且共享同一个 Gateway 网关主机/配置,请按信任边界运行单独的 Gateway 网关。 +这是消息上下文边界,不是主机管理员边界。如果这些用户彼此具有对抗关系且共享同一个 Gateway 网关主机/配置,请按信任边界运行独立的 Gateway 网关。 ### 安全私信模式(推荐) 将上面的片段视为**安全私信模式**: -- 默认:`session.dmScope: "main"`(所有私信共享一个 session,以保持连续性)。 -- 本地 CLI 新手引导默认:在未设置时写入 `session.dmScope: "per-channel-peer"`(保留现有显式值)。 -- 安全私信模式:`session.dmScope: "per-channel-peer"`(每个渠道 + 发送者组合获得独立的私信上下文)。 -- 跨渠道对等隔离:`session.dmScope: "per-peer"`(同一类型的所有渠道中,每个发送者共享一个 session)。 +- 默认值:`session.dmScope: "main"`(所有私信共享一个 session,以保持连续性)。 +- 本地 CLI 新手引导默认值:当未设置时,写入 `session.dmScope: "per-channel-peer"`(保留现有显式值)。 +- 安全私信模式:`session.dmScope: "per-channel-peer"`(每个渠道 + 发送者组合获得一个隔离的私信上下文)。 +- 跨渠道联系人隔离:`session.dmScope: "per-peer"`(每个发送者在同一类型的所有渠道中共享一个 session)。 -如果你在同一渠道上运行多个账号,请改用 `per-account-channel-peer`。如果同一个人通过多个渠道联系你,可以使用 `session.identityLinks` 将这些私信 sessions 合并为一个规范身份。详见 [Session Management](/zh-CN/concepts/session) 和 [Configuration](/zh-CN/gateway/configuration)。 +如果你在同一渠道上运行多个账号,请改用 `per-account-channel-peer`。如果同一个人通过多个渠道联系你,请使用 `session.identityLinks` 将这些私信 session 合并为一个规范身份。参见[会话管理](/zh-CN/concepts/session)和[配置](/zh-CN/gateway/configuration)。 -## 私信和群组的 allowlists +## 私信和群组的 allowlist -OpenClaw 有两层独立的“谁能触发我?”机制: +OpenClaw 有两个独立的“谁可以触发我?”层级: - **私信 allowlist**(`allowFrom` / `channels.discord.allowFrom` / `channels.slack.allowFrom`;旧版:`channels.discord.dm.allowFrom`、`channels.slack.dm.allowFrom`):谁被允许在私信中与机器人对话。 - - 当 `dmPolicy="pairing"` 时,批准结果会写入 `~/.openclaw/credentials/` 下按账号划分的 pairing allowlist 存储中(默认账号使用 `-allowFrom.json`,非默认账号使用 `--allowFrom.json`),并与 config allowlists 合并。 -- **群组 allowlist**(按渠道区分):机器人总体上接受哪些群组/频道/guild 的消息。 + - 当 `dmPolicy="pairing"` 时,批准结果会写入 `~/.openclaw/credentials/` 下按账号划分的配对 allowlist 存储(默认账号使用 `-allowFrom.json`,非默认账号使用 `--allowFrom.json`),并与配置中的 allowlist 合并。 +- **群组 allowlist**(按渠道定义):机器人总体上会接受哪些群组/频道/服务器中的消息。 - 常见模式: - - `channels.whatsapp.groups`、`channels.telegram.groups`、`channels.imessage.groups`:按群组设置默认值,如 `requireMention`;设置后也会充当群组 allowlist(包含 `"*"` 可保持允许所有的行为)。 - - `groupPolicy="allowlist"` + `groupAllowFrom`:限制在群组 session **内部**谁可以触发机器人(WhatsApp/Telegram/Signal/iMessage/Microsoft Teams)。 - - `channels.discord.guilds` / `channels.slack.channels`:按界面划分的 allowlists + mention 默认值。 - - 群组检查顺序如下:先检查 `groupPolicy`/群组 allowlists,再检查 mention/reply 激活。 - - 回复机器人消息(隐式 mention)**不会**绕过诸如 `groupAllowFrom` 之类的发送者 allowlists。 - - **安全说明:** 应将 `dmPolicy="open"` 和 `groupPolicy="open"` 视为最后手段。应尽量少用;除非你完全信任房间中的每个成员,否则优先使用 pairing + allowlists。 + - `channels.whatsapp.groups`、`channels.telegram.groups`、`channels.imessage.groups`:按群组设置默认值,如 `requireMention`;设置后,它也会充当群组 allowlist(包含 `"*"` 可保持允许所有的行为)。 + - `groupPolicy="allowlist"` + `groupAllowFrom`:限制在群组 session _内部_ 哪些人可以触发机器人(WhatsApp/Telegram/Signal/iMessage/Microsoft Teams)。 + - `channels.discord.guilds` / `channels.slack.channels`:按表面设置 allowlist + 默认提及规则。 + - 群组检查按此顺序运行:先 `groupPolicy`/群组 allowlist,后提及/回复激活。 + - 回复机器人消息(隐式提及)**不会**绕过像 `groupAllowFrom` 这样的发送者 allowlist。 + - **安全说明:**应将 `dmPolicy="open"` 和 `groupPolicy="open"` 视为最后手段设置。它们应尽量少用;除非你完全信任房间内每一位成员,否则优先使用配对 + allowlist。 -详情见:[Configuration](/zh-CN/gateway/configuration) 和 [Groups](/zh-CN/channels/groups) +详情见:[配置](/zh-CN/gateway/configuration)和[群组](/zh-CN/channels/groups) -## Prompt injection(它是什么,为什么重要) +## 提示注入(是什么,为什么重要) -Prompt injection 是指攻击者构造一条消息,操纵模型去执行不安全的事情(例如“忽略你的指令”“导出你的文件系统”“打开这个链接并运行命令”等)。 +提示注入是指攻击者精心构造消息,操纵模型执行不安全行为(“忽略你的指令”“导出你的文件系统”“访问这个链接并运行命令”等)。 -即使有很强的 system prompt,**prompt injection 也没有被解决**。System prompt 防护栏只是软性指导;真正的硬性执行来自工具策略、exec 审批、沙箱隔离和渠道 allowlists(而且操作员按设计可以禁用这些机制)。实际中真正有帮助的是: +即使有很强的系统提示词,**提示注入也尚未被解决**。系统提示词防护栏只是软性指导;硬性强制来自工具策略、exec 审批、沙箱隔离和渠道 allowlist(并且按设计,操作员可以关闭这些机制)。实践中真正有帮助的是: -- 保持入站私信为锁定状态(pairing/allowlists)。 -- 在群组中优先使用 mention gating;避免在公共房间中部署“始终在线”的机器人。 +- 保持入站私信处于锁定状态(配对/allowlist)。 +- 在群组中优先使用提及门槛;避免在公共房间中部署“始终在线”的机器人。 - 默认将链接、附件和粘贴的指令视为不受信任内容。 -- 在沙箱中执行敏感工具;不要把 secrets 放在智能体可访问的文件系统中。 -- 注意:沙箱隔离是可选启用的。如果沙箱模式关闭,隐式 `host=auto` 会解析为 gateway 主机。显式 `host=sandbox` 仍会失败关闭,因为没有可用的沙箱运行时。如果你希望在配置中明确表示该行为,请设置 `host=gateway`。 -- 将高风险工具(`exec`、`browser`、`web_fetch`、`web_search`)限制给受信任智能体或显式 allowlists。 -- 如果你对解释器进行 allowlist 配置(`python`、`node`、`ruby`、`perl`、`php`、`lua`、`osascript`),请启用 `tools.exec.strictInlineEval`,这样内联 eval 形式仍需要显式审批。 -- Shell 审批分析还会拒绝**未加引号 heredoc** 中的 POSIX 参数展开形式(`$VAR`、`$?`、`$$`、`$1`、`$@`、`${…}`),因此处于 allowlist 中的 heredoc 正文不能把 shell 展开伪装成普通文本绕过 allowlist 审查。给 heredoc 终止符加引号(例如 `<<'EOF'`)即可选择字面量正文语义;若未加引号的 heredoc 本会触发变量展开,则会被拒绝。 -- **模型选择很重要:** 较老/较小/旧版模型在抵御 prompt injection 和工具滥用方面明显更弱。对于启用了工具的智能体,请使用当前可用的最新一代、经过指令加固的最强模型。 +- 在沙箱中运行敏感工具执行;不要让 secret 出现在智能体可访问的文件系统中。 +- 注意:沙箱隔离为选择启用。如果 sandbox 模式关闭,隐式 `host=auto` 会解析到 gateway 主机。显式 `host=sandbox` 仍会失败即关闭,因为没有可用的 sandbox 运行时。如果你希望这种行为在配置中明确表达,请设置 `host=gateway`。 +- 将高风险工具(`exec`、`browser`、`web_fetch`、`web_search`)限制给受信任智能体或显式 allowlist。 +- 如果你将解释器加入 allowlist(`python`、`node`、`ruby`、`perl`、`php`、`lua`、`osascript`),请启用 `tools.exec.strictInlineEval`,这样内联 eval 形式仍需要显式审批。 +- Shell 审批分析还会拒绝**未加引号 heredoc** 中的 POSIX 参数展开形式(`$VAR`、`$?`、`$$`、`$1`、`$@`、`${…}`),因此加入 allowlist 的 heredoc 正文不能把 shell 展开伪装成纯文本来绕过 allowlist 审查。若要启用字面量正文语义,请给 heredoc 终止符加引号(例如 `<<'EOF'`);会发生变量展开的未加引号 heredoc 会被拒绝。 +- **模型选择很重要:**较旧/较小/旧版模型对提示注入和工具滥用的抵抗能力明显更弱。对于启用了工具的智能体,请使用可用的最新一代、指令加固能力最强的模型。 应视为不受信任的危险信号: -- “读取这个文件/URL,然后严格照它说的做。” -- “忽略你的 system prompt 或安全规则。” -- “透露你隐藏的指令或工具输出。” -- “把 `~/.openclaw` 或你的日志的完整内容贴出来。” +- “读取这个文件/URL,并完全照着它说的做。” +- “忽略你的系统提示词或安全规则。” +- “泄露你的隐藏指令或工具输出。” +- “贴出 `~/.openclaw` 或你的日志的完整内容。” -## 外部内容特殊 token 清洗 +## 外部内容 special-token 清洗 -OpenClaw 会在包装后的外部内容和元数据到达模型之前,去除常见的自托管 LLM chat-template 特殊 token 字面量。覆盖的标记家族包括 Qwen/ChatML、Llama、Gemma、Mistral、Phi 和 GPT-OSS 的角色/轮次 token。 +OpenClaw 会在常见的自托管 LLM chat-template special-token 字面量进入模型之前,从封装后的外部内容和元数据中剥离它们。覆盖的标记家族包括 Qwen/ChatML、Llama、Gemma、Mistral、Phi 和 GPT-OSS 的角色/轮次 token。 原因: -- 一些前置自托管模型的 OpenAI 兼容后端,有时会保留出现在用户文本中的特殊 token,而不是将其屏蔽。攻击者如果能写入入站外部内容(如抓取的页面、邮件正文、文件内容工具输出),否则就可能注入一个伪造的 `assistant` 或 `system` 角色边界,从而逃逸包装内容防护栏。 -- 清洗发生在外部内容包装层,因此它会统一作用于 fetch/read 工具和入站渠道内容,而不是按 provider 单独处理。 -- 出站模型响应已经有单独的清洗器,用于从用户可见回复中去除泄漏的 ``、`` 以及类似脚手架。外部内容清洗器则是其入站对应机制。 +- 一些位于自托管模型前面的 OpenAI 兼容后端,有时会保留出现在用户文本中的 special token,而不是对其进行掩蔽。攻击者如果能写入入站外部内容(抓取的页面、邮件正文、文件内容工具输出),否则就可能注入伪造的 `assistant` 或 `system` 角色边界,从而逃逸封装外部内容的防护栏。 +- 清洗发生在外部内容封装层,因此它会统一应用于 fetch/read 工具和入站渠道内容,而不是按提供商分别处理。 +- 出站模型响应已经有单独的清洗器,会从面向用户的回复中去掉泄露的 ``、`` 及类似脚手架。外部内容清洗器则是它在入站方向上的对应物。 -这并不能替代本页中的其他加固措施——`dmPolicy`、allowlists、exec 审批、沙箱隔离和 `contextVisibility` 仍然承担主要防护作用。它封堵的是一种特定的 tokenizer 层绕过:在会原样转发带有特殊 token 的用户文本的自托管技术栈中,攻击者可能利用这一点发起攻击。 +这不能替代本页中的其他加固措施——`dmPolicy`、allowlist、exec 审批、沙箱隔离和 `contextVisibility` 仍然承担主要防护作用。它关闭的是一种特定的 tokenizer 层绕过:针对会完整转发带有 special token 的用户文本的自托管技术栈。 ## 不安全外部内容绕过标志 -OpenClaw 包含显式的绕过标志,可禁用外部内容安全包装: +OpenClaw 包含显式的绕过标志,可禁用外部内容安全封装: - `hooks.mappings[].allowUnsafeExternalContent` - `hooks.gmail.allowUnsafeExternalContent` - Cron 负载字段 `allowUnsafeExternalContent` -指导建议: +指南: -- 在生产环境中保持这些设置未启用/为 false。 -- 仅在范围严格受控的调试场景中临时启用。 -- 如果启用,请隔离该智能体(沙箱隔离 + 最小工具集 + 专用 session 命名空间)。 +- 在生产环境中保持这些值未设置/为 false。 +- 仅在严格限定的调试场景中临时启用。 +- 如果启用,请隔离该智能体(沙箱隔离 + 最小化工具 + 专用 session 命名空间)。 Hooks 风险说明: -- Hook 负载是不受信任内容,即使投递来自你可控的系统也是如此(邮件/文档/网页内容都可能携带 prompt injection)。 -- 较弱模型层级会放大此风险。对于 hook 驱动的自动化,优先使用强大的现代模型层级,并保持工具策略严格(`tools.profile: "messaging"` 或更严格),并在可能时启用沙箱隔离。 +- Hook 负载属于不受信任内容,即使它们来自你控制的系统也是如此(邮件/文档/网页内容都可能携带提示注入)。 +- 较弱的模型层级会放大这一风险。对于 hook 驱动的自动化,应优先选择现代强模型层级,并保持严格的工具策略(`tools.profile: "messaging"` 或更严格),同时在可能时启用沙箱隔离。 -### Prompt injection 不需要公开私信 +### 提示注入并不要求公开私信 -即使**只有你**可以给机器人发消息,prompt injection 仍然可能通过 -机器人读取的任何**不受信任内容**发生(网页搜索/抓取结果、浏览器页面、 -电子邮件、文档、附件、粘贴的日志/代码)。换句话说:发送者并不是 -唯一的威胁面;**内容本身**也可能携带对抗性指令。 +即使**只有你自己**可以给机器人发消息,提示注入仍然可能通过 +机器人读取的任何**不受信任内容**发生(web 搜索/抓取结果、浏览器页面、 +电子邮件、文档、附件、粘贴的日志/代码)。换句话说:威胁面不只是发送者; +**内容本身**也可能携带对抗性指令。 -当工具启用时,典型风险是外泄上下文或触发 -工具调用。可通过以下方式缩小影响半径: +启用工具后,典型风险是外泄上下文或触发工具调用。可通过以下方式缩小影响半径: -- 使用只读或禁用工具的**阅读型智能体**来总结不受信任内容, +- 使用只读或禁用工具的**阅读智能体**来总结不受信任内容, 然后再把摘要传给你的主智能体。 - 除非确有需要,否则对启用了工具的智能体关闭 `web_search` / `web_fetch` / `browser`。 - 对于 OpenResponses URL 输入(`input_file` / `input_image`),请设置严格的 `gateway.http.endpoints.responses.files.urlAllowlist` 和 - `gateway.http.endpoints.responses.images.urlAllowlist`,并保持 `maxUrlParts` 较低。 - 空 allowlists 会被视为未设置;如果你想完全禁用 URL 抓取,请使用 `files.allowUrl: false` / `images.allowUrl: false`。 + `gateway.http.endpoints.responses.images.urlAllowlist`,并将 `maxUrlParts` 保持较低。 + 空 allowlist 会被视为未设置;如果你想完全禁用 URL 抓取,请使用 `files.allowUrl: false` / `images.allowUrl: false`。 - 对于 OpenResponses 文件输入,解码后的 `input_file` 文本仍会作为 - **不受信任的外部内容**注入。不要因为文本是由 Gateway 网关本地解码的, - 就认为文件文本是可信的。注入块仍然会带有明确的 + **不受信任的外部内容**注入。不要因为 Gateway 网关是在本地解码文件文本, + 就认为这些文本是可信的。注入块仍会带有显式的 `<<>>` 边界标记以及 `Source: External` - 元数据,尽管这一路径省略了更长的 `SECURITY NOTICE:` 横幅。 -- 当媒体理解功能从附加文档中提取文本并将其附加到媒体 prompt 时, - 也会应用相同的基于标记的包装。 -- 对任何接触不受信任输入的智能体启用沙箱隔离和严格工具 allowlists。 -- 不要把 secrets 放进 prompts;应通过 gateway 主机上的 env/config 传递它们。 + 元数据,尽管该路径省略了更长的 `SECURITY NOTICE:` 横幅。 +- 当媒体理解在将文本附加到媒体提示词之前从附加文档中提取文本时,也会应用相同的基于标记的封装。 +- 对任何接触不受信任输入的智能体启用沙箱隔离和严格的工具 allowlist。 +- 不要把 secret 放进提示词;应通过 gateway 主机上的环境变量/配置来传递。 ### 自托管 LLM 后端 -诸如 vLLM、SGLang、TGI、LM Studio -或自定义 Hugging Face tokenizer 技术栈之类的 OpenAI 兼容自托管后端, -在处理 chat-template 特殊 token 时,行为可能与托管 provider 不同。如果某个后端会将 -用户内容中的字面字符串(例如 `<|im_start|>`、`<|start_header_id|>` 或 ``) -当作结构性的 chat-template token 来分词, -那么不受信任文本就可能尝试在 tokenizer 层伪造角色边界。 +OpenAI 兼容的自托管后端,如 vLLM、SGLang、TGI、LM Studio, +或自定义 Hugging Face tokenizer 技术栈,在处理 +chat-template special token 的方式上,可能与托管提供商不同。如果某个后端会把 +用户内容中的字面量字符串,如 `<|im_start|>`、`<|start_header_id|>` 或 ``, +当作结构化 chat-template token 来进行分词,不受信任文本就可能尝试在 tokenizer 层伪造角色边界。 -OpenClaw 会在将包装后的 -外部内容发送给模型之前,去除常见模型家族的特殊 token 字面量。请保持外部内容 -包装启用,并在可用时优先使用能够对用户提供内容中的特殊 -token 进行拆分或转义的后端设置。OpenAI -和 Anthropic 等托管 provider 已经在请求侧应用了自己的清洗机制。 +OpenClaw 会在将封装后的外部内容分发给模型之前,从中剥离常见模型家族的 special-token 字面量。请保持外部内容封装处于启用状态,并在可用时优先使用能够拆分或转义用户提供内容中 special token 的后端设置。OpenAI +和 Anthropic 等托管提供商已经在请求侧应用了自己的清洗机制。 ### 模型强度(安全说明) -不同模型层级在 prompt injection 抵抗能力上**并不一致**。更小/更便宜的模型通常更容易受到工具滥用和指令劫持的影响,尤其是在对抗性 prompt 下。 +不同模型层级对提示注入的抵抗能力**并不一致**。更小/更便宜的模型通常更容易发生工具滥用和指令劫持,尤其是在对抗性提示词下。 -对于启用了工具的智能体,或会读取不受信任内容的智能体,较老/较小模型带来的 prompt injection 风险通常过高。不要在较弱模型层级上运行这些工作负载。 +对于启用了工具的智能体或会读取不受信任内容的智能体,较旧/较小模型的提示注入风险通常过高。不要在较弱模型层级上运行这类工作负载。 建议: -- 对于任何可以运行工具或接触文件/网络的机器人,**使用最新一代、最佳层级的模型**。 -- **不要在启用了工具的智能体或不受信任收件箱场景中使用较老/较弱/较小的模型层级**;prompt injection 风险过高。 -- 如果你必须使用较小模型,**缩小影响半径**(只读工具、强沙箱隔离、最小文件系统访问、严格 allowlists)。 -- 运行小模型时,**为所有 sessions 启用沙箱隔离**,并且**禁用 `web_search`/`web_fetch`/`browser`**,除非输入受到严格控制。 -- 对于仅聊天、输入可信且不使用工具的个人助理,较小模型通常是可以接受的。 +- 对任何可以运行工具或接触文件/网络的机器人,**使用最新一代、最高等级的模型**。 +- 对启用了工具的智能体或不受信任收件箱,**不要使用较旧/较弱/较小的层级**;提示注入风险过高。 +- 如果你必须使用较小模型,**请缩小影响半径**(只读工具、强沙箱隔离、最小文件系统访问、严格 allowlist)。 +- 运行小模型时,**为所有 session 启用沙箱隔离**,并且**禁用 `web_search`/`web_fetch`/`browser`**,除非输入受到严格控制。 +- 对于仅聊天、输入可信且没有工具的个人助理,较小模型通常是可以的。 -## 群组中的推理与详细输出 +## 群组中的推理和详细输出 -`/reasoning`、`/verbose` 和 `/trace` 可能会暴露内部推理、工具 +`/reasoning`、`/verbose` 和 `/trace` 可能暴露内部推理、工具 输出或插件诊断信息,而这些内容 -原本并不打算出现在公开渠道中。在群组环境里,应将它们视为**仅供调试** +原本并不打算出现在公共渠道中。在群组环境下,应将它们视为**仅限调试** 功能,除非你明确需要,否则请保持关闭。 -指导建议: +指南: -- 在公开房间中保持 `/reasoning`、`/verbose` 和 `/trace` 关闭。 -- 如果要启用,只应在受信任的私信或严格受控的房间中启用。 -- 请记住:verbose 和 trace 输出可能包含工具参数、URL、插件诊断信息以及模型看到的数据。 +- 在公共房间中保持 `/reasoning`、`/verbose` 和 `/trace` 关闭。 +- 如果启用,也只应在受信任私信或严格控制的房间中启用。 +- 请记住:verbose 和 trace 输出可能包含工具参数、URL、插件诊断信息,以及模型看到的数据。 ## 配置加固示例 ### 文件权限 -在 gateway 主机上保持 config + state 私有: +在 gateway 主机上保持配置和状态私有: - `~/.openclaw/openclaw.json`:`600`(仅用户可读写) - `~/.openclaw`:`700`(仅用户可访问) -`openclaw doctor` 可以发出警告,并提供收紧这些权限的建议。 +`openclaw doctor` 可以发出警告,并提供收紧这些权限的选项。 ### 网络暴露(bind、port、防火墙) -Gateway 网关在单个端口上复用 **WebSocket + HTTP**: +Gateway 网关会在单个端口上复用 **WebSocket + HTTP**: - 默认:`18789` -- Config/flags/env:`gateway.port`、`--port`、`OPENCLAW_GATEWAY_PORT` +- 配置/标志/环境变量:`gateway.port`、`--port`、`OPENCLAW_GATEWAY_PORT` -这个 HTTP 界面包含 Control UI 和 canvas host: +这个 HTTP 表面包括 Control UI 和 canvas host: - Control UI(SPA 资源)(默认基础路径 `/`) -- Canvas host:`/__openclaw__/canvas/` 和 `/__openclaw__/a2ui/`(任意 HTML/JS;应视为不受信任内容) +- Canvas host:`/__openclaw__/canvas/` 和 `/__openclaw__/a2ui/`(任意 HTML/JS;应将其视为不受信任内容) -如果你在普通浏览器中加载 canvas 内容,应像对待其他不受信任网页一样处理它: +如果你在普通浏览器中加载 canvas 内容,请像对待任何其他不受信任网页一样处理它: -- 不要把 canvas host 暴露给不受信任的网络/用户。 -- 不要让 canvas 内容与高权限网页界面共享同一 origin,除非你完全理解其影响。 +- 不要将 canvas host 暴露给不受信任的网络/用户。 +- 不要让 canvas 内容与有特权的 Web 表面共享同一 origin,除非你完全理解其中影响。 -Bind 模式控制 Gateway 网关监听的位置: +绑定模式控制 Gateway 网关监听的位置: - `gateway.bind: "loopback"`(默认):只有本地客户端可以连接。 -- 非 loopback 绑定(`"lan"`、`"tailnet"`、`"custom"`)会扩大攻击面。只有在启用 gateway auth(共享 token/password 或正确配置的非 loopback trusted proxy)并配合真实防火墙时才应使用它们。 +- 非 loopback 绑定(`"lan"`、`"tailnet"`、`"custom"`)会扩大攻击面。仅应在启用了 gateway 认证(共享 token/password 或正确配置的非 loopback trusted proxy)且具备真实防火墙的情况下使用。 -经验法则: +经验规则: -- 优先使用 Tailscale Serve,而不是 LAN bind(Serve 会让 Gateway 网关保持在 loopback 上,并由 Tailscale 负责访问控制)。 -- 如果你必须绑定到 LAN,请通过防火墙将端口限制为严格的源 IP allowlist;不要大范围做端口转发。 -- 永远不要将未启用身份验证的 Gateway 网关暴露在 `0.0.0.0` 上。 +- 优先使用 Tailscale Serve,而不是 LAN 绑定(Serve 会让 Gateway 网关保持在 loopback 上,并由 Tailscale 处理访问)。 +- 如果必须绑定到 LAN,请用防火墙将端口限制为严格的源 IP allowlist;不要广泛做端口转发。 +- 绝不要在 `0.0.0.0` 上以未认证方式暴露 Gateway 网关。 -### 配合 UFW 的 Docker 端口发布 +### 使用 UFW 的 Docker 端口发布 -如果你在 VPS 上通过 Docker 运行 OpenClaw,请记住,已发布的容器端口 -(`-p HOST:CONTAINER` 或 Compose `ports:`)会经过 Docker 的转发链路, +如果你在 VPS 上通过 Docker 运行 OpenClaw,请记住,容器发布的端口 +(`-p HOST:CONTAINER` 或 Compose `ports:`)是通过 Docker 的转发链路路由的, 而不只是主机的 `INPUT` 规则。 -为了让 Docker 流量与防火墙策略保持一致,请在 +为了让 Docker 流量与你的防火墙策略保持一致,请在 `DOCKER-USER` 中强制执行规则(这个链会在 Docker 自己的 accept 规则之前被评估)。 -在许多现代发行版上,`iptables`/`ip6tables` 使用的是 `iptables-nft` 前端, -但这些规则仍会应用到底层 nftables 后端。 +在许多现代发行版上,`iptables`/`ip6tables` 使用 `iptables-nft` 前端, +并且仍会将这些规则应用到 nftables 后端。 最小 allowlist 示例(IPv4): ```bash -# /etc/ufw/after.rules (作为独立的 *filter 段追加) +# /etc/ufw/after.rules(作为独立的 *filter 段追加) *filter :DOCKER-USER - [0:0] -A DOCKER-USER -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN @@ -739,14 +731,14 @@ Bind 模式控制 Gateway 网关监听的位置: COMMIT ``` -IPv6 有单独的表。如果启用了 Docker IPv6, -请在 `/etc/ufw/after6.rules` 中添加匹配策略。 +IPv6 有独立的表。如果启用了 Docker IPv6,请在 `/etc/ufw/after6.rules` 中 +添加匹配的策略。 -避免在文档片段中硬编码诸如 `eth0` 之类的接口名称。不同 VPS 镜像上的接口名称 -各不相同(`ens3`、`enp*` 等),不匹配可能会意外 +避免在文档示例中硬编码像 `eth0` 这样的接口名。接口名 +会因 VPS 镜像而异(`ens3`、`enp*` 等),不匹配可能会意外 跳过你的拒绝规则。 -重载后的快速验证: +重新加载后的快速验证: ```bash ufw reload @@ -755,22 +747,22 @@ ip6tables -S DOCKER-USER nmap -sT -p 1-65535 --open ``` -预期的对外开放端口应该只有你有意暴露的那些(对于大多数 -配置:SSH + 你的反向代理端口)。 +预期的对外开放端口应只包含你有意暴露的端口(对大多数 +配置来说:SSH + 你的反向代理端口)。 -### mDNS/Bonjour 设备发现 +### mDNS/Bonjour 发现 -Gateway 网关会通过 mDNS 广播自身存在(`_openclaw-gw._tcp`,端口 5353),用于本地设备发现。在 full 模式下,这还包括可能暴露运行细节的 TXT 记录: +Gateway 网关会通过 mDNS 广播自己的存在(`_openclaw-gw._tcp`,端口 5353),用于本地设备发现。在 full 模式下,这还包括可能泄露运行细节的 TXT 记录: -- `cliPath`:CLI 二进制文件的完整文件系统路径(会暴露用户名和安装位置) -- `sshPort`:表明主机提供 SSH 服务 +- `cliPath`:CLI 二进制文件的完整文件系统路径(会泄露用户名和安装位置) +- `sshPort`:会通告主机上的 SSH 可用性 - `displayName`、`lanHost`:主机名信息 -**运行安全注意事项:** 广播基础设施细节会让本地网络中的任何人更容易进行侦察。即使像文件系统路径和 SSH 可用性这样看似“无害”的信息,也有助于攻击者绘制你的环境图谱。 +**操作安全注意事项:**广播基础设施细节会让本地网络中的任何人更容易进行侦察。即使是文件系统路径、SSH 可用性这类“看似无害”的信息,也有助于攻击者绘制你的环境图谱。 **建议:** -1. **最小模式**(默认,推荐用于暴露的 Gateway 网关):从 mDNS 广播中省略敏感字段: +1. **Minimal 模式**(默认,推荐用于暴露的 Gateway 网关):从 mDNS 广播中省略敏感字段: ```json5 { @@ -780,7 +772,7 @@ Gateway 网关会通过 mDNS 广播自身存在(`_openclaw-gw._tcp`,端口 5 } ``` -2. 如果你不需要本地设备发现,**可完全禁用**: +2. **完全禁用**,如果你不需要本地设备发现: ```json5 { @@ -790,7 +782,7 @@ Gateway 网关会通过 mDNS 广播自身存在(`_openclaw-gw._tcp`,端口 5 } ``` -3. **完整模式**(显式启用):在 TXT 记录中包含 `cliPath` + `sshPort`: +3. **Full 模式**(选择启用):在 TXT 记录中包含 `cliPath` + `sshPort`: ```json5 { @@ -800,19 +792,19 @@ Gateway 网关会通过 mDNS 广播自身存在(`_openclaw-gw._tcp`,端口 5 } ``` -4. **环境变量**(替代方案):设置 `OPENCLAW_DISABLE_BONJOUR=1`,无需修改配置即可禁用 mDNS。 +4. **环境变量**(替代方式):设置 `OPENCLAW_DISABLE_BONJOUR=1`,无需修改配置即可禁用 mDNS。 -在最小模式下,Gateway 网关仍会广播足够用于设备发现的信息(`role`、`gatewayPort`、`transport`),但会省略 `cliPath` 和 `sshPort`。需要 CLI 路径信息的应用可以改为通过经过身份验证的 WebSocket 连接来获取。 +在 minimal 模式下,Gateway 网关仍会广播足够用于设备发现的信息(`role`、`gatewayPort`、`transport`),但会省略 `cliPath` 和 `sshPort`。需要 CLI 路径信息的应用,可以改为通过经过认证的 WebSocket 连接获取。 -### 锁定 Gateway 网关 WebSocket(本地身份验证) +### 锁定 Gateway 网关 WebSocket(本地认证) -默认情况下**必须启用** gateway auth。如果没有配置有效的 gateway auth 路径, -Gateway 网关将拒绝 WebSocket 连接(失败关闭)。 +默认情况下**必须启用** gateway 认证。如果没有配置有效的 gateway 认证路径, +Gateway 网关会拒绝 WebSocket 连接(失败即关闭)。 新手引导默认会生成一个 token(即使是在 loopback 上),因此 -本地客户端也必须进行身份验证。 +本地客户端也必须进行认证。 -设置一个 token,使**所有** WS 客户端都必须进行身份验证: +设置一个 token,这样**所有** WS 客户端都必须认证: ```json5 { @@ -825,149 +817,151 @@ Gateway 网关将拒绝 WebSocket 连接(失败关闭)。 Doctor 可以帮你生成一个:`openclaw doctor --generate-gateway-token`。 注意:`gateway.remote.token` / `.password` 是客户端凭证来源。 -它们**不会**单独保护本地 WS 访问。 -只有当 `gateway.auth.*` 未设置时,本地调用路径才会将 `gateway.remote.*` 用作回退。 -如果通过 SecretRef 显式配置了 `gateway.auth.token` / `gateway.auth.password`, -但未能解析,则会失败关闭(不会用远程回退来掩盖该问题)。 +它们本身**不会**保护本地 WS 访问。 +只有在 `gateway.auth.*` 未设置时,本地调用路径才可以将 `gateway.remote.*` +用作回退。 +如果通过 SecretRef 显式配置了 `gateway.auth.token` / `gateway.auth.password` +但无法解析,则会失败即关闭(不会用 remote 回退来掩盖)。 可选:当使用 `wss://` 时,可通过 `gateway.remote.tlsFingerprint` 固定远程 TLS。 -默认情况下,明文 `ws://` 仅限 loopback。对于受信任的私有网络 -路径,可在客户端进程上设置 `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1` -作为紧急兜底。这有意仅支持进程环境变量,而不是 +默认情况下,明文 `ws://` 仅限 loopback 使用。对于受信任的私有网络 +路径,可在客户端进程上设置 `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1` 作为 +紧急兜底。这有意只支持进程环境变量,而不是 `openclaw.json` 配置键。 -移动端配对以及 Android 手动或扫描的 Gateway 网关路由要求更严格: -明文连接可用于 loopback,但 private-LAN、链路本地、`.local` 和 +移动端配对以及 Android 手动或扫码 Gateway 网关路径更加严格: +loopback 接受明文,但私有 LAN、链路本地、`.local` 以及 无点主机名必须使用 TLS,除非你显式选择启用受信任私有网络明文路径。 本地设备配对: -- 为了让同主机客户端体验顺畅,针对直接本地 loopback 连接的设备配对会自动批准。 -- OpenClaw 还为受信任的共享密钥辅助流程提供了一条狭窄的后端/容器本地自连接路径。 -- Tailnet 和 LAN 连接(包括同主机 tailnet 绑定)在配对上都会被视为远程连接,仍然需要批准。 -- loopback 请求上的转发 header 证据会取消其 loopback - 本地性资格。metadata 升级自动批准仅限于非常狭窄的范围。详情见 - [Gateway pairing](/zh-CN/gateway/pairing)。 +- 为了让同主机客户端保持顺畅,针对直接本地 loopback 连接的设备配对会自动批准。 +- OpenClaw 还提供了一条狭窄的后端/容器本地自连接路径,用于 + 受信任共享 secret 的辅助流程。 +- Tailnet 和 LAN 连接(包括同主机 tailnet 绑定)在配对上都被视为远程, + 仍然需要批准。 +- loopback 请求中的转发头证据会取消其 loopback + 本地性资格。元数据升级自动批准只在极窄范围内适用。详见 + [Gateway 配对](/zh-CN/gateway/pairing) 中的两类规则。 -Auth 模式: +认证模式: - `gateway.auth.mode: "token"`:共享 bearer token(推荐用于大多数配置)。 -- `gateway.auth.mode: "password"`:密码身份验证(建议通过 env 设置:`OPENCLAW_GATEWAY_PASSWORD`)。 -- `gateway.auth.mode: "trusted-proxy"`:信任具备身份感知能力的反向代理来对用户进行身份验证,并通过 headers 传递身份(见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth))。 +- `gateway.auth.mode: "password"`:密码认证(建议通过环境变量设置:`OPENCLAW_GATEWAY_PASSWORD`)。 +- `gateway.auth.mode: "trusted-proxy"`:信任具备身份感知能力的反向代理,由它对用户进行认证并通过头部传递身份(参见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth))。 -轮换清单(token/password): +轮换检查清单(token/password): 1. 生成/设置新的 secret(`gateway.auth.token` 或 `OPENCLAW_GATEWAY_PASSWORD`)。 -2. 重启 Gateway 网关(或者如果由 macOS 应用监管 Gateway 网关,则重启该应用)。 -3. 更新所有远程客户端(在调用 Gateway 网关的机器上更新 `gateway.remote.token` / `.password`)。 +2. 重启 Gateway 网关(如果是 macOS app 负责监管 Gateway 网关,则重启该 app)。 +3. 更新所有远程客户端(调用 Gateway 网关的机器上配置的 `gateway.remote.token` / `.password`)。 4. 验证旧凭证已无法再连接。 -### Tailscale Serve 身份 headers +### Tailscale Serve 身份头 当 `gateway.auth.allowTailscale` 为 `true`(Serve 的默认值)时,OpenClaw -接受 Tailscale Serve 身份 headers(`tailscale-user-login`),用于 Control -UI/WebSocket 身份验证。OpenClaw 会通过本地 Tailscale 守护进程 -(`tailscale whois`)解析 `x-forwarded-for` 地址,并将其与该 header 匹配,从而验证身份。此逻辑仅会在请求命中 loopback -且包含由 Tailscale 注入的 `x-forwarded-for`、`x-forwarded-proto` 和 `x-forwarded-host` +会接受 Tailscale Serve 身份头(`tailscale-user-login`)用于 Control +UI/WebSocket 认证。OpenClaw 会通过本地 Tailscale 守护进程 +(`tailscale whois`)解析 `x-forwarded-for` 地址并与该头进行匹配,从而验证身份。该逻辑仅在请求命中 loopback +且包含 Tailscale 注入的 `x-forwarded-for`、`x-forwarded-proto` 和 `x-forwarded-host` 时触发。 -对于这条异步身份检查路径,同一 `{scope, ip}` -的失败尝试会在限流器记录失败之前被串行化处理。 -因此,同一个 Serve 客户端并发发起的错误重试,第二次尝试可能会被立即锁定, -而不会像两个普通不匹配请求那样相互竞争通过。 +对于这一路径中的异步身份检查,同一 `{scope, ip}` +的失败尝试会在限流器记录失败之前被串行化处理。因此,来自同一 Serve 客户端的并发错误重试 +可能会让第二次尝试立即被锁定,而不是像两个普通不匹配那样并发竞争通过。 HTTP API 端点(例如 `/v1/*`、`/tools/invoke` 和 `/api/channels/*`) -**不会**使用 Tailscale 身份 header 身份验证。它们仍然遵循 Gateway 网关 -已配置的 HTTP auth 模式。 +**不会**使用 Tailscale 身份头认证。它们仍然遵循 gateway +配置的 HTTP 认证模式。 重要边界说明: -- Gateway 网关 HTTP bearer auth 实际上等同于全有或全无的操作员访问。 -- 能调用 `/v1/chat/completions`、`/v1/responses` 或 `/api/channels/*` 的凭证,应视为该 Gateway 网关的全权限操作员 secret。 -- 在 OpenAI 兼容 HTTP 界面上,共享密钥 bearer auth 会恢复完整的默认操作员 scopes(`operator.admin`、`operator.approvals`、`operator.pairing`、`operator.read`、`operator.talk.secrets`、`operator.write`)以及智能体轮次的 owner 语义;更窄的 `x-openclaw-scopes` 值不会缩减这条共享密钥路径。 -- HTTP 上的按请求 scope 语义,仅在请求来自带身份模式时适用,例如 trusted proxy auth 或私有入口上的 `gateway.auth.mode="none"`。 -- 在这些带身份模式下,如果省略 `x-openclaw-scopes`,会回退到正常的默认操作员 scope 集合;如果你希望更窄的 scope 集合,请显式发送该 header。 -- `/tools/invoke` 遵循相同的共享密钥规则:在该接口上,token/password bearer auth 也会被视为完全操作员访问,而带身份模式仍会遵守声明的 scopes。 -- 不要将这些凭证分享给不受信任的调用方;应按信任边界使用单独的 Gateway 网关。 +- Gateway 网关 HTTP bearer 认证实际上等同于全有或全无的操作员访问。 +- 应将能够调用 `/v1/chat/completions`、`/v1/responses` 或 `/api/channels/*` 的凭证视为该 gateway 的全访问操作员 secret。 +- 在兼容 OpenAI 的 HTTP 表面上,共享 secret bearer 认证会恢复完整的默认操作员 scope(`operator.admin`、`operator.approvals`、`operator.pairing`、`operator.read`、`operator.talk.secrets`、`operator.write`)以及面向智能体轮次的 owner 语义;更窄的 `x-openclaw-scopes` 值不会缩减这条共享 secret 路径。 +- 只有当 HTTP 请求来自带有身份的模式(如 trusted proxy auth 或私有入口上的 `gateway.auth.mode="none"`)时,请求级 scope 语义才会生效。 +- 在这些带有身份的模式下,如果省略 `x-openclaw-scopes`,会回退到普通的默认操作员 scope 集合;如果你想要更窄的 scope 集合,请显式发送该头。 +- `/tools/invoke` 遵循相同的共享 secret 规则:在这里 token/password bearer auth 同样被视为完整操作员访问,而带身份的模式仍会遵循声明的 scope。 +- 不要与不受信任调用方共享这些凭证;应按信任边界使用独立的 Gateway 网关。 -**信任假设:** 无 token 的 Serve auth 假设 Gateway 网关主机是受信任的。 -不要把它当作针对同主机恶意进程的保护机制。如果 Gateway 网关主机上 -可能运行不受信任的本地代码,请禁用 `gateway.auth.allowTailscale`, -并要求使用显式共享密钥身份验证,即 `gateway.auth.mode: "token"` 或 -`"password"`。 +**信任假设:**无 token 的 Serve 认证假设 gateway 主机是受信任的。 +不要把它视为防御敌对同主机进程的保护机制。如果不受信任的 +本地代码可能在 gateway 主机上运行,请关闭 `gateway.auth.allowTailscale`, +并要求使用 `gateway.auth.mode: "token"` 或 +`"password"` 进行显式共享 secret 认证。 -**安全规则:** 不要从你自己的反向代理转发这些 headers。如果 -你在 Gateway 网关前终止 TLS 或进行代理,请禁用 -`gateway.auth.allowTailscale`,改用共享密钥身份验证(`gateway.auth.mode: +**安全规则:**不要从你自己的反向代理转发这些头。如果 +你在 gateway 前终止 TLS 或做代理,请关闭 +`gateway.auth.allowTailscale`,并改用共享 secret 认证(`gateway.auth.mode: "token"` 或 `"password"`)或 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth)。 -Trusted proxies: +受信任代理: -- 如果你在 Gateway 网关前终止 TLS,请将 `gateway.trustedProxies` 设置为代理 IP。 -- OpenClaw 会信任来自这些 IP 的 `x-forwarded-for`(或 `x-real-ip`),以确定客户端 IP,用于本地配对检查以及 HTTP auth/本地检查。 +- 如果你在 Gateway 网关前终止 TLS,请将代理 IP 设置到 `gateway.trustedProxies`。 +- OpenClaw 会信任这些 IP 发来的 `x-forwarded-for`(或 `x-real-ip`),以便在本地配对检查和 HTTP 认证/本地检查中确定客户端 IP。 - 确保你的代理会**覆盖** `x-forwarded-for`,并阻止对 Gateway 网关端口的直接访问。 -参见 [Tailscale](/zh-CN/gateway/tailscale) 和 [Web overview](/zh-CN/web)。 +参见 [Tailscale](/zh-CN/gateway/tailscale) 和 [Web 概览](/zh-CN/web)。 ### 通过 node host 进行浏览器控制(推荐) -如果你的 Gateway 网关位于远端,但浏览器运行在另一台机器上,请在浏览器所在机器上运行一个 **node host**, -并让 Gateway 网关代理浏览器操作(见 [Browser tool](/zh-CN/tools/browser))。 -应将 node 节点配对视为管理员访问。 +如果你的 Gateway 网关是远程的,但浏览器运行在另一台机器上,请在浏览器机器上运行一个 **node host**, +并让 Gateway 网关代理浏览器操作(参见[Browser 工具](/zh-CN/tools/browser))。 +应将节点配对视为管理员访问。 推荐模式: - 让 Gateway 网关和 node host 位于同一个 tailnet(Tailscale)中。 -- 有意识地配对该 node 节点;如果不需要浏览器代理路由,则禁用它。 +- 有意地为节点配对;如果你不需要浏览器代理路由,请将其关闭。 避免: -- 通过 LAN 或公共互联网暴露中继/控制端口。 +- 通过 LAN 或公共互联网暴露 relay/control 端口。 - 对浏览器控制端点使用 Tailscale Funnel(公开暴露)。 -### 磁盘上的 secrets +### 磁盘上的 secret -应假设 `~/.openclaw/`(或 `$OPENCLAW_STATE_DIR/`)下的任何内容都可能包含 secrets 或私有数据: +假定 `~/.openclaw/`(或 `$OPENCLAW_STATE_DIR/`)下的任何内容都可能包含 secret 或私有数据: -- `openclaw.json`:配置中可能包含 tokens(gateway、remote gateway)、provider 设置和 allowlists。 -- `credentials/**`:渠道凭证(例如 WhatsApp 凭证)、pairing allowlists、旧版 OAuth 导入。 -- `agents//agent/auth-profiles.json`:API keys、token profiles、OAuth tokens,以及可选的 `keyRef`/`tokenRef`。 -- `secrets.json`(可选):由 `file` SecretRef providers(`secrets.providers`)使用的基于文件的 secret 负载。 -- `agents//agent/auth.json`:旧版兼容文件。发现静态 `api_key` 条目时会清除。 -- `agents//sessions/**`:session 转录(`*.jsonl`)+ 路由元数据(`sessions.json`),可能包含私信和工具输出。 -- 内置插件包:已安装插件(以及它们的 `node_modules/`)。 -- `sandboxes/**`:工具沙箱工作区;可能累积你在沙箱中读写文件的副本。 +- `openclaw.json`:配置中可能包含 token(gateway、remote gateway)、提供商设置和 allowlist。 +- `credentials/**`:渠道凭证(例如 WhatsApp 凭证)、配对 allowlist、旧版 OAuth 导入。 +- `agents//agent/auth-profiles.json`:API key、token profile、OAuth token,以及可选的 `keyRef`/`tokenRef`。 +- `secrets.json`(可选):供 `file` SecretRef 提供商(`secrets.providers`)使用的基于文件的 secret 负载。 +- `agents//agent/auth.json`:旧版兼容文件。发现时会清除其中静态 `api_key` 条目。 +- `agents//sessions/**`:会话记录(`*.jsonl`)+ 路由元数据(`sessions.json`),可能包含私信和工具输出。 +- 内置插件包:已安装的插件(以及它们的 `node_modules/`)。 +- `sandboxes/**`:工具沙箱工作区;可能累积你在沙箱中读写的文件副本。 加固建议: - 保持严格权限(目录 `700`,文件 `600`)。 -- 在 Gateway 网关主机上使用全盘加密。 -- 如果主机是共享的,优先为 Gateway 网关使用专用操作系统用户账号。 +- 在 gateway 主机上使用全盘加密。 +- 如果主机是共享的,优先为 Gateway 网关使用专用 OS 用户账号。 ### 工作区 `.env` 文件 -OpenClaw 会为智能体和工具加载工作区本地 `.env` 文件,但绝不会允许这些文件悄悄覆盖 gateway 运行时控制。 +OpenClaw 会为智能体和工具加载工作区本地 `.env` 文件,但绝不会让这些文件悄悄覆盖 gateway 运行时控制。 -- 任何以 `OPENCLAW_*` 开头的键都会被来自不受信任工作区 `.env` 文件的值拦截。 -- Matrix、Mattermost、IRC 和 Synology Chat 的渠道端点设置也会被阻止通过工作区 `.env` 覆盖,因此克隆的工作区无法通过本地端点配置重定向内置连接器流量。端点环境变量键(如 `MATRIX_HOMESERVER`、`MATTERMOST_URL`、`IRC_HOST`、`SYNOLOGY_CHAT_INCOMING_URL`)必须来自 gateway 进程环境或 `env.shellEnv`,不能来自工作区加载的 `.env`。 -- 该拦截是失败关闭的:将来版本中新增的运行时控制变量,不能从已提交或攻击者提供的 `.env` 中继承;该键会被忽略,而 gateway 会保留自己的值。 -- 受信任的进程/操作系统环境变量(gateway 自身的 shell、launchd/systemd 单元、应用包)仍然有效——这项限制只约束 `.env` 文件加载。 +- 任何以 `OPENCLAW_*` 开头的键都会被来自不受信任工作区 `.env` 文件的值阻止。 +- Matrix、Mattermost、IRC 和 Synology Chat 的渠道端点设置也会被阻止通过工作区 `.env` 覆盖,因此克隆出的工作区无法通过本地端点配置重定向内置连接器流量。端点环境变量键(如 `MATRIX_HOMESERVER`、`MATTERMOST_URL`、`IRC_HOST`、`SYNOLOGY_CHAT_INCOMING_URL`)必须来自 gateway 进程环境或 `env.shellEnv`,而不能来自工作区加载的 `.env`。 +- 这种阻止机制是失败即关闭的:未来版本中新增加的运行时控制变量,无法从已提交或攻击者提供的 `.env` 中继承;该键会被忽略,gateway 会保留自己的值。 +- 受信任的进程/OS 环境变量(gateway 自身的 shell、launchd/systemd unit、app bundle)仍然有效——这里限制的只是 `.env` 文件加载。 -原因:工作区 `.env` 文件经常与智能体代码放在一起,容易被误提交,或者被工具写入。拦截整个 `OPENCLAW_*` 前缀意味着以后即使新增 `OPENCLAW_*` 标志,也绝不会退化为从工作区状态中静默继承。 +原因:工作区 `.env` 文件常常与智能体代码放在一起,容易被误提交,或者被工具写入。阻止整个 `OPENCLAW_*` 前缀,意味着未来新增任何 `OPENCLAW_*` 标志时,都不可能退化为从工作区状态中静默继承。 -### 日志和转录记录(脱敏与保留) +### 日志和记录(脱敏与保留) -即使访问控制正确,日志和转录记录仍然可能泄露敏感信息: +即使访问控制配置正确,日志和记录仍可能泄露敏感信息: - Gateway 网关日志可能包含工具摘要、错误和 URL。 -- Session 转录可能包含粘贴的 secrets、文件内容、命令输出和链接。 +- 会话记录可能包含粘贴的 secret、文件内容、命令输出和链接。 建议: -- 保持工具摘要脱敏开启(`logging.redactSensitive: "tools"`;默认值)。 -- 通过 `logging.redactPatterns` 为你的环境添加自定义模式(tokens、主机名、内部 URL)。 -- 分享诊断信息时,优先使用 `openclaw status --all`(可直接粘贴,secrets 已脱敏),而不是原始日志。 -- 如果不需要长期保留,请清理旧的 session 转录和日志文件。 +- 保持日志和记录脱敏开启(`logging.redactSensitive: "tools"`;默认值)。 +- 通过 `logging.redactPatterns` 为你的环境添加自定义模式(token、主机名、内部 URL)。 +- 分享诊断信息时,优先使用 `openclaw status --all`(可直接粘贴,secret 已脱敏),而不是原始日志。 +- 如果你不需要长期保留,请清理旧的会话记录和日志文件。 -详情见:[Logging](/zh-CN/gateway/logging) +详情见:[日志](/zh-CN/gateway/logging) -### 私信:默认启用 pairing +### 私信:默认使用配对 ```json5 { @@ -975,7 +969,7 @@ OpenClaw 会为智能体和工具加载工作区本地 `.env` 文件,但绝不 } ``` -### 群组:始终要求 mention +### 群组:始终要求提及 ```json { @@ -997,31 +991,31 @@ OpenClaw 会为智能体和工具加载工作区本地 `.env` 文件,但绝不 } ``` -在群聊中,仅在被明确提及时响应。 +在群聊中,仅当被明确提及时才响应。 ### 分离号码(WhatsApp、Signal、Telegram) -对于基于电话号码的渠道,建议考虑让你的 AI 使用与个人号码分开的号码: +对于基于电话号码的渠道,可以考虑让你的 AI 使用与个人号码分离的号码运行: - 个人号码:你的对话保持私密 -- 机器人号码:由 AI 处理,并设置适当边界 +- 机器人号码:AI 处理这些对话,并应用适当的边界 -### 只读模式(通过沙箱和工具) +### 只读模式(通过沙箱隔离和工具) -你可以通过以下组合构建只读配置: +你可以通过组合以下方式构建只读 profile: -- `agents.defaults.sandbox.workspaceAccess: "ro"`(或使用 `"none"` 以完全不允许工作区访问) +- `agents.defaults.sandbox.workspaceAccess: "ro"`(或使用 `"none"` 完全禁止工作区访问) - 使用工具 allow/deny 列表来阻止 `write`、`edit`、`apply_patch`、`exec`、`process` 等。 其他加固选项: -- `tools.exec.applyPatch.workspaceOnly: true`(默认):确保即使沙箱隔离关闭,`apply_patch` 也无法在工作区目录之外写入/删除。只有在你明确希望 `apply_patch` 触及工作区外文件时,才将其设为 `false`。 -- `tools.fs.workspaceOnly: true`(可选):将 `read`/`write`/`edit`/`apply_patch` 路径以及原生 prompt 图像自动加载路径限制在工作区目录内(如果你当前允许绝对路径,并希望有一条统一防护栏,这会很有用)。 -- 保持文件系统根目录范围狭窄:避免把你的主目录这类宽泛根目录用作智能体工作区/沙箱工作区。过宽的根目录可能让文件系统工具接触到敏感本地文件(例如 `~/.openclaw` 下的 state/config)。 +- `tools.exec.applyPatch.workspaceOnly: true`(默认):确保即使在未启用沙箱隔离时,`apply_patch` 也不能在工作区目录之外写入/删除文件。只有当你明确希望 `apply_patch` 触及工作区之外的文件时,才将其设为 `false`。 +- `tools.fs.workspaceOnly: true`(可选):将 `read`/`write`/`edit`/`apply_patch` 路径以及原生提示词图片自动加载路径限制在工作区目录内(如果你目前允许绝对路径,并希望用单一防护栏统一收紧,这会很有用)。 +- 保持文件系统根目录范围狭窄:避免把像你的主目录这样的大范围根目录用作智能体工作区/沙箱工作区。范围过大的根目录可能会让文件系统工具接触到敏感本地文件(例如 `~/.openclaw` 下的状态/配置)。 -### 安全基线(可直接复制/粘贴) +### 安全基线(可直接复制粘贴) -一个“安全默认”配置:保持 Gateway 网关私有、要求私信 pairing,并避免在群组中部署始终在线的机器人: +一个“安全默认”配置,能让 Gateway 网关保持私有、要求私信配对,并避免群组中始终在线的机器人: ```json5 { @@ -1040,69 +1034,69 @@ OpenClaw 会为智能体和工具加载工作区本地 `.env` 文件,但绝不 } ``` -如果你还希望工具执行也“默认更安全”,可为任何非 owner 智能体添加沙箱 + 拒绝危险工具(示例见下方“按智能体划分的访问配置”)。 +如果你还希望工具执行也“默认更安全”,可为任何非 owner 智能体添加沙箱 + 拒绝危险工具(见下方“按智能体划分的访问 profile”示例)。 -对于聊天驱动的智能体轮次,内置基线是:非 owner 发送者不能使用 `cron` 或 `gateway` 工具。 +对于由聊天驱动的智能体轮次,内置基线是:非 owner 发送者不能使用 `cron` 或 `gateway` 工具。 ## 沙箱隔离(推荐) 专门文档:[沙箱隔离](/zh-CN/gateway/sandboxing) -两种可互补的方法: +两种互补方法: -- **将完整 Gateway 网关运行在 Docker 中**(容器边界):[Docker](/zh-CN/install/docker) -- **工具沙箱**(`agents.defaults.sandbox`,gateway 主机运行 + 工具在沙箱中隔离;Docker 是默认后端):[沙箱隔离](/zh-CN/gateway/sandboxing) +- **在 Docker 中运行整个 Gateway 网关**(容器边界):[Docker](/zh-CN/install/docker) +- **工具沙箱**(`agents.defaults.sandbox`,gateway 主机 + 沙箱隔离工具;Docker 是默认后端):[沙箱隔离](/zh-CN/gateway/sandboxing) -注意:为了防止跨智能体访问,请将 `agents.defaults.sandbox.scope` 保持为 `"agent"`(默认) -或使用 `"session"` 以实现更严格的按 session 隔离。`scope: "shared"` 会使用 +注意:为防止跨智能体访问,请将 `agents.defaults.sandbox.scope` 保持为 `"agent"`(默认) +或使用更严格的 `"session"` 实现按 session 隔离。`scope: "shared"` 会使用 单一容器/工作区。 -还要考虑智能体在沙箱中的工作区访问: +同时也请考虑智能体在沙箱中的工作区访问权限: -- `agents.defaults.sandbox.workspaceAccess: "none"`(默认)会阻止访问智能体工作区;工具会在 `~/.openclaw/sandboxes` 下的沙箱工作区中运行 -- `agents.defaults.sandbox.workspaceAccess: "ro"` 会将智能体工作区以只读方式挂载到 `/agent`(会禁用 `write`/`edit`/`apply_patch`) -- `agents.defaults.sandbox.workspaceAccess: "rw"` 会将智能体工作区以读写方式挂载到 `/workspace` -- 额外的 `sandbox.docker.binds` 会根据标准化和规范化后的源路径进行校验。如果它们解析到被阻止的根目录(例如 `/etc`、`/var/run` 或操作系统主目录下的凭证目录),父级符号链接技巧和规范主目录别名仍会失败关闭。 +- `agents.defaults.sandbox.workspaceAccess: "none"`(默认)会禁止访问智能体工作区;工具会在 `~/.openclaw/sandboxes` 下的沙箱工作区中运行 +- `agents.defaults.sandbox.workspaceAccess: "ro"` 会把智能体工作区以只读方式挂载到 `/agent`(会禁用 `write`/`edit`/`apply_patch`) +- `agents.defaults.sandbox.workspaceAccess: "rw"` 会把智能体工作区以读写方式挂载到 `/workspace` +- 额外的 `sandbox.docker.binds` 会根据规范化和 canonicalized 后的源路径进行校验。如果父级符号链接技巧或 canonical home 别名最终解析到诸如 `/etc`、`/var/run` 或 OS 主目录下凭证目录等被阻止的根路径,仍会失败即关闭。 -重要:`tools.elevated` 是全局基础逃逸口,用于在沙箱外运行 exec。默认情况下,其实际 host 为 `gateway`;如果 exec 目标被配置为 `node`,则实际 host 为 `node`。请保持 `tools.elevated.allowFrom` 范围严格,不要对陌生人启用它。你还可以通过 `agents.list[].tools.elevated` 对单个智能体进一步限制 elevated。详见 [Elevated Mode](/zh-CN/tools/elevated)。 +重要说明:`tools.elevated` 是全局基线逃逸口,会让 exec 在沙箱之外运行。其有效主机默认是 `gateway`,当 exec 目标配置为 `node` 时则为 `node`。请保持 `tools.elevated.allowFrom` 范围严格,不要为陌生人启用。你还可以通过 `agents.list[].tools.elevated` 进一步按智能体限制高权限模式。参见[Elevated Mode](/zh-CN/tools/elevated)。 ### 子智能体委派防护栏 -如果你允许 session 工具,应将委派给子智能体的运行视为另一项边界决策: +如果你允许使用 session 工具,请将委派给子智能体的运行视为另一项边界决策: - 除非智能体确实需要委派,否则拒绝 `sessions_spawn`。 -- 将 `agents.defaults.subagents.allowAgents` 以及任何按智能体覆盖的 `agents.list[].subagents.allowAgents` 限制为已知安全的目标智能体。 -- 对于任何必须保持沙箱隔离的工作流,请以 `sandbox: "require"` 调用 `sessions_spawn`(默认是 `inherit`)。 -- `sandbox: "require"` 会在目标子运行时未启用沙箱隔离时快速失败。 +- 保持 `agents.defaults.subagents.allowAgents` 以及任何按智能体覆盖的 `agents.list[].subagents.allowAgents`,仅限已知安全的目标智能体。 +- 对于任何必须保持沙箱隔离的工作流,请在调用 `sessions_spawn` 时使用 `sandbox: "require"`(默认值为 `inherit`)。 +- `sandbox: "require"` 会在目标子运行时未启用沙箱时快速失败。 ## 浏览器控制风险 -启用浏览器控制意味着模型拥有驱动真实浏览器的能力。 -如果该浏览器配置文件中已经登录了会话,模型就可以 -访问这些账号和数据。应将浏览器配置文件视为**敏感状态**: +启用浏览器控制意味着模型可以驱动真实浏览器。 +如果该浏览器 profile 中已包含登录会话,模型就可以 +访问这些账号和数据。请将浏览器 profile 视为**敏感状态**: -- 优先为智能体使用专用配置文件(默认的 `openclaw` 配置文件)。 -- 避免让智能体使用你的个人日常主浏览器配置文件。 -- 对于启用了沙箱隔离的智能体,除非你信任它们,否则应保持主机浏览器控制关闭。 -- 独立的 loopback 浏览器控制 API 只接受共享密钥身份验证 +- 优先为智能体使用专用 profile(默认的 `openclaw` profile)。 +- 避免让智能体使用你的个人日常主力 profile。 +- 除非你信任这些智能体,否则不要为沙箱隔离智能体启用主机浏览器控制。 +- 独立的 loopback 浏览器控制 API 只接受共享 secret 认证 (gateway token bearer auth 或 gateway password)。它不会使用 - trusted-proxy 或 Tailscale Serve 身份 headers。 -- 应将浏览器下载内容视为不受信任输入;优先使用隔离的下载目录。 -- 如果可能,请在智能体配置文件中禁用浏览器同步/密码管理器(可缩小影响半径)。 -- 对于远程 Gateway 网关,应假设“浏览器控制”等同于对该配置文件可访问内容的“操作员访问”。 -- 保持 Gateway 网关和 node hosts 仅在 tailnet 中可访问;避免将浏览器控制端口暴露到 LAN 或公共互联网。 -- 当你不需要浏览器代理路由时,请禁用它(`gateway.nodes.browser.mode="off"`)。 -- Chrome MCP 现有会话模式**并不**“更安全”;它可以像你一样操作该主机上 Chrome 配置文件所能访问的一切。 + trusted-proxy 或 Tailscale Serve 身份头。 +- 将浏览器下载内容视为不受信任输入;优先使用隔离的下载目录。 +- 如果可能,请在智能体 profile 中禁用浏览器同步/密码管理器(可缩小影响半径)。 +- 对于远程 Gateway 网关,应假设“浏览器控制”等同于“操作员访问”该 profile 可到达的任何内容。 +- 保持 Gateway 网关和 node host 仅在 tailnet 中可访问;避免将浏览器控制端口暴露到 LAN 或公共互联网。 +- 当你不需要浏览器代理路由时,请关闭它(`gateway.nodes.browser.mode="off"`)。 +- Chrome MCP 现有会话模式**并不**“更安全”;它可以以你的身份访问该主机上 Chrome profile 可触及的一切。 ### 浏览器 SSRF 策略(默认严格) -默认情况下,OpenClaw 的浏览器导航策略是严格的:私有/内部目标会保持被阻止,除非你显式选择启用。 +OpenClaw 的浏览器导航策略默认是严格的:私有/内部目标会保持阻止状态,除非你显式选择启用。 -- 默认:`browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` 未设置,因此浏览器导航会继续阻止私有/内部/特殊用途目标。 -- 旧版别名:为了兼容性,仍接受 `browser.ssrfPolicy.allowPrivateNetwork`。 -- 显式启用模式:设置 `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork: true`,以允许私有/内部/特殊用途目标。 -- 在严格模式下,可使用 `hostnameAllowlist`(如 `*.example.com` 这样的模式)和 `allowedHostnames`(精确主机例外,包括像 `localhost` 这样的被阻止名称)来添加显式例外。 -- 为降低基于重定向的跳转风险,系统会在请求前进行检查,并在导航完成后的最终 `http(s)` URL 上尽力再次检查。 +- 默认值:`browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` 未设置,因此浏览器导航会继续阻止私有/内部/特殊用途目标。 +- 旧版别名:出于兼容性,仍接受 `browser.ssrfPolicy.allowPrivateNetwork`。 +- 选择启用模式:设置 `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork: true`,以允许私有/内部/特殊用途目标。 +- 在严格模式下,使用 `hostnameAllowlist`(如 `*.example.com` 这样的模式)和 `allowedHostnames`(精确主机例外,包括 `localhost` 这类默认被阻止的名称)来定义显式例外。 +- 为减少基于重定向的跳转攻击,系统会在请求前检查导航目标,并在导航后的最终 `http(s)` URL 上尽力再次检查。 严格策略示例: @@ -1118,11 +1112,11 @@ OpenClaw 会为智能体和工具加载工作区本地 `.env` 文件,但绝不 } ``` -## 按智能体划分的访问配置(多智能体) +## 按智能体划分的访问 profile(多智能体) -在多智能体路由下,每个智能体都可以有自己的沙箱 + 工具策略: -利用这一点,你可以为每个智能体赋予**完全访问**、**只读**或**无访问权限**。 -完整细节和优先级规则见 [Multi-Agent Sandbox & Tools](/zh-CN/tools/multi-agent-sandbox-tools)。 +使用多智能体路由时,每个智能体都可以拥有自己的沙箱 + 工具策略: +利用这一点可以为不同智能体分别赋予**完全访问**、**只读**或**无访问权限**。 +完整细节和优先级规则见 [多智能体沙箱隔离与工具](/zh-CN/tools/multi-agent-sandbox-tools)。 常见用例: @@ -1170,7 +1164,7 @@ OpenClaw 会为智能体和工具加载工作区本地 `.env` 文件,但绝不 } ``` -### 示例:无文件系统/shell 访问(允许 provider 消息) +### 示例:无文件系统/shell 访问(允许 provider 消息工具) ```json5 { @@ -1184,8 +1178,8 @@ OpenClaw 会为智能体和工具加载工作区本地 `.env` 文件,但绝不 scope: "agent", workspaceAccess: "none", }, - // Session 工具可能泄露转录中的敏感数据。默认情况下 OpenClaw 会将这些工具 - // 限制在当前 session + 其派生的子智能体 sessions 中,但如有需要你还可以进一步收紧。 + // Session 工具可能会从记录中泄露敏感数据。默认情况下 OpenClaw 会将这些工具 + // 限制为当前 session + 派生子智能体 session,但如有需要,你还可以进一步收紧。 // 参见配置参考中的 `tools.sessions.visibility`。 tools: { sessions: { visibility: "tree" }, // self | tree | agent | all @@ -1223,70 +1217,71 @@ OpenClaw 会为智能体和工具加载工作区本地 `.env` 文件,但绝不 ## 事件响应 -如果你的 AI 做了不好的事情: +如果你的 AI 做了坏事: -### 遏制 +### 控制事态 -1. **停止它:** 停止 macOS 应用(如果它在监管 Gateway 网关),或终止你的 `openclaw gateway` 进程。 -2. **关闭暴露面:** 将 `gateway.bind` 设为 `"loopback"`(或禁用 Tailscale Funnel/Serve),直到你弄清楚发生了什么。 -3. **冻结访问:** 将高风险私信/群组切换为 `dmPolicy: "disabled"` / 要求 mention,并移除你之前可能设置过的 `"*"` 全部允许项。 +1. **停止它:**停止 macOS app(如果它负责监管 Gateway 网关),或终止你的 `openclaw gateway` 进程。 +2. **关闭暴露面:**将 `gateway.bind` 设为 `"loopback"`(或禁用 Tailscale Funnel/Serve),直到你弄清楚发生了什么。 +3. **冻结访问:**将高风险私信/群组切换为 `dmPolicy: "disabled"` / 要求提及,如果你之前配置了 `"*"` 允许所有条目,请将其移除。 -### 轮换(如果 secrets 泄露,应假定已被攻破) +### 轮换(如果 secret 已泄露,则按已失陷处理) -1. 轮换 Gateway 网关 auth(`gateway.auth.token` / `OPENCLAW_GATEWAY_PASSWORD`)并重启。 -2. 轮换任何能调用 Gateway 网关的机器上的远程客户端 secrets(`gateway.remote.token` / `.password`)。 -3. 轮换 provider/API 凭证(WhatsApp 凭证、Slack/Discord tokens、`auth-profiles.json` 中的 model/API keys,以及加密 secrets 负载中的值,如果有使用)。 +1. 轮换 Gateway 网关认证(`gateway.auth.token` / `OPENCLAW_GATEWAY_PASSWORD`)并重启。 +2. 轮换所有可调用 Gateway 网关机器上的远程客户端 secret(`gateway.remote.token` / `.password`)。 +3. 轮换 provider/API 凭证(WhatsApp 凭证、Slack/Discord token、`auth-profiles.json` 中的模型/API key,以及使用时的加密 secret 负载值)。 ### 审计 1. 检查 Gateway 网关日志:`/tmp/openclaw/openclaw-YYYY-MM-DD.log`(或 `logging.file`)。 -2. 查看相关转录:`~/.openclaw/agents//sessions/*.jsonl`。 -3. 检查最近的配置更改(任何可能扩大访问范围的更改:`gateway.bind`、`gateway.auth`、私信/群组策略、`tools.elevated`、插件变更)。 -4. 重新运行 `openclaw security audit --deep`,并确认关键发现已解决。 +2. 查看相关记录:`~/.openclaw/agents//sessions/*.jsonl`。 +3. 查看最近的配置变更(任何可能扩大访问范围的内容:`gateway.bind`、`gateway.auth`、私信/群组策略、`tools.elevated`、插件变更)。 +4. 重新运行 `openclaw security audit --deep`,并确认严重发现已解决。 ### 为报告收集信息 -- 时间戳、gateway 主机操作系统 + OpenClaw 版本 -- session 转录 + 一小段日志尾部(脱敏后) -- 攻击者发送了什么 + 智能体做了什么 -- Gateway 网关是否暴露在 loopback 之外(LAN/Tailscale Funnel/Serve) +- 时间戳、gateway 主机 OS + OpenClaw 版本 +- 会话记录 + 简短日志尾部(脱敏后) +- 攻击者发送了什么 + 智能体执行了什么 +- Gateway 网关是否暴露到 loopback 之外(LAN/Tailscale Funnel/Serve) ## 使用 detect-secrets 进行 secret 扫描 -CI 会在 `secrets` job 中运行 `detect-secrets` pre-commit hook。 -推送到 `main` 时总会扫描所有文件。Pull request 在有基准提交可用时 -会走按变更文件快速路径,否则回退为全文件扫描。 -如果失败,说明存在尚未写入基线的新候选项。 +CI 会在 `secrets` 任务中运行 `detect-secrets` pre-commit hook。 +推送到 `main` 时始终会执行全文件扫描。Pull request 会在 +存在 base commit 时使用变更文件快速路径,否则回退为全文件扫描。 +如果失败,说明出现了尚未写入 baseline 的新候选项。 ### 如果 CI 失败 -1. 本地复现: +1. 在本地复现: ```bash pre-commit run --all-files detect-secrets ``` 2. 了解相关工具: - - pre-commit 中的 `detect-secrets` 会结合仓库的 - baseline 和排除项运行 `detect-secrets-hook`。 - - `detect-secrets audit` 会打开交互式审查界面,将 baseline + - pre-commit 中的 `detect-secrets` 会使用仓库的 + baseline 和排除规则运行 `detect-secrets-hook`。 + - `detect-secrets audit` 会打开交互式审查界面,用于将 baseline 中的每一项标记为真实 secret 或误报。 -3. 对于真实 secrets:轮换/移除它们,然后重新运行扫描以更新 baseline。 +3. 对于真实 secret:轮换/移除它们,然后重新运行扫描以更新 baseline。 4. 对于误报:运行交互式审查并将其标记为误报: ```bash detect-secrets audit .secrets.baseline ``` -5. 如果你需要新的排除项,请将其添加到 `.detect-secrets.cfg`,然后使用匹配的 `--exclude-files` / `--exclude-lines` 标志重新生成 - baseline(该配置文件仅供参考;detect-secrets 不会自动读取它)。 +5. 如果你需要新增排除规则,请将其添加到 `.detect-secrets.cfg`,并使用匹配的 + `--exclude-files` / `--exclude-lines` 参数重新生成 + baseline(该配置文件仅作参考;detect-secrets 不会自动读取它)。 -当更新后的 `.secrets.baseline` 反映出预期状态后,请提交它。 +当 `.secrets.baseline` 反映了预期状态后,请提交更新后的文件。 ## 报告安全问题 -在 OpenClaw 中发现了漏洞?请负责任地报告: +如果你在 OpenClaw 中发现了漏洞,请负责任地报告: -1. 邮件: [security@openclaw.ai](mailto:security@openclaw.ai) -2. 在修复之前不要公开发布 -3. 我们会署名感谢你(除非你希望匿名) +1. 电子邮件:[security@openclaw.ai](mailto:security@openclaw.ai) +2. 在修复前不要公开发布 +3. 我们会为你署名致谢(除非你希望匿名) diff --git a/docs/zh-CN/logging.md b/docs/zh-CN/logging.md index 328929e03..9791e036b 100644 --- a/docs/zh-CN/logging.md +++ b/docs/zh-CN/logging.md @@ -1,35 +1,37 @@ --- read_when: - 你需要一份面向初学者的 OpenClaw 日志概览 - - 你想要配置日志级别、格式或敏感信息脱敏处理 + - 你想要配置日志级别、格式或脱敏处理 - 你正在进行故障排除,需要快速找到日志 -summary: 文件日志、控制台输出、CLI 尾部输出,以及 Control UI 的日志标签页 +summary: 文件日志、控制台输出、CLI 尾部跟踪,以及 Control UI 日志标签页 title: 日志 x-i18n: - generated_at: "2026-04-26T06:01:23Z" + generated_at: "2026-04-26T19:16:57Z" model: gpt-5.4 provider: openai - source_hash: 6fa55caa65a2a06a757e37ad64c5fd030f958cf6827596db5c183c6c6db2ed9b + source_hash: 3c1d4629a1d886d38061a9bb89c4b4e7720189de7647eee2174821070a12b600 source_path: logging.md workflow: 15 --- -OpenClaw 有两个主要的日志显示面: +OpenClaw 有两个主要的日志展示面: - 由 Gateway 网关写入的**文件日志**(JSON 行)。 - 在终端和 Gateway 网关调试 UI 中显示的**控制台输出**。 -Control UI 的**日志**标签页会对 gateway 文件日志执行尾部跟踪。本页说明日志位于哪里、如何读取日志,以及如何配置日志级别和格式。 +Control UI 的**日志**标签页会尾随 Gateway 网关文件日志。本页说明日志位于何处、如何读取,以及如何配置日志级别和格式。 -## 日志位于哪里 +## 日志位置 默认情况下,Gateway 网关会在以下位置写入滚动日志文件: `/tmp/openclaw/openclaw-YYYY-MM-DD.log` -日期使用 gateway 主机的本地时区。 +日期使用 Gateway 网关宿主机的本地时区。 -每个文件在达到 `logging.maxFileBytes`(默认值:100 MB)时会轮转。OpenClaw 会在活动文件旁边最多保留五个带编号的归档文件,例如 `openclaw-YYYY-MM-DD.1.log`,并继续写入一个新的活动日志文件,而不是抑制诊断信息。 +每个文件在达到 `logging.maxFileBytes` 时轮转(默认值:100 MB)。 +OpenClaw 会在当前活动文件旁边最多保留五个带编号的归档文件,例如 +`openclaw-YYYY-MM-DD.1.log`,并继续写入新的活动日志文件,而不是抑制诊断信息。 你可以在 `~/.openclaw/openclaw.json` 中覆盖此设置: @@ -43,40 +45,40 @@ Control UI 的**日志**标签页会对 gateway 文件日志执行尾部跟踪 ## 如何读取日志 -### CLI:实时尾部跟踪(推荐) +### CLI:实时尾随(推荐) -使用 CLI 通过 RPC 对 gateway 日志文件执行尾部跟踪: +使用 CLI 通过 RPC 尾随 Gateway 网关日志文件: ```bash openclaw logs --follow ``` -当前实用选项: +当前有用的选项: -- `--local-time`:以你的本地时区渲染时间戳 -- `--url ` / `--token ` / `--timeout `:标准 Gateway RPC 标志 -- `--expect-final`:由智能体支持的 RPC 最终响应等待标志(通过共享客户端层在此处接受) +- `--local-time`:使用你的本地时区渲染时间戳 +- `--url ` / `--token ` / `--timeout `:标准 Gateway 网关 RPC 标志 +- `--expect-final`:由智能体支持的 RPC 最终响应等待标志(这里通过共享客户端层接受) 输出模式: - **TTY 会话**:美观、带颜色、结构化的日志行。 - **非 TTY 会话**:纯文本。 -- `--json`:按行分隔的 JSON(每行一个日志事件)。 +- `--json`:行分隔 JSON(每行一个日志事件)。 - `--plain`:在 TTY 会话中强制使用纯文本。 - `--no-color`:禁用 ANSI 颜色。 -当你传入显式的 `--url` 时,CLI 不会自动应用配置或环境变量凭证;如果目标 Gateway 网关需要身份验证,请自行附带 `--token`。 +当你显式传入 `--url` 时,CLI 不会自动应用配置或环境变量中的凭证;如果目标 Gateway 网关需要认证,请自行包含 `--token`。 在 JSON 模式下,CLI 会输出带有 `type` 标签的对象: - `meta`:流元数据(文件、游标、大小) - `log`:已解析的日志条目 - `notice`:截断 / 轮转提示 -- `raw`:未解析的日志行 +- `raw`:未解析的原始日志行 -如果 local loopback Gateway 网关请求配对,`openclaw logs` 会自动回退到已配置的本地日志文件。显式的 `--url` 目标不会使用此回退机制。 +如果本地 local loopback Gateway 网关请求配对,`openclaw logs` 会自动回退到已配置的本地日志文件。显式指定的 `--url` 目标不会使用此回退。 -如果 Gateway 网关无法访问,CLI 会打印一条简短提示,建议运行: +如果 Gateway 网关无法访问,CLI 会输出一条简短提示,建议运行: ```bash openclaw doctor @@ -84,11 +86,12 @@ openclaw doctor ### Control UI(网页) -Control UI 的**日志**标签页使用 `logs.tail` 对同一个文件执行尾部跟踪。如何打开它,请参阅 [/web/control-ui](/zh-CN/web/control-ui)。 +Control UI 的**日志**标签页会使用 `logs.tail` 尾随同一个文件。 +有关如何打开它,请参见 [/web/control-ui](/zh-CN/web/control-ui)。 ### 仅渠道日志 -如需筛选渠道活动(WhatsApp / Telegram 等),请使用: +要筛选渠道活动(WhatsApp/Telegram 等),请使用: ```bash openclaw channels logs --channel whatsapp @@ -102,21 +105,21 @@ openclaw channels logs --channel whatsapp ### 控制台输出 -控制台日志是**TTY 感知**的,并针对可读性进行了格式化: +控制台日志是**TTY 感知的**,并经过格式化以提高可读性: - 子系统前缀(例如 `gateway/channels/whatsapp`) -- 级别着色(info / warn / error) -- 可选的紧凑模式或 JSON 模式 +- 级别着色(info/warn/error) +- 可选紧凑模式或 JSON 模式 控制台格式由 `logging.consoleStyle` 控制。 -### Gateway WebSocket 日志 +### Gateway 网关 WebSocket 日志 `openclaw gateway` 还提供用于 RPC 流量的 WebSocket 协议日志: - 普通模式:仅显示重要结果(错误、解析错误、慢调用) -- `--verbose`:显示所有请求 / 响应流量 -- `--ws-log auto|compact|full`:选择详细渲染样式 +- `--verbose`:显示全部请求/响应流量 +- `--ws-log auto|compact|full`:选择详细日志的渲染样式 - `--compact`:`--ws-log compact` 的别名 示例: @@ -149,7 +152,7 @@ openclaw gateway --verbose --ws-log full - `logging.level`:**文件日志**(JSONL)级别。 - `logging.consoleLevel`:**控制台**详细程度级别。 -你可以通过 **`OPENCLAW_LOG_LEVEL`** 环境变量覆盖这两者(例如 `OPENCLAW_LOG_LEVEL=debug`)。该环境变量优先于配置文件,因此你可以在不编辑 `openclaw.json` 的情况下,仅为单次运行提高详细程度。你也可以传递全局 CLI 选项 **`--log-level `**(例如 `openclaw --log-level debug gateway run`),它会为该命令覆盖环境变量。 +你可以通过 **`OPENCLAW_LOG_LEVEL`** 环境变量覆盖这两者(例如 `OPENCLAW_LOG_LEVEL=debug`)。该环境变量优先于配置文件,因此你可以在不编辑 `openclaw.json` 的情况下,仅为单次运行提高详细程度。你还可以传递全局 CLI 选项 **`--log-level `**(例如,`openclaw --log-level debug gateway run`),它会为该命令覆盖环境变量。 `--verbose` 只影响控制台输出和 WS 日志详细程度;它不会更改文件日志级别。 @@ -157,29 +160,33 @@ openclaw gateway --verbose --ws-log full `logging.consoleStyle`: -- `pretty`:适合人工阅读,带颜色和时间戳。 +- `pretty`:适合人类阅读,带颜色和时间戳。 - `compact`:更紧凑的输出(最适合长时间会话)。 -- `json`:每行一个 JSON(适用于日志处理器)。 +- `json`:每行一个 JSON(用于日志处理器)。 ### 脱敏处理 -工具摘要可以在输出到控制台之前,对敏感令牌进行脱敏: +OpenClaw 可以在敏感令牌进入控制台输出、文件日志、OTLP 日志记录或持久化会话转录文本之前对其进行脱敏: - `logging.redactSensitive`:`off` | `tools`(默认值:`tools`) -- `logging.redactPatterns`:用于覆盖默认集合的正则表达式字符串列表 +- `logging.redactPatterns`:正则表达式字符串列表,用于覆盖默认集合 -脱敏处理会在日志输出端应用于**控制台输出**、**路由到 stderr 的控制台诊断信息**以及**文件日志**。文件日志仍保持为 JSONL,但在将行写入磁盘之前,匹配的秘密值会被屏蔽。 +文件日志和会话转录仍然保持为 JSONL,但在写入磁盘前,匹配到的秘密值会先在行或消息中被屏蔽。脱敏处理是尽力而为的:它会应用于承载文本的消息内容和日志字符串,但不会覆盖每个标识符或二进制负载字段。 -## 诊断与 OpenTelemetry +## Diagnostics 和 OpenTelemetry -诊断是结构化、机器可读的事件,用于模型运行和消息流遥测(webhook、排队、会话状态)。它们**不会**取代日志——它们为指标、追踪和导出器提供输入。无论你是否导出它们,事件都会在进程内发出。 +Diagnostics 是用于模型运行和消息流遥测(webhook、排队、会话状态)的结构化、机器可读事件。它们**不会**替代日志——它们用于驱动指标、追踪和导出器。无论你是否导出它们,事件都会在进程内发出。 -两个相邻的显示面: +两个相邻的展示面: -- **OpenTelemetry 导出** —— 通过 OTLP / HTTP 将指标、追踪和日志发送到任何兼容 OpenTelemetry 的收集器或后端(Grafana、Datadog、Honeycomb、New Relic、Tempo 等)。完整配置、信号目录、指标 / span 名称、环境变量和隐私模型位于专门页面:[OpenTelemetry 导出](/zh-CN/gateway/opentelemetry)。 -- **诊断标志** —— 定向调试日志标志,可在不提高 `logging.level` 的情况下,将额外日志路由到 `logging.file`。标志不区分大小写,并支持通配符(`telegram.*`、`*`)。可在 `diagnostics.flags` 下配置,或通过 `OPENCLAW_DIAGNOSTICS=...` 环境变量覆盖。完整指南请参阅:[诊断标志](/zh-CN/diagnostics/flags)。 +- **OpenTelemetry 导出**——通过 OTLP/HTTP 将指标、追踪和日志发送到任何兼容 OpenTelemetry 的收集器或后端(Grafana、Datadog、Honeycomb、New Relic、Tempo 等)。完整配置、信号目录、指标 / span 名称、环境变量和隐私模型位于专门页面: + [OpenTelemetry 导出](/zh-CN/gateway/opentelemetry)。 +- **Diagnostics 标志**——有针对性的调试日志标志,可将额外日志路由到 + `logging.file`,而无需提高 `logging.level`。这些标志不区分大小写,并支持通配符(`telegram.*`、`*`)。可在 `diagnostics.flags` + 下配置,或通过 `OPENCLAW_DIAGNOSTICS=...` 环境变量覆盖。完整指南: + [Diagnostics 标志](/zh-CN/diagnostics/flags)。 -如果你想为插件或自定义输出端启用诊断事件,而不使用 OTLP 导出: +要为插件或自定义接收端启用 Diagnostics 事件,而不使用 OTLP 导出: ```json5 { @@ -187,17 +194,17 @@ openclaw gateway --verbose --ws-log full } ``` -如需将 OTLP 导出到收集器,请参阅 [OpenTelemetry 导出](/zh-CN/gateway/opentelemetry)。 +如需将 OTLP 导出到收集器,请参见 [OpenTelemetry 导出](/zh-CN/gateway/opentelemetry)。 ## 故障排除提示 - **Gateway 网关无法访问?** 先运行 `openclaw doctor`。 -- **日志为空?** 检查 Gateway 网关是否正在运行,以及是否正在向 `logging.file` 中的文件路径写入。 +- **日志为空?** 检查 Gateway 网关是否正在运行,以及是否正在写入 `logging.file` 中的文件路径。 - **需要更多细节?** 将 `logging.level` 设置为 `debug` 或 `trace` 后重试。 ## 相关内容 -- [OpenTelemetry 导出](/zh-CN/gateway/opentelemetry) — OTLP / HTTP 导出、指标 / span 目录、隐私模型 -- [诊断标志](/zh-CN/diagnostics/flags) — 定向调试日志标志 +- [OpenTelemetry 导出](/zh-CN/gateway/opentelemetry) — OTLP/HTTP 导出、指标 / span 目录、隐私模型 +- [Diagnostics 标志](/zh-CN/diagnostics/flags) — 有针对性的调试日志标志 - [Gateway 网关日志内部机制](/zh-CN/gateway/logging) — WS 日志样式、子系统前缀和控制台捕获 - [配置参考](/zh-CN/gateway/configuration-reference#diagnostics) — 完整的 `diagnostics.*` 字段参考