From fa8ee31bfc8b3e1ff4496aafe341bc70dc55ff01 Mon Sep 17 00:00:00 2001 From: "openclaw-docs-i18n[bot]" Date: Thu, 23 Apr 2026 08:06:49 +0000 Subject: [PATCH] chore(i18n): refresh zh-CN translations --- docs/zh-CN/gateway/security/audit-checks.md | 130 ++ docs/zh-CN/gateway/security/index.md | 1209 +++++++++---------- 2 files changed, 683 insertions(+), 656 deletions(-) create mode 100644 docs/zh-CN/gateway/security/audit-checks.md diff --git a/docs/zh-CN/gateway/security/audit-checks.md b/docs/zh-CN/gateway/security/audit-checks.md new file mode 100644 index 000000000..09c390bca --- /dev/null +++ b/docs/zh-CN/gateway/security/audit-checks.md @@ -0,0 +1,130 @@ +--- +read_when: + - 你在 `openclaw security audit` 输出中看到了特定的 `checkId`,想知道它是什么意思 + - 你需要某个发现项对应的修复键/路径 + - 你正在对一次安全审计运行中的严重性进行分类梳理 +summary: openclaw 安全审计发出的 checkId 参考目录 +title: 安全审计检查 +x-i18n: + generated_at: "2026-04-23T08:02:56Z" + model: gpt-5.4 + provider: openai + source_hash: b53a8dc798ecc8c37be43758b741c68772b10c92323ab3d26592d7b3cc2c795e + source_path: gateway/security/audit-checks.md + workflow: 15 +--- + +# 安全审计检查 + +`openclaw security audit` 会输出以 `checkId` 为键的结构化发现项。本页是这些 ID 的参考目录。有关高层威胁模型和加固指导,请参阅 [Security](/zh-CN/gateway/security)。 + +你在真实部署中最有可能看到的高信号 `checkId` 值(并非详尽列表): + +| `checkId` | 严重性 | 重要原因 | 主要修复键/路径 | 自动修复 | +| ------------------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- | -------- | +| `fs.state_dir.perms_world_writable` | 严重 | 其他用户/进程可以修改完整的 OpenClaw 状态 | `~/.openclaw` 的文件系统权限 | 是 | +| `fs.state_dir.perms_group_writable` | 警告 | 同组用户可以修改完整的 OpenClaw 状态 | `~/.openclaw` 的文件系统权限 | 是 | +| `fs.state_dir.perms_readable` | 警告 | 状态目录可被其他人读取 | `~/.openclaw` 的文件系统权限 | 是 | +| `fs.state_dir.symlink` | 警告 | 状态目录目标变成了另一个信任边界 | 状态目录的文件系统布局 | 否 | +| `fs.config.perms_writable` | 严重 | 其他人可以更改认证/工具策略/配置 | `~/.openclaw/openclaw.json` 的文件系统权限 | 是 | +| `fs.config.symlink` | 警告 | 不支持对符号链接配置文件进行写入,并且会引入另一个信任边界 | 替换为常规配置文件,或将 `OPENCLAW_CONFIG_PATH` 指向真实文件 | 否 | +| `fs.config.perms_group_readable` | 警告 | 同组用户可以读取配置中的令牌/设置 | 配置文件的文件系统权限 | 是 | +| `fs.config.perms_world_readable` | 严重 | 配置可能暴露令牌/设置 | 配置文件的文件系统权限 | 是 | +| `fs.config_include.perms_writable` | 严重 | 配置包含文件可被其他人修改 | `openclaw.json` 引用的包含文件权限 | 是 | +| `fs.config_include.perms_group_readable` | 警告 | 同组用户可以读取包含的机密信息/设置 | `openclaw.json` 引用的包含文件权限 | 是 | +| `fs.config_include.perms_world_readable` | 严重 | 包含的机密信息/设置对所有人可读 | `openclaw.json` 引用的包含文件权限 | 是 | +| `fs.auth_profiles.perms_writable` | 严重 | 其他人可以注入或替换已存储的模型凭证 | `agents//agent/auth-profiles.json` 的权限 | 是 | +| `fs.auth_profiles.perms_readable` | 警告 | 其他人可以读取 API 密钥和 OAuth 令牌 | `agents//agent/auth-profiles.json` 的权限 | 是 | +| `fs.credentials_dir.perms_writable` | 严重 | 其他人可以修改渠道配对/凭证状态 | `~/.openclaw/credentials` 的文件系统权限 | 是 | +| `fs.credentials_dir.perms_readable` | 警告 | 其他人可以读取渠道凭证状态 | `~/.openclaw/credentials` 的文件系统权限 | 是 | +| `fs.sessions_store.perms_readable` | 警告 | 其他人可以读取会话转录内容/元数据 | 会话存储权限 | 是 | +| `fs.log_file.perms_readable` | 警告 | 其他人可以读取虽经脱敏但仍然敏感的日志 | Gateway 网关日志文件权限 | 是 | +| `fs.synced_dir` | 警告 | 将状态/配置放在 iCloud/Dropbox/Drive 中会扩大令牌/转录内容的暴露范围 | 将配置/状态移出同步文件夹 | 否 | +| `gateway.bind_no_auth` | 严重 | 远程绑定但没有共享密钥 | `gateway.bind`、`gateway.auth.*` | 否 | +| `gateway.loopback_no_auth` | 严重 | 经过反向代理的 loopback 可能变成未认证状态 | `gateway.auth.*`、代理设置 | 否 | +| `gateway.trusted_proxies_missing` | 警告 | 存在反向代理请求头,但这些代理未被信任 | `gateway.trustedProxies` | 否 | +| `gateway.http.no_auth` | 警告/严重 | 当 `auth.mode="none"` 时,Gateway 网关 HTTP API 可被访问 | `gateway.auth.mode`、`gateway.http.endpoints.*` | 否 | +| `gateway.http.session_key_override_enabled` | 信息 | HTTP API 调用方可以覆盖 `sessionKey` | `gateway.http.allowSessionKeyOverride` | 否 | +| `gateway.tools_invoke_http.dangerous_allow` | 警告/严重 | 通过 HTTP API 重新启用危险工具 | `gateway.tools.allow` | 否 | +| `gateway.nodes.allow_commands_dangerous` | 警告/严重 | 启用高影响节点命令(相机/屏幕/联系人/日历/SMS) | `gateway.nodes.allowCommands` | 否 | +| `gateway.nodes.deny_commands_ineffective` | 警告 | 类模式的拒绝条目无法匹配 shell 文本或分组 | `gateway.nodes.denyCommands` | 否 | +| `gateway.tailscale_funnel` | 严重 | 暴露到公共互联网 | `gateway.tailscale.mode` | 否 | +| `gateway.tailscale_serve` | 信息 | 已通过 Serve 启用 Tailnet 暴露 | `gateway.tailscale.mode` | 否 | +| `gateway.control_ui.allowed_origins_required` | 严重 | 非 loopback 的控制 UI 未显式配置浏览器来源允许列表 | `gateway.controlUi.allowedOrigins` | 否 | +| `gateway.control_ui.allowed_origins_wildcard` | 警告/严重 | `allowedOrigins=["*"]` 会禁用浏览器来源允许列表 | `gateway.controlUi.allowedOrigins` | 否 | +| `gateway.control_ui.host_header_origin_fallback` | 警告/严重 | 启用 Host 请求头来源回退(降低 DNS 重绑定加固级别) | `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback` | 否 | +| `gateway.control_ui.insecure_auth` | 警告 | 已启用不安全认证兼容开关 | `gateway.controlUi.allowInsecureAuth` | 否 | +| `gateway.control_ui.device_auth_disabled` | 严重 | 禁用了设备身份校验 | `gateway.controlUi.dangerouslyDisableDeviceAuth` | 否 | +| `gateway.real_ip_fallback_enabled` | 警告/严重 | 信任 `X-Real-IP` 回退可能因代理配置错误而导致源 IP 欺骗 | `gateway.allowRealIpFallback`、`gateway.trustedProxies` | 否 | +| `gateway.token_too_short` | 警告 | 过短的共享令牌更容易被暴力破解 | `gateway.auth.token` | 否 | +| `gateway.auth_no_rate_limit` | 警告 | 暴露的认证端点若无速率限制,会增加暴力破解风险 | `gateway.auth.rateLimit` | 否 | +| `gateway.trusted_proxy_auth` | 严重 | 代理身份现在成为认证边界 | `gateway.auth.mode="trusted-proxy"` | 否 | +| `gateway.trusted_proxy_no_proxies` | 严重 | trusted-proxy 认证在没有受信任代理 IP 的情况下是不安全的 | `gateway.trustedProxies` | 否 | +| `gateway.trusted_proxy_no_user_header` | 严重 | trusted-proxy 认证无法安全解析用户身份 | `gateway.auth.trustedProxy.userHeader` | 否 | +| `gateway.trusted_proxy_no_allowlist` | 警告 | trusted-proxy 认证会接受任何已认证的上游用户 | `gateway.auth.trustedProxy.allowUsers` | 否 | +| `gateway.probe_auth_secretref_unavailable` | 警告 | 深度探测在此命令路径中无法解析认证 SecretRef | 深度探测认证来源 / SecretRef 可用性 | 否 | +| `gateway.probe_failed` | 警告/严重 | 实时 Gateway 网关探测失败 | Gateway 网关可达性/认证 | 否 | +| `discovery.mdns_full_mode` | 警告/严重 | mDNS 完整模式会在本地网络上通告 `cliPath`/`sshPort` 元数据 | `discovery.mdns.mode`、`gateway.bind` | 否 | +| `config.insecure_or_dangerous_flags` | 警告 | 启用了任意不安全/危险的调试标志 | 多个键(见发现项详情) | 否 | +| `config.secrets.gateway_password_in_config` | 警告 | Gateway 网关密码直接存储在配置中 | `gateway.auth.password` | 否 | +| `config.secrets.hooks_token_in_config` | 警告 | Hook bearer 令牌直接存储在配置中 | `hooks.token` | 否 | +| `hooks.token_reuse_gateway_token` | 严重 | Hook 入口令牌同时也可解锁 Gateway 网关认证 | `hooks.token`、`gateway.auth.token` | 否 | +| `hooks.token_too_short` | 警告 | Hook 入口更容易遭受暴力破解 | `hooks.token` | 否 | +| `hooks.default_session_key_unset` | 警告 | Hook 智能体运行会扇出到按请求生成的会话 | `hooks.defaultSessionKey` | 否 | +| `hooks.allowed_agent_ids_unrestricted` | 警告/严重 | 已认证的 Hook 调用方可路由到任何已配置的智能体 | `hooks.allowedAgentIds` | 否 | +| `hooks.request_session_key_enabled` | 警告/严重 | 外部调用方可以选择 `sessionKey` | `hooks.allowRequestSessionKey` | 否 | +| `hooks.request_session_key_prefixes_missing` | 警告/严重 | 外部会话键格式没有限制 | `hooks.allowedSessionKeyPrefixes` | 否 | +| `hooks.path_root` | 严重 | Hook 路径为 `/`,使入口更容易发生冲突或误路由 | `hooks.path` | 否 | +| `hooks.installs_unpinned_npm_specs` | 警告 | Hook 安装记录未固定到不可变的 npm 规格 | Hook 安装元数据 | 否 | +| `hooks.installs_missing_integrity` | 警告 | Hook 安装记录缺少完整性元数据 | Hook 安装元数据 | 否 | +| `hooks.installs_version_drift` | 警告 | Hook 安装记录与已安装软件包发生漂移 | Hook 安装元数据 | 否 | +| `logging.redact_off` | 警告 | 敏感值会泄露到日志/状态中 | `logging.redactSensitive` | 是 | +| `browser.control_invalid_config` | 警告 | 浏览器控制配置在运行前即无效 | `browser.*` | 否 | +| `browser.control_no_auth` | 严重 | 浏览器控制在没有令牌/密码认证的情况下暴露 | `gateway.auth.*` | 否 | +| `browser.remote_cdp_http` | 警告 | 通过纯 HTTP 使用远程 CDP 缺少传输加密 | 浏览器配置文件中的 `cdpUrl` | 否 | +| `browser.remote_cdp_private_host` | 警告 | 远程 CDP 指向私有/内部主机 | 浏览器配置文件中的 `cdpUrl`、`browser.ssrfPolicy.*` | 否 | +| `sandbox.docker_config_mode_off` | 警告 | 沙箱 Docker 配置存在但未激活 | `agents.*.sandbox.mode` | 否 | +| `sandbox.bind_mount_non_absolute` | 警告 | 相对绑定挂载的解析结果可能不可预测 | `agents.*.sandbox.docker.binds[]` | 否 | +| `sandbox.dangerous_bind_mount` | 严重 | 沙箱绑定挂载目标命中了被阻止的系统、凭证或 Docker socket 路径 | `agents.*.sandbox.docker.binds[]` | 否 | +| `sandbox.dangerous_network_mode` | 严重 | 沙箱 Docker 网络使用 `host` 或 `container:*` 命名空间加入模式 | `agents.*.sandbox.docker.network` | 否 | +| `sandbox.dangerous_seccomp_profile` | 严重 | 沙箱 seccomp 配置文件削弱了容器隔离 | `agents.*.sandbox.docker.securityOpt` | 否 | +| `sandbox.dangerous_apparmor_profile` | 严重 | 沙箱 AppArmor 配置文件削弱了容器隔离 | `agents.*.sandbox.docker.securityOpt` | 否 | +| `sandbox.browser_cdp_bridge_unrestricted` | 警告 | 沙箱浏览器桥在没有源地址范围限制的情况下暴露 | `sandbox.browser.cdpSourceRange` | 否 | +| `sandbox.browser_container.non_loopback_publish` | 严重 | 现有浏览器容器在非 loopback 接口上发布 CDP | 浏览器沙箱容器发布配置 | 否 | +| `sandbox.browser_container.hash_label_missing` | 警告 | 现有浏览器容器早于当前配置哈希标签 | `openclaw sandbox recreate --browser --all` | 否 | +| `sandbox.browser_container.hash_epoch_stale` | 警告 | 现有浏览器容器早于当前浏览器配置纪元 | `openclaw sandbox recreate --browser --all` | 否 | +| `tools.exec.host_sandbox_no_sandbox_defaults` | 警告 | 当沙箱关闭时,`exec host=sandbox` 会以关闭方式失败 | `tools.exec.host`、`agents.defaults.sandbox.mode` | 否 | +| `tools.exec.host_sandbox_no_sandbox_agents` | 警告 | 当沙箱关闭时,按智能体配置的 `exec host=sandbox` 会以关闭方式失败 | `agents.list[].tools.exec.host`、`agents.list[].sandbox.mode` | 否 | +| `tools.exec.security_full_configured` | 警告/严重 | 主机 exec 正在以 `security="full"` 运行 | `tools.exec.security`、`agents.list[].tools.exec.security` | 否 | +| `tools.exec.auto_allow_skills_enabled` | 警告 | Exec 审批会隐式信任 skill 二进制文件 | `~/.openclaw/exec-approvals.json` | 否 | +| `tools.exec.allowlist_interpreter_without_strict_inline_eval` | 警告 | 解释器允许列表允许内联 eval,且不会强制重新审批 | `tools.exec.strictInlineEval`、`agents.list[].tools.exec.strictInlineEval`、exec 审批允许列表 | 否 | +| `tools.exec.safe_bins_interpreter_unprofiled` | 警告 | `safeBins` 中的解释器/运行时二进制文件没有显式配置文件,会扩大 exec 风险 | `tools.exec.safeBins`、`tools.exec.safeBinProfiles`、`agents.list[].tools.exec.*` | 否 | +| `tools.exec.safe_bins_broad_behavior` | 警告 | `safeBins` 中行为广泛的工具会削弱低风险 stdin 过滤信任模型 | `tools.exec.safeBins`、`agents.list[].tools.exec.safeBins` | 否 | +| `tools.exec.safe_bin_trusted_dirs_risky` | 警告 | `safeBinTrustedDirs` 包含可变或高风险目录 | `tools.exec.safeBinTrustedDirs`、`agents.list[].tools.exec.safeBinTrustedDirs` | 否 | +| `skills.workspace.symlink_escape` | 警告 | 工作区 `skills/**/SKILL.md` 解析到工作区根目录之外(符号链接链漂移) | 工作区 `skills/**` 文件系统状态 | 否 | +| `plugins.extensions_no_allowlist` | 警告 | 安装插件时未配置显式插件允许列表 | `plugins.allowlist` | 否 | +| `plugins.installs_unpinned_npm_specs` | 警告 | 插件安装记录未固定到不可变的 npm 规格 | 插件安装元数据 | 否 | +| `plugins.installs_missing_integrity` | 警告 | 插件安装记录缺少完整性元数据 | 插件安装元数据 | 否 | +| `plugins.installs_version_drift` | 警告 | 插件安装记录与已安装软件包发生漂移 | 插件安装元数据 | 否 | +| `plugins.code_safety` | 警告/严重 | 插件代码扫描发现可疑或危险模式 | 插件代码 / 安装来源 | 否 | +| `plugins.code_safety.entry_path` | 警告 | 插件入口路径指向隐藏位置或 `node_modules` 位置 | 插件清单中的 `entry` | 否 | +| `plugins.code_safety.entry_escape` | 严重 | 插件入口逃逸出插件目录 | 插件清单中的 `entry` | 否 | +| `plugins.code_safety.scan_failed` | 警告 | 插件代码扫描无法完成 | 插件路径 / 扫描环境 | 否 | +| `skills.code_safety` | 警告/严重 | Skills 安装器元数据/代码包含可疑或危险模式 | skill 安装来源 | 否 | +| `skills.code_safety.scan_failed` | 警告 | skill 代码扫描无法完成 | skill 扫描环境 | 否 | +| `security.exposure.open_channels_with_exec` | 警告/严重 | 共享/公开房间可以访问启用了 exec 的智能体 | `channels.*.dmPolicy`、`channels.*.groupPolicy`、`tools.exec.*`、`agents.list[].tools.exec.*` | 否 | +| `security.exposure.open_groups_with_elevated` | 严重 | 开放群组 + 提权工具会形成高影响的提示注入路径 | `channels.*.groupPolicy`、`tools.elevated.*` | 否 | +| `security.exposure.open_groups_with_runtime_or_fs` | 严重/警告 | 开放群组在没有沙箱/工作区防护的情况下可以访问命令/文件工具 | `channels.*.groupPolicy`、`tools.profile/deny`、`tools.fs.workspaceOnly`、`agents.*.sandbox.mode` | 否 | +| `security.trust_model.multi_user_heuristic` | 警告 | 配置看起来是多用户场景,而 Gateway 网关信任模型是个人助理 | 拆分信任边界,或进行共享用户加固(`sandbox.mode`、工具 deny/工作区范围限定) | 否 | +| `tools.profile_minimal_overridden` | 警告 | 智能体覆盖设置绕过了全局最小配置文件 | `agents.list[].tools.profile` | 否 | +| `plugins.tools_reachable_permissive_policy` | 警告 | 扩展工具在宽松上下文中可被访问 | `tools.profile` + 工具 allow/deny | 否 | +| `models.legacy` | 警告 | 仍然配置了旧版模型家族 | 模型选择 | 否 | +| `models.weak_tier` | 警告 | 已配置模型低于当前推荐层级 | 模型选择 | 否 | +| `models.small_params` | 严重/信息 | 小模型 + 不安全的工具暴露面会提高注入风险 | 模型选择 + 沙箱/工具策略 | 否 | +| `summary.attack_surface` | 信息 | 对认证、渠道、工具和暴露态势的汇总摘要 | 多个键(见发现项详情) | 否 | + +## 相关 + +- [Security](/zh-CN/gateway/security) +- [Configuration](/zh-CN/gateway/configuration) +- [Trusted proxy auth](/zh-CN/gateway/trusted-proxy-auth) diff --git a/docs/zh-CN/gateway/security/index.md b/docs/zh-CN/gateway/security/index.md index fdb7e9d5f..76f640d20 100644 --- a/docs/zh-CN/gateway/security/index.md +++ b/docs/zh-CN/gateway/security/index.md @@ -1,43 +1,43 @@ --- read_when: - 添加会扩大访问范围或自动化能力的功能 -summary: 运行具备 shell 访问权限的 AI Gateway 网关时的安全注意事项与威胁模型 -title: 安全 +summary: 运行具有 shell 访问权限的 AI Gateway 网关的安全注意事项和威胁模型 +title: 安全性 x-i18n: - generated_at: "2026-04-23T07:25:35Z" + generated_at: "2026-04-23T08:02:51Z" model: gpt-5.4 provider: openai - source_hash: 431bdfa6dca8d81d157ea39b09cedd849a067ee1be7a4ad1777a523ac1de5174 + source_hash: ccdc8d9a0eef88294d9f831ec4f24eb90b00631b9266d69df888a62468cb1dea source_path: gateway/security/index.md workflow: 15 --- -# 安全 +# 安全性 -**个人助理信任模型:** 本指南假设每个 Gateway 网关只有一个受信任的操作员边界(单用户/个人助理模型)。 -对于多个对抗性用户共享同一个智能体/Gateway 网关的场景,OpenClaw **不是** 一个可抵御恶意多租户的安全边界。 -如果你需要混合信任或对抗性用户运行模式,请拆分信任边界(独立的 Gateway 网关 + 凭证,最好再配合独立的 OS 用户/主机)。 +**个人助手信任模型:** 本指南假定每个 Gateway 网关只有一个受信任的操作员边界(单用户/个人助手模型)。 +OpenClaw **不是** 一个适用于多个对抗性用户共享同一智能体/Gateway 网关的恶意多租户安全边界。 +如果你需要混合信任或对抗性用户运行,请拆分信任边界(独立的 Gateway 网关 + 凭证,最好再使用独立的操作系统用户/主机)。 -**本页内容:** [信任模型](#scope-first-personal-assistant-security-model) | [快速审计](#quick-check-openclaw-security-audit) | [60 秒加固基线](#hardened-baseline-in-60-seconds) | [私信访问模型](#dm-access-model-pairing-allowlist-open-disabled) | [配置加固](#configuration-hardening-examples) | [事件响应](#incident-response) +**本页内容:** [信任模型](#scope-first-personal-assistant-security-model) | [快速审计](#quick-check-openclaw-security-audit) | [加固基线](#hardened-baseline-in-60-seconds) | [私信访问模型](#dm-access-model-pairing-allowlist-open-disabled) | [配置加固](#configuration-hardening-examples) | [事件响应](#incident-response) -## 首先明确范围:个人助理安全模型 +## 先明确范围:个人助手安全模型 -OpenClaw 的安全指南假设的是一种**个人助理**部署方式:一个受信任的操作员边界,可能包含多个智能体。 +OpenClaw 的安全指南假定你采用的是**个人助手**部署:一个受信任的操作员边界,可能对应多个智能体。 -- 支持的安全姿态:每个 Gateway 网关一个用户/信任边界(最好每个边界对应一个 OS 用户/主机/VPS)。 -- 不受支持的安全边界:一个共享的 Gateway 网关/智能体被彼此不信任或具有对抗关系的用户共同使用。 -- 如果需要对抗性用户隔离,请按信任边界拆分(独立的 Gateway 网关 + 凭证,最好再配合独立的 OS 用户/主机)。 -- 如果多个不受信任的用户都可以向同一个启用了工具的智能体发消息,应视为他们共享该智能体所委派的同一组工具权限。 +- 支持的安全姿态:每个 Gateway 网关一个用户/信任边界(最好每个边界对应一个操作系统用户/主机/VPS)。 +- 不受支持的安全边界:多个互不信任或具有对抗关系的用户,共享同一个 Gateway 网关/智能体。 +- 如果需要对抗性用户隔离,请按信任边界拆分(独立的 Gateway 网关 + 凭证,最好再使用独立的操作系统用户/主机)。 +- 如果多个不受信任的用户可以向同一个启用了工具的智能体发送消息,应视为他们共享该智能体的同一组委托工具权限。 -本页说明的是**在这一模型内部**如何进行加固。它并不声称单一共享 Gateway 网关可以提供对抗性的多租户隔离。 +本页解释的是**在该模型内**如何加固。它并不声称单个共享 Gateway 网关具备对抗性多租户隔离能力。 ## 快速检查:`openclaw security audit` -另请参见:[形式化验证(安全模型)](/zh-CN/security/formal-verification) +另见:[Formal Verification(Security Models)](/zh-CN/security/formal-verification) -请定期运行此命令(尤其是在更改配置或暴露网络接口之后): +请定期运行此命令(尤其是在修改配置或暴露网络接口之后): ```bash openclaw security audit @@ -46,103 +46,92 @@ openclaw security audit --fix openclaw security audit --json ``` -`security audit --fix` 有意保持范围较窄:它会将常见的开放群组策略切换为允许列表,恢复 `logging.redactSensitive: "tools"`,收紧 state/config/include-file 的权限,并且在 Windows 上运行时使用 Windows ACL 重置,而不是 POSIX `chmod`。 +`security audit --fix` 的修复范围被刻意保持得很窄:它会将常见的开放群组策略切换为 allowlist,恢复 `logging.redactSensitive: "tools"`,收紧状态/配置/包含文件的权限,并且在 Windows 上运行时使用 Windows ACL 重置,而不是 POSIX `chmod`。 -它会标记常见的易错点(Gateway 网关身份验证暴露、浏览器控制暴露、宽松的允许列表、文件系统权限、过于宽松的 exec 审批,以及开放渠道中的工具暴露)。 +它会标记常见的易踩坑配置(Gateway 网关认证暴露、浏览器控制暴露、高权限 allowlist、文件系统权限、过于宽松的 exec 审批,以及开放渠道的工具暴露)。 -OpenClaw 既是一个产品,也是一个实验:你是在将前沿模型行为接入真实的消息渠道和真实工具。**不存在“绝对安全”的配置。** 目标是有意识地明确: +OpenClaw 既是一个产品,也是一个实验:你正在把前沿模型行为接入真实的消息渠道和真实工具。**不存在“绝对安全”的配置。** 目标是有意识地明确: -- 谁可以与你的机器人通信 -- 机器人被允许在哪些地方执行操作 -- 机器人可以接触什么内容 +- 谁可以和你的机器人对话 +- 机器人被允许在何处执行操作 +- 机器人可以接触什么 -从仍能正常工作的最小权限开始,然后随着信心增加再逐步放宽。 +从仍能满足需求的最小权限开始,随着你建立信心,再逐步放宽。 ### 部署与主机信任 -OpenClaw 假设主机和配置边界是受信任的: +OpenClaw 假定主机和配置边界是受信任的: -- 如果某人可以修改 Gateway 网关主机状态/配置(`~/.openclaw`,包括 `openclaw.json`),应将其视为受信任操作员。 -- 让多个彼此不信任/具有对抗关系的操作员共用一个 Gateway 网关,**不是推荐的部署方式**。 -- 对于混合信任团队,请使用独立的 Gateway 网关 来拆分信任边界(至少也应使用独立的 OS 用户/主机)。 -- 推荐默认方式:每台机器/主机(或 VPS)一个用户,该用户对应一个 Gateway 网关,该 Gateway 网关中运行一个或多个智能体。 -- 在单个 Gateway 网关实例内部,经过身份验证的操作员访问属于受信任的控制平面角色,而不是按用户区分的租户角色。 -- 会话标识符(`sessionKey`、会话 ID、标签)是路由选择器,而不是授权令牌。 -- 如果多人都可以向同一个启用了工具的智能体发消息,那么他们每个人都可以驱动同一组权限。按用户的会话/记忆隔离有助于隐私,但不会把共享智能体变成按用户划分的主机授权边界。 +- 如果某人能够修改 Gateway 网关主机状态/配置(`~/.openclaw`,包括 `openclaw.json`),就应将其视为受信任的操作员。 +- 让多个彼此不信任/具有对抗关系的操作员共用一个 Gateway 网关**不是推荐的配置**。 +- 对于混合信任团队,请使用独立的 Gateway 网关 拆分信任边界(或者至少使用独立的操作系统用户/主机)。 +- 推荐默认方式:每台机器/主机(或 VPS)一个用户,该用户一个 Gateway 网关,该 Gateway 网关内可有一个或多个智能体。 +- 在同一个 Gateway 网关实例内,经过认证的操作员访问属于受信任的控制平面角色,而不是按用户划分的租户角色。 +- 会话标识符(`sessionKey`、会话 ID、标签)是路由选择器,不是授权令牌。 +- 如果多人可以向同一个启用了工具的智能体发送消息,那么他们每个人都可以驱动同一组权限。按用户隔离会话/记忆有助于保护隐私,但并不会把一个共享智能体变成按用户划分的主机授权边界。 ### 共享 Slack 工作区:真实风险 -如果“Slack 中的所有人都可以给机器人发消息”,核心风险在于被委派的工具权限: +如果“Slack 里的所有人都可以给机器人发消息”,核心风险在于委托工具权限: - 任何被允许的发送者都可以在该智能体的策略范围内诱导工具调用(`exec`、浏览器、网络/文件工具); -- 来自某个发送者的提示/内容注入可能导致影响共享状态、设备或输出的操作; -- 如果某个共享智能体拥有敏感凭证/文件,任何被允许的发送者都可能通过工具使用驱动数据外泄。 +- 某个发送者的提示词/内容注入可能导致影响共享状态、设备或输出的操作; +- 如果某个共享智能体拥有敏感凭证/文件,任何被允许的发送者都可能通过工具使用来驱动数据外泄。 -对于团队工作流,请使用拥有最少工具权限的独立智能体/Gateway 网关;涉及个人数据的智能体应保持私有。 +对于团队工作流,请使用工具最少化的独立智能体/Gateway 网关;涉及个人数据的智能体应保持私有。 ### 公司共享智能体:可接受模式 -当使用该智能体的所有人都处于同一信任边界内(例如同一个公司团队),且该智能体严格限定在业务范围内时,这是可接受的。 +当使用该智能体的所有人都处于同一信任边界内(例如同一个公司团队),并且该智能体严格限定在业务范围内时,这是可接受的。 - 在专用机器/VM/容器上运行它; -- 为该运行时使用专用的 OS 用户 + 专用的浏览器/Profile/账户; -- 不要让该运行时登录个人 Apple/Google 账户,也不要使用个人密码管理器/浏览器 Profile。 +- 为该运行时使用专用的操作系统用户 + 专用浏览器/配置文件/账号; +- 不要让该运行时登录个人 Apple/Google 账号,或个人密码管理器/浏览器配置文件。 -如果你在同一个运行时中混用个人身份和公司身份,就会打破这种隔离,并增加个人数据暴露风险。 +如果你在同一运行时中混用了个人身份和公司身份,就会破坏这种隔离,并增加个人数据暴露风险。 -## Gateway 网关 与 node 节点的信任概念 +## Gateway 网关与节点信任概念 -将 Gateway 网关 和 node 节点视为同一个操作员信任域中的不同角色: +将 Gateway 网关和节点视为同一个操作员信任域中的不同角色: -- **Gateway 网关** 是控制平面和策略表面(`gateway.auth`、工具策略、路由)。 -- **Node 节点** 是与该 Gateway 网关 配对的远程执行表面(命令、设备操作、主机本地能力)。 -- 通过身份验证连接到 Gateway 网关的调用方,在 Gateway 网关作用域内被视为受信任。完成配对后,node 节点上的操作被视为该节点上的受信任操作员操作。 -- `sessionKey` 是路由/上下文选择项,而不是按用户划分的身份验证机制。 -- Exec 审批(允许列表 + 询问)是针对操作员意图的防护栏,而不是对抗性多租户隔离。 -- OpenClaw 针对受信任单操作员场景的产品默认值是:允许在 `gateway`/`node` 上执行主机 exec,而无需审批提示(`security="full"`,`ask="off"`,除非你主动收紧)。这是有意的 UX 默认设计,本身并不是漏洞。 -- Exec 审批绑定的是精确请求上下文和尽力识别的直接本地文件操作数;它不会在语义层面建模所有运行时/解释器加载路径。若需要强边界,请使用沙箱隔离和主机隔离。 +- **Gateway 网关** 是控制平面和策略层(`gateway.auth`、工具策略、路由)。 +- **Node 节点** 是与该 Gateway 网关配对的远程执行层(命令、设备操作、主机本地能力)。 +- 通过 Gateway 网关认证的调用者,在 Gateway 网关范围内被视为受信任。完成配对后,节点操作被视为该节点上的受信任操作员行为。 +- `sessionKey` 是路由/上下文选择,不是按用户划分的认证。 +- Exec 审批(allowlist + 询问)是对操作员意图的防护栏,不是恶意多租户隔离。 +- OpenClaw 针对受信任单操作员场景的产品默认值是:允许在 `gateway`/`node` 上执行主机 exec,而无需审批提示(`security="full"`,`ask="off"`,除非你主动收紧)。这个默认值是有意的 UX 设计,本身并不是漏洞。 +- Exec 审批会绑定精确的请求上下文,以及尽力识别的直接本地文件操作数;它不会对每一种运行时/解释器加载路径进行语义建模。若需要强边界,请使用沙箱隔离和主机隔离。 -如果你需要对抗性用户隔离,请按 OS 用户/主机拆分信任边界,并运行独立的 Gateway 网关。 +如果你需要对抗性用户隔离,请按操作系统用户/主机拆分信任边界,并运行独立的 Gateway 网关。 ## 信任边界矩阵 -在进行风险研判时,可将此表作为快速模型: +在进行风险分级时,可将其作为快速模型: -| 边界或控制 | 含义 | 常见误解 | +| 边界或控制项 | 它的含义 | 常见误读 | | --- | --- | --- | -| `gateway.auth`(token/password/trusted-proxy/device auth) | 对 Gateway 网关 API 的调用方进行身份验证 | “要安全,就必须对每一帧消息都进行逐条签名” | -| `sessionKey` | 用于上下文/会话选择的路由键 | “会话键是用户身份验证边界” | -| 提示/内容防护栏 | 降低模型被滥用的风险 | “仅凭提示注入就足以证明身份验证被绕过” | -| `canvas.eval` / browser evaluate | 启用后属于有意提供给操作员的能力 | “任何 JS eval 原语在这个信任模型下都会自动构成漏洞” | -| 本地 TUI `!` shell | 由操作员显式触发的本地执行 | “本地 shell 便捷命令等同于远程注入” | -| Node 节点配对和 node 节点命令 | 已配对设备上的操作员级远程执行 | “默认就应将远程设备控制视为不受信任用户访问” | +| `gateway.auth`(token/password/trusted-proxy/device auth) | 对 Gateway 网关 API 的调用者进行认证 | “要安全,就必须对每一帧消息都做按消息签名” | +| `sessionKey` | 用于上下文/会话选择的路由键 | “会话键就是用户认证边界” | +| 提示词/内容防护栏 | 降低模型被滥用的风险 | “只要有提示词注入就说明认证被绕过了” | +| `canvas.eval` / 浏览器 evaluate | 启用时的有意操作员能力 | “任何 JS eval 原语在这种信任模型中自动算漏洞” | +| 本地 TUI `!` shell | 明确由操作员触发的本地执行 | “本地 shell 便捷命令就是远程注入” | +| 节点配对与节点命令 | 对已配对设备的操作员级远程执行 | “远程设备控制默认应被视为不受信任用户访问” | ## 按设计不视为漏洞的情况 -以下模式经常被报告,但通常会被关闭且不采取行动,除非能够证明存在真实的边界绕过: +这些模式经常被报告,但通常会被关闭且无需处理,除非能证明存在真实的边界绕过: -- 仅靠提示注入的链路,且没有策略/身份验证/沙箱隔离绕过。 -- 以单一共享主机/配置上的对抗性多租户运行为前提的声明。 -- 将共享 Gateway 网关 设置中正常的操作员读取路径(例如 `sessions.list`/`sessions.preview`/`chat.history`)认定为 IDOR 的报告。 -- 仅限 localhost 部署的发现(例如仅 loopback Gateway 网关 上缺少 HSTS)。 -- 针对本仓库中并不存在的入站路径,报告 Discord 入站 webhook 签名问题。 -- 将 node 节点配对元数据视为 `system.run` 的隐藏二级逐命令审批层的报告,而实际上真正的执行边界仍然是 Gateway 网关 的全局 node 命令策略加上 node 节点自身的 exec 审批。 -- 将 `sessionKey` 视为身份验证令牌,并据此提出“缺少按用户授权”的发现。 +- 仅有提示词注入链,而没有策略/认证/沙箱绕过。 +- 假定单个共享主机/配置上存在恶意多租户运行的声明。 +- 将正常的操作员读取路径访问(例如 `sessions.list`/`sessions.preview`/`chat.history`)在共享 Gateway 网关设置中归类为 IDOR 的声明。 +- 仅限 localhost 部署的发现(例如仅 loopback Gateway 网关上的 HSTS)。 +- 针对本仓库中并不存在的入站路径所提出的 Discord 入站 webhook 签名问题。 +- 将节点配对元数据视为 `system.run` 的隐藏第二层逐命令审批,而真实执行边界实际上仍是 Gateway 网关的全局节点命令策略加上节点自身的 exec 审批。 +- 把 `sessionKey` 当作认证令牌,并据此报告“缺少按用户授权”的问题。 -## 安全研究者提交前检查清单 +## 六十秒建立加固基线 -在提交 GHSA 之前,请确认以下所有项: - -1. 复现仍可在最新 `main` 或最新发布版本上成功。 -2. 报告包含精确代码路径(`file`、函数、行范围)以及测试版本/commit。 -3. 影响跨越了已记录的信任边界,而不仅仅是提示注入。 -4. 该声明未被列入 [超出范围](https://github.com/openclaw/openclaw/blob/main/SECURITY.md#out-of-scope)。 -5. 已检查现有 advisory 是否重复(适用时复用规范 GHSA)。 -6. 已明确部署假设(loopback/本地 还是 对外暴露,受信任操作员 还是 不受信任操作员)。 - -## 60 秒加固基线 - -先使用这个基线,然后再按受信任智能体选择性重新启用工具: +先使用这套基线,然后再按受信任智能体有选择地重新启用工具: ```json5 { @@ -167,266 +156,182 @@ OpenClaw 假设主机和配置边界是受信任的: } ``` -这样会将 Gateway 网关 限制为仅本地访问、隔离私信,并默认禁用控制平面/运行时工具。 +这会将 Gateway 网关限制为仅本地访问、隔离私信,并默认禁用控制平面/运行时工具。 ## 共享收件箱快速规则 -如果不止一个人可以给你的机器人发送私信: +如果不止一个人可以给你的机器人发私信: -- 设置 `session.dmScope: "per-channel-peer"`(对于多账户渠道则使用 `"per-account-channel-peer"`)。 -- 保持 `dmPolicy: "pairing"` 或严格允许列表。 -- 绝不要将共享私信与广泛的工具访问权限组合使用。 -- 这可以加固协作式/共享收件箱,但在用户共享主机/配置写权限时,并不是为对抗性共租户隔离而设计的。 +- 设置 `session.dmScope: "per-channel-peer"`(多账号渠道则使用 `"per-account-channel-peer"`)。 +- 保持 `dmPolicy: "pairing"` 或使用严格的 allowlist。 +- 绝不要把共享私信和广泛的工具访问权限组合在一起。 +- 这有助于加固协作式/共享收件箱,但并不是为用户共享主机/配置写入权限时的对抗性共租户隔离而设计的。 ## 上下文可见性模型 -OpenClaw 将两个概念区分开来: +OpenClaw 将两个概念分开处理: -- **触发授权**:谁可以触发智能体(`dmPolicy`、`groupPolicy`、允许列表、提及门控)。 -- **上下文可见性**:哪些补充上下文会被注入模型输入(回复正文、引用文本、线程历史、转发元数据)。 +- **触发授权**:谁可以触发该智能体(`dmPolicy`、`groupPolicy`、allowlist、mention 门控)。 +- **上下文可见性**:哪些补充上下文会被注入到模型输入中(回复正文、引用文本、线程历史、转发元数据)。 -允许列表控制触发和命令授权。`contextVisibility` 设置则控制如何过滤补充上下文(引用回复、线程根消息、已获取历史记录): +Allowlists 用于控制触发和命令授权。`contextVisibility` 设置用于控制补充上下文(引用回复、线程根消息、抓取的历史记录)的过滤方式: -- `contextVisibility: "all"`(默认)保留接收到的所有补充上下文。 -- `contextVisibility: "allowlist"` 会将补充上下文过滤为仅包含通过当前允许列表检查的发送者内容。 -- `contextVisibility: "allowlist_quote"` 与 `allowlist` 类似,但仍保留一条显式引用回复。 +- `contextVisibility: "all"`(默认)会保留收到的全部补充上下文。 +- `contextVisibility: "allowlist"` 会把补充上下文过滤为仅包含通过当前 allowlist 检查的发送者内容。 +- `contextVisibility: "allowlist_quote"` 的行为与 `allowlist` 类似,但仍会保留一个显式引用回复。 -可以按渠道或按房间/会话设置 `contextVisibility`。设置详情请参见 [群聊](/zh-CN/channels/groups#context-visibility-and-allowlists)。 +你可以按渠道或按房间/对话设置 `contextVisibility`。配置细节请参见 [群聊](/zh-CN/channels/groups#context-visibility-and-allowlists)。 -安全 advisory 分流指引: +安全通告分级指导: -- 仅证明“模型可以看到来自不在允许列表中的发送者的引用或历史文本”的报告,属于可通过 `contextVisibility` 解决的加固发现,本身并不构成身份验证或沙箱隔离边界绕过。 -- 若要认定为具有安全影响,报告仍需展示明确的信任边界绕过(身份验证、策略、沙箱隔离、审批,或其他已记录边界)。 +- 如果报告仅表明“模型可以看到来自非 allowlist 发送者的引用文本或历史文本”,这属于可通过 `contextVisibility` 解决的加固问题,而不是认证或沙箱边界绕过。 +- 若要被认定为具有安全影响,报告仍需证明存在信任边界绕过(认证、策略、沙箱、审批或其他已记录的边界)。 -## 审计会检查什么(高层概述) +## 审计会检查什么(高级概览) -- **入站访问**(私信策略、群组策略、允许列表):陌生人能否触发机器人? -- **工具影响半径**(高权限工具 + 开放房间):提示注入是否可能演变为 shell/文件/网络操作? -- **Exec 审批漂移**(`security=full`、`autoAllowSkills`、未启用 `strictInlineEval` 的解释器允许列表):主机 exec 防护栏是否仍然按你的预期工作? - - `security="full"` 是一种广泛姿态警告,并不代表存在 bug。它是为受信任的个人助理场景选择的默认值;只有当你的威胁模型确实需要审批或允许列表防护栏时,才应将其收紧。 -- **网络暴露**(Gateway 网关 bind/auth、Tailscale Serve/Funnel、弱或过短的身份验证 token)。 -- **浏览器控制暴露**(远程 node 节点、中继端口、远程 CDP 端点)。 -- **本地磁盘卫生**(权限、符号链接、配置 include、已同步文件夹路径)。 -- **插件**(插件会在没有显式允许列表的情况下加载)。 -- **策略漂移/错误配置**(已配置 sandbox docker 设置但未开启 sandbox 模式;无效的 `gateway.nodes.denyCommands` 模式,因为匹配仅针对精确命令名,例如 `system.run`,不会检查 shell 文本;危险的 `gateway.nodes.allowCommands` 条目;全局 `tools.profile="minimal"` 被按智能体配置文件覆盖;在宽松工具策略下可访问由插件拥有的工具)。 -- **运行时预期漂移**(例如,假设隐式 exec 仍然表示 `sandbox`,而现在 `tools.exec.host` 默认是 `auto`;或者显式设置 `tools.exec.host="sandbox"`,但 sandbox 模式已关闭)。 -- **模型卫生**(当配置的模型看起来较旧时给出警告;不是硬性阻止)。 +- **入站访问**(私信策略、群组策略、allowlist):陌生人能否触发机器人? +- **工具影响半径**(高权限工具 + 开放房间):提示词注入是否可能演变为 shell/文件/网络操作? +- **Exec 审批漂移**(`security=full`、`autoAllowSkills`、未启用 `strictInlineEval` 的解释器 allowlist):主机 exec 防护栏是否仍按你的预期工作? + - `security="full"` 是一种宽泛姿态警告,不代表一定存在 bug。它是受信任个人助手场景下有意选择的默认值;只有当你的威胁模型需要审批或 allowlist 防护栏时,才应收紧它。 +- **网络暴露**(Gateway 网关绑定/认证、Tailscale Serve/Funnel、弱或过短的认证 token)。 +- **浏览器控制暴露**(远程节点、中继端口、远程 CDP 端点)。 +- **本地磁盘卫生**(权限、符号链接、配置 include、 “同步文件夹” 路径)。 +- **插件**(插件在没有显式 allowlist 的情况下加载)。 +- **策略漂移/配置错误**(已配置沙箱 Docker 设置但沙箱模式关闭;无效的 `gateway.nodes.denyCommands` 模式,因为匹配仅基于精确命令名,例如 `system.run`,而不会检查 shell 文本;危险的 `gateway.nodes.allowCommands` 条目;全局 `tools.profile="minimal"` 被按智能体配置文件覆盖;在宽松工具策略下可访问插件自有工具)。 +- **运行时预期漂移**(例如误以为隐式 exec 仍然表示 `sandbox`,但 `tools.exec.host` 现在默认是 `auto`;或者在沙箱模式关闭时显式设置 `tools.exec.host="sandbox"`)。 +- **模型卫生**(当已配置模型看起来像旧版模型时发出警告;不是硬性阻断)。 -如果你运行 `--deep`,OpenClaw 还会尽力尝试对 Gateway 网关进行实时探测。 +如果你运行 `--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 提供商) -- **Slack tokens**:config/env(`channels.slack.*`) -- **配对允许列表**: - - `~/.openclaw/credentials/-allowFrom.json`(默认账户) - - `~/.openclaw/credentials/--allowFrom.json`(非默认账户) +- **Telegram 机器人 token**:配置/环境变量,或 `channels.telegram.tokenFile`(仅接受常规文件;拒绝符号链接) +- **Discord 机器人 token**:配置/环境变量,或 SecretRef(env/file/exec 提供商) +- **Slack token**:配置/环境变量(`channels.slack.*`) +- **配对 allowlist**: + - `~/.openclaw/credentials/-allowFrom.json`(默认账号) + - `~/.openclaw/credentials/--allowFrom.json`(非默认账号) - **模型认证配置文件**:`~/.openclaw/agents//agent/auth-profiles.json` - **基于文件的 secrets 负载(可选)**:`~/.openclaw/secrets.json` - **旧版 OAuth 导入**:`~/.openclaw/credentials/oauth.json` ## 安全审计检查清单 -当审计输出发现项时,请按以下优先级顺序处理: +当审计打印出发现项时,请按以下优先级处理: -1. **任何“开放” + 已启用工具的组合**:先锁定私信/群组(配对/允许列表),再收紧工具策略/沙箱隔离。 -2. **公共网络暴露**(LAN bind、Funnel、缺少身份验证):立即修复。 -3. **浏览器控制远程暴露**:将其视为操作员访问权限(仅 tailnet、谨慎配对 node 节点、避免公开暴露)。 -4. **权限**:确保 state/config/credentials/auth 对组用户或所有用户不可读。 +1. **任何“开放” + 已启用工具**:先锁定私信/群组(配对/allowlist),然后收紧工具策略/沙箱隔离。 +2. **公共网络暴露**(LAN 绑定、Funnel、缺少认证):立即修复。 +3. **浏览器控制的远程暴露**:应将其视为操作员访问权限来处理(仅 tailnet、有意识地配对节点、避免公开暴露)。 +4. **权限**:确保状态/配置/凭证/认证数据不会对 group/world 可读。 5. **插件**:只加载你明确信任的插件。 -6. **模型选择**:对于任何带工具的机器人,优先使用现代且具备更强指令加固能力的模型。 +6. **模型选择**:对任何启用工具的机器人,优先选择现代、具备更强指令加固能力的模型。 ## 安全审计术语表 -在真实部署中,你最可能看到的高信号 `checkId` 值如下(并非完整列表): +每条审计发现都会使用结构化的 `checkId` 作为键(例如 +`gateway.bind_no_auth` 或 `tools.exec.security_full_configured`)。常见的 +严重级别类别包括: -| `checkId` | 严重级别 | 为什么重要 | 主要修复键/路径 | 自动修复 | -| ------------------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- | -------- | -| `fs.state_dir.perms_world_writable` | 严重 | 其他用户/进程可以修改完整的 OpenClaw state | `~/.openclaw` 的文件系统权限 | 是 | -| `fs.state_dir.perms_group_writable` | 警告 | 同组用户可以修改完整的 OpenClaw state | `~/.openclaw` 的文件系统权限 | 是 | -| `fs.state_dir.perms_readable` | 警告 | 其他人可以读取 state 目录 | `~/.openclaw` 的文件系统权限 | 是 | -| `fs.state_dir.symlink` | 警告 | state 目录目标变成了另一个信任边界 | state 目录的文件系统布局 | 否 | -| `fs.config.perms_writable` | 严重 | 其他人可以更改 auth/工具策略/配置 | `~/.openclaw/openclaw.json` 的文件系统权限 | 是 | -| `fs.config.symlink` | 警告 | 不支持对符号链接配置文件进行写入,并且会引入另一个信任边界 | 替换为常规配置文件,或将 `OPENCLAW_CONFIG_PATH` 指向真实文件 | 否 | -| `fs.config.perms_group_readable` | 警告 | 同组用户可以读取配置 token/设置 | 配置文件的文件系统权限 | 是 | -| `fs.config.perms_world_readable` | 严重 | 配置可能泄露 token/设置 | 配置文件的文件系统权限 | 是 | -| `fs.config_include.perms_writable` | 严重 | 配置 include 文件可被其他人修改 | `openclaw.json` 引用的 include 文件权限 | 是 | -| `fs.config_include.perms_group_readable` | 警告 | 同组用户可以读取 include 的 secrets/设置 | `openclaw.json` 引用的 include 文件权限 | 是 | -| `fs.config_include.perms_world_readable` | 严重 | include 的 secrets/设置对所有人可读 | `openclaw.json` 引用的 include 文件权限 | 是 | -| `fs.auth_profiles.perms_writable` | 严重 | 其他人可以注入或替换已存储的模型凭证 | `agents//agent/auth-profiles.json` 的权限 | 是 | -| `fs.auth_profiles.perms_readable` | 警告 | 其他人可以读取 API key 和 OAuth token | `agents//agent/auth-profiles.json` 的权限 | 是 | -| `fs.credentials_dir.perms_writable` | 严重 | 其他人可以修改渠道配对/凭证 state | `~/.openclaw/credentials` 的文件系统权限 | 是 | -| `fs.credentials_dir.perms_readable` | 警告 | 其他人可以读取渠道凭证 state | `~/.openclaw/credentials` 的文件系统权限 | 是 | -| `fs.sessions_store.perms_readable` | 警告 | 其他人可以读取会话转录/元数据 | 会话存储权限 | 是 | -| `fs.log_file.perms_readable` | 警告 | 其他人可以读取已脱敏但仍然敏感的日志 | Gateway 网关日志文件权限 | 是 | -| `fs.synced_dir` | 警告 | iCloud/Dropbox/Drive 中的 state/配置会扩大 token/转录暴露范围 | 将配置/state 移出同步文件夹 | 否 | -| `gateway.bind_no_auth` | 严重 | 远程 bind 且没有共享密钥 | `gateway.bind`、`gateway.auth.*` | 否 | -| `gateway.loopback_no_auth` | 严重 | 经反向代理的 loopback 可能变成未认证访问 | `gateway.auth.*`、代理设置 | 否 | -| `gateway.trusted_proxies_missing` | 警告 | 存在反向代理头,但未将其标记为受信任 | `gateway.trustedProxies` | 否 | -| `gateway.http.no_auth` | 警告/严重 | 使用 `auth.mode="none"` 时可访问 Gateway 网关 HTTP API | `gateway.auth.mode`、`gateway.http.endpoints.*` | 否 | -| `gateway.http.session_key_override_enabled` | 信息 | HTTP API 调用方可以覆盖 `sessionKey` | `gateway.http.allowSessionKeyOverride` | 否 | -| `gateway.tools_invoke_http.dangerous_allow` | 警告/严重 | 通过 HTTP API 重新启用了危险工具 | `gateway.tools.allow` | 否 | -| `gateway.nodes.allow_commands_dangerous` | 警告/严重 | 启用了高影响的 node 节点命令(摄像头/屏幕/联系人/日历/SMS) | `gateway.nodes.allowCommands` | 否 | -| `gateway.nodes.deny_commands_ineffective` | 警告 | 类似模式的 deny 条目不会匹配 shell 文本或命令组 | `gateway.nodes.denyCommands` | 否 | -| `gateway.tailscale_funnel` | 严重 | 对公网暴露 | `gateway.tailscale.mode` | 否 | -| `gateway.tailscale_serve` | 信息 | 已通过 Serve 启用 tailnet 暴露 | `gateway.tailscale.mode` | 否 | -| `gateway.control_ui.allowed_origins_required` | 严重 | 非 loopback 的控制 UI 缺少显式浏览器来源允许列表 | `gateway.controlUi.allowedOrigins` | 否 | -| `gateway.control_ui.allowed_origins_wildcard` | 警告/严重 | `allowedOrigins=["*"]` 会禁用浏览器来源允许列表 | `gateway.controlUi.allowedOrigins` | 否 | -| `gateway.control_ui.host_header_origin_fallback` | 警告/严重 | 启用 Host-header 来源回退(降低 DNS rebinding 加固强度) | `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback` | 否 | -| `gateway.control_ui.insecure_auth` | 警告 | 已启用 insecure-auth 兼容开关 | `gateway.controlUi.allowInsecureAuth` | 否 | -| `gateway.control_ui.device_auth_disabled` | 严重 | 禁用了设备身份检查 | `gateway.controlUi.dangerouslyDisableDeviceAuth` | 否 | -| `gateway.real_ip_fallback_enabled` | 警告/严重 | 信任 `X-Real-IP` 回退可能因代理错误配置而导致源 IP 伪造 | `gateway.allowRealIpFallback`、`gateway.trustedProxies` | 否 | -| `gateway.token_too_short` | 警告 | 较短的共享 token 更容易被暴力破解 | `gateway.auth.token` | 否 | -| `gateway.auth_no_rate_limit` | 警告 | 暴露的 auth 如果没有速率限制,会增加暴力破解风险 | `gateway.auth.rateLimit` | 否 | -| `gateway.trusted_proxy_auth` | 严重 | 代理身份现在成为 auth 边界 | `gateway.auth.mode="trusted-proxy"` | 否 | -| `gateway.trusted_proxy_no_proxies` | 严重 | trusted-proxy auth 如果没有受信任代理 IP,将是不安全的 | `gateway.trustedProxies` | 否 | -| `gateway.trusted_proxy_no_user_header` | 严重 | trusted-proxy auth 无法安全解析用户身份 | `gateway.auth.trustedProxy.userHeader` | 否 | -| `gateway.trusted_proxy_no_allowlist` | 警告 | trusted-proxy auth 会接受任何已认证的上游用户 | `gateway.auth.trustedProxy.allowUsers` | 否 | -| `checkId` | 严重级别 | 为什么重要 | 主要修复键/路径 | 自动修复 | -| `gateway.probe_auth_secretref_unavailable` | 警告 | 深度探测在当前命令路径下无法解析 auth SecretRef | 深度探测 auth 来源 / SecretRef 可用性 | 否 | -| `gateway.probe_failed` | 警告/严重 | 实时 Gateway 网关探测失败 | Gateway 网关可达性/身份验证 | 否 | -| `discovery.mdns_full_mode` | 警告/严重 | mDNS 完整模式会在本地网络上广播 `cliPath`/`sshPort` 元数据 | `discovery.mdns.mode`、`gateway.bind` | 否 | -| `config.insecure_or_dangerous_flags` | 警告 | 已启用任意不安全/危险的调试标志 | 多个键(见发现详情) | 否 | -| `config.secrets.gateway_password_in_config` | 警告 | Gateway 网关密码直接存储在配置中 | `gateway.auth.password` | 否 | -| `config.secrets.hooks_token_in_config` | 警告 | Hook bearer token 直接存储在配置中 | `hooks.token` | 否 | -| `hooks.token_reuse_gateway_token` | 严重 | Hook 入站 token 同时也可解锁 Gateway 网关身份验证 | `hooks.token`、`gateway.auth.token` | 否 | -| `hooks.token_too_short` | 警告 | Hook 入站更容易被暴力破解 | `hooks.token` | 否 | -| `hooks.default_session_key_unset` | 警告 | Hook 智能体运行会扇出到按请求生成的会话中 | `hooks.defaultSessionKey` | 否 | -| `hooks.allowed_agent_ids_unrestricted` | 警告/严重 | 已认证的 Hook 调用方可以路由到任意已配置智能体 | `hooks.allowedAgentIds` | 否 | -| `hooks.request_session_key_enabled` | 警告/严重 | 外部调用方可以选择 `sessionKey` | `hooks.allowRequestSessionKey` | 否 | -| `hooks.request_session_key_prefixes_missing` | 警告/严重 | 外部会话键格式没有边界限制 | `hooks.allowedSessionKeyPrefixes` | 否 | -| `hooks.path_root` | 严重 | Hook 路径为 `/`,更容易发生入站冲突或误路由 | `hooks.path` | 否 | -| `hooks.installs_unpinned_npm_specs` | 警告 | Hook 安装记录未固定到不可变的 npm 规格 | Hook 安装元数据 | 否 | -| `hooks.installs_missing_integrity` | 警告 | Hook 安装记录缺少完整性元数据 | Hook 安装元数据 | 否 | -| `hooks.installs_version_drift` | 警告 | Hook 安装记录与已安装包发生版本漂移 | Hook 安装元数据 | 否 | -| `logging.redact_off` | 警告 | 敏感值会泄露到日志/状态中 | `logging.redactSensitive` | 是 | -| `browser.control_invalid_config` | 警告 | 浏览器控制配置在运行前即无效 | `browser.*` | 否 | -| `browser.control_no_auth` | 严重 | 浏览器控制在没有 token/password 身份验证的情况下暴露 | `gateway.auth.*` | 否 | -| `browser.remote_cdp_http` | 警告 | 通过纯 HTTP 访问远程 CDP 缺少传输加密 | 浏览器 profile `cdpUrl` | 否 | -| `browser.remote_cdp_private_host` | 警告 | 远程 CDP 指向私有/内网主机 | 浏览器 profile `cdpUrl`、`browser.ssrfPolicy.*` | 否 | -| `sandbox.docker_config_mode_off` | 警告 | 已存在 Sandbox Docker 配置但未生效 | `agents.*.sandbox.mode` | 否 | -| `sandbox.bind_mount_non_absolute` | 警告 | 相对 bind mount 可能解析为不可预测的位置 | `agents.*.sandbox.docker.binds[]` | 否 | -| `sandbox.dangerous_bind_mount` | 严重 | Sandbox bind mount 指向了受阻止的系统、凭证或 Docker socket 路径 | `agents.*.sandbox.docker.binds[]` | 否 | -| `sandbox.dangerous_network_mode` | 严重 | Sandbox Docker 网络使用 `host` 或 `container:*` 命名空间加入模式 | `agents.*.sandbox.docker.network` | 否 | -| `sandbox.dangerous_seccomp_profile` | 严重 | Sandbox seccomp profile 会削弱容器隔离 | `agents.*.sandbox.docker.securityOpt` | 否 | -| `sandbox.dangerous_apparmor_profile` | 严重 | Sandbox AppArmor profile 会削弱容器隔离 | `agents.*.sandbox.docker.securityOpt` | 否 | -| `sandbox.browser_cdp_bridge_unrestricted` | 警告 | Sandbox 浏览器桥接在没有源地址范围限制的情况下暴露 | `sandbox.browser.cdpSourceRange` | 否 | -| `sandbox.browser_container.non_loopback_publish` | 严重 | 现有浏览器容器在非 loopback 接口上发布 CDP | 浏览器沙箱容器发布配置 | 否 | -| `sandbox.browser_container.hash_label_missing` | 警告 | 现有浏览器容器早于当前配置哈希标签 | `openclaw sandbox recreate --browser --all` | 否 | -| `sandbox.browser_container.hash_epoch_stale` | 警告 | 现有浏览器容器早于当前浏览器配置 epoch | `openclaw sandbox recreate --browser --all` | 否 | -| `tools.exec.host_sandbox_no_sandbox_defaults` | 警告 | 当 sandbox 关闭时,`exec host=sandbox` 会以关闭式失败 | `tools.exec.host`、`agents.defaults.sandbox.mode` | 否 | -| `tools.exec.host_sandbox_no_sandbox_agents` | 警告 | 当 sandbox 关闭时,按智能体配置的 `exec host=sandbox` 会以关闭式失败 | `agents.list[].tools.exec.host`、`agents.list[].sandbox.mode` | 否 | -| `tools.exec.security_full_configured` | 警告/严重 | 主机 exec 正以 `security="full"` 运行 | `tools.exec.security`、`agents.list[].tools.exec.security` | 否 | -| `tools.exec.auto_allow_skills_enabled` | 警告 | Exec 审批会隐式信任技能 bin | `~/.openclaw/exec-approvals.json` | 否 | -| `tools.exec.allowlist_interpreter_without_strict_inline_eval` | 警告 | 解释器允许列表允许内联 eval,但不会强制重新审批 | `tools.exec.strictInlineEval`、`agents.list[].tools.exec.strictInlineEval`、exec 审批允许列表 | 否 | -| `tools.exec.safe_bins_interpreter_unprofiled` | 警告 | `safeBins` 中的解释器/运行时 bin 若没有显式 profile,会扩大 exec 风险 | `tools.exec.safeBins`、`tools.exec.safeBinProfiles`、`agents.list[].tools.exec.*` | 否 | -| `tools.exec.safe_bins_broad_behavior` | 警告 | `safeBins` 中具备广泛行为的工具会削弱低风险 stdin 过滤信任模型 | `tools.exec.safeBins`、`agents.list[].tools.exec.safeBins` | 否 | -| `tools.exec.safe_bin_trusted_dirs_risky` | 警告 | `safeBinTrustedDirs` 包含可变或高风险目录 | `tools.exec.safeBinTrustedDirs`、`agents.list[].tools.exec.safeBinTrustedDirs` | 否 | -| `skills.workspace.symlink_escape` | 警告 | 工作区 `skills/**/SKILL.md` 解析到工作区根之外(符号链接链漂移) | 工作区 `skills/**` 文件系统状态 | 否 | -| `plugins.extensions_no_allowlist` | 警告 | 插件安装时没有显式插件允许列表 | `plugins.allowlist` | 否 | -| `plugins.installs_unpinned_npm_specs` | 警告 | 插件安装记录未固定到不可变的 npm 规格 | 插件安装元数据 | 否 | -| `checkId` | 严重级别 | 为什么重要 | 主要修复键/路径 | 自动修复 | -| `plugins.installs_missing_integrity` | 警告 | 插件安装记录缺少完整性元数据 | 插件安装元数据 | 否 | -| `plugins.installs_version_drift` | 警告 | 插件安装记录与已安装包发生版本漂移 | 插件安装元数据 | 否 | -| `plugins.code_safety` | 警告/严重 | 插件代码扫描发现可疑或危险模式 | 插件代码 / 安装来源 | 否 | -| `plugins.code_safety.entry_path` | 警告 | 插件入口路径指向隐藏目录或 `node_modules` 位置 | 插件清单 `entry` | 否 | -| `plugins.code_safety.entry_escape` | 严重 | 插件入口逃逸出插件目录 | 插件清单 `entry` | 否 | -| `plugins.code_safety.scan_failed` | 警告 | 插件代码扫描无法完成 | 插件路径 / 扫描环境 | 否 | -| `skills.code_safety` | 警告/严重 | 技能安装器元数据/代码包含可疑或危险模式 | 技能安装来源 | 否 | -| `skills.code_safety.scan_failed` | 警告 | 技能代码扫描无法完成 | 技能扫描环境 | 否 | -| `security.exposure.open_channels_with_exec` | 警告/严重 | 共享/公共房间可以访问启用了 exec 的智能体 | `channels.*.dmPolicy`、`channels.*.groupPolicy`、`tools.exec.*`、`agents.list[].tools.exec.*` | 否 | -| `security.exposure.open_groups_with_elevated` | 严重 | 开放群组 + 高权限工具会形成高影响的提示注入路径 | `channels.*.groupPolicy`、`tools.elevated.*` | 否 | -| `security.exposure.open_groups_with_runtime_or_fs` | 严重/警告 | 开放群组可以在没有沙箱隔离/工作区保护的情况下访问命令/文件工具 | `channels.*.groupPolicy`、`tools.profile/deny`、`tools.fs.workspaceOnly`、`agents.*.sandbox.mode` | 否 | -| `security.trust_model.multi_user_heuristic` | 警告 | 配置看起来像多用户使用,但 Gateway 网关信任模型是个人助理 | 拆分信任边界,或进行共享用户加固(`sandbox.mode`、工具 deny/工作区范围限制) | 否 | -| `tools.profile_minimal_overridden` | 警告 | 智能体覆盖配置绕过了全局 minimal profile | `agents.list[].tools.profile` | 否 | -| `plugins.tools_reachable_permissive_policy` | 警告 | 在宽松上下文中可以访问扩展工具 | `tools.profile` + 工具 allow/deny | 否 | -| `models.legacy` | 警告 | 仍在配置旧版模型家族 | 模型选择 | 否 | -| `models.weak_tier` | 警告 | 已配置的模型低于当前推荐层级 | 模型选择 | 否 | -| `models.small_params` | 严重/信息 | 小参数模型 + 不安全工具表面会提高注入风险 | 模型选择 + 沙箱隔离/工具策略 | 否 | -| `summary.attack_surface` | 信息 | 对身份验证、渠道、工具和暴露姿态的汇总摘要 | 多个键(见发现详情) | 否 | +- `fs.*` — 状态、配置、凭证、认证配置文件的文件系统权限。 +- `gateway.*` — 绑定模式、认证、Tailscale、Control UI、trusted-proxy 设置。 +- `hooks.*`、`browser.*`、`sandbox.*`、`tools.exec.*` — 各表面的加固项。 +- `plugins.*`、`skills.*` — plugin/skill 供应链和扫描发现。 +- `security.exposure.*` — 访问策略与工具影响半径交汇处的跨领域检查。 -## 通过 HTTP 使用控制 UI +完整目录(含严重级别、修复键和自动修复支持)见 +[安全审计检查项](/zh-CN/gateway/security/audit-checks)。 + +## 通过 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 角色的 Control UI 会话。 +可以在没有设备身份的情况下允许**操作员** 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` -- `hooks.gmail.allowUnsafeExternalContent=true` -- `hooks.mappings[].allowUnsafeExternalContent=true` -- `tools.exec.applyPatch.workspaceOnly=false` -- `plugins.entries.acpx.config.permissionMode=approve-all` + + + - `gateway.controlUi.allowInsecureAuth=true` + - `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true` + - `gateway.controlUi.dangerouslyDisableDeviceAuth=true` + - `hooks.gmail.allowUnsafeExternalContent=true` + - `hooks.mappings[].allowUnsafeExternalContent=true` + - `tools.exec.applyPatch.workspaceOnly=false` + - `plugins.entries.acpx.config.permissionMode=approve-all` + -在 OpenClaw 配置 schema 中定义的完整 `dangerous*` / `dangerously*` 配置键: + + Control UI 和浏览器: -- `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback` -- `gateway.controlUi.dangerouslyDisableDeviceAuth` -- `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` -- `channels.discord.dangerouslyAllowNameMatching` -- `channels.discord.accounts..dangerouslyAllowNameMatching` -- `channels.slack.dangerouslyAllowNameMatching` -- `channels.slack.accounts..dangerouslyAllowNameMatching` -- `channels.googlechat.dangerouslyAllowNameMatching` -- `channels.googlechat.accounts..dangerouslyAllowNameMatching` -- `channels.msteams.dangerouslyAllowNameMatching` -- `channels.synology-chat.dangerouslyAllowNameMatching`(渠道插件) -- `channels.synology-chat.accounts..dangerouslyAllowNameMatching`(渠道插件) -- `channels.synology-chat.dangerouslyAllowInheritedWebhookPath`(渠道插件) -- `channels.zalouser.dangerouslyAllowNameMatching`(渠道插件) -- `channels.zalouser.accounts..dangerouslyAllowNameMatching`(渠道插件) -- `channels.irc.dangerouslyAllowNameMatching`(渠道插件) -- `channels.irc.accounts..dangerouslyAllowNameMatching`(渠道插件) -- `channels.mattermost.dangerouslyAllowNameMatching`(渠道插件) -- `channels.mattermost.accounts..dangerouslyAllowNameMatching`(渠道插件) -- `channels.telegram.network.dangerouslyAllowPrivateNetwork` -- `channels.telegram.accounts..network.dangerouslyAllowPrivateNetwork` -- `agents.defaults.sandbox.docker.dangerouslyAllowReservedContainerTargets` -- `agents.defaults.sandbox.docker.dangerouslyAllowExternalBindSources` -- `agents.defaults.sandbox.docker.dangerouslyAllowContainerNamespaceJoin` -- `agents.list[].sandbox.docker.dangerouslyAllowReservedContainerTargets` -- `agents.list[].sandbox.docker.dangerouslyAllowExternalBindSources` -- `agents.list[].sandbox.docker.dangerouslyAllowContainerNamespaceJoin` + - `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback` + - `gateway.controlUi.dangerouslyDisableDeviceAuth` + - `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` + + 渠道名称匹配(内置渠道和插件渠道;如适用,也可按 + `accounts.` 单独设置): + + - `channels.discord.dangerouslyAllowNameMatching` + - `channels.slack.dangerouslyAllowNameMatching` + - `channels.googlechat.dangerouslyAllowNameMatching` + - `channels.msteams.dangerouslyAllowNameMatching` + - `channels.synology-chat.dangerouslyAllowNameMatching`(渠道插件) + - `channels.synology-chat.dangerouslyAllowInheritedWebhookPath`(渠道插件) + - `channels.zalouser.dangerouslyAllowNameMatching`(渠道插件) + - `channels.irc.dangerouslyAllowNameMatching`(渠道插件) + - `channels.mattermost.dangerouslyAllowNameMatching`(渠道插件) + + 网络暴露: + + - `channels.telegram.network.dangerouslyAllowPrivateNetwork`(也支持按账号设置) + + 沙箱 Docker(默认值 + 按智能体设置): + + - `agents.defaults.sandbox.docker.dangerouslyAllowReservedContainerTargets` + - `agents.defaults.sandbox.docker.dangerouslyAllowExternalBindSources` + - `agents.defaults.sandbox.docker.dangerouslyAllowContainerNamespaceJoin` + + + ## 反向代理配置 -如果你在反向代理(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 源的代理执行关闭式失败** -- 同主机的 loopback 反向代理仍可使用 `gateway.trustedProxies` 来进行本地客户端检测和转发 IP 处理 -- 对于同主机的 loopback 反向代理,请使用 token/password auth,而不是 `gateway.auth.mode: "trusted-proxy"` +- trusted-proxy 认证**会对来自 loopback 源的代理默认失败关闭** +- 同主机上的 loopback 反向代理仍可使用 `gateway.trustedProxies` 来进行本地客户端检测和转发 IP 处理 +- 对于同主机 loopback 反向代理,应使用 token/password 认证,而不是 `gateway.auth.mode: "trusted-proxy"` ```yaml gateway: trustedProxies: - - "10.0.0.1" # 反向代理 IP + - "10.0.0.1" # reverse proxy IP # 可选。默认 false。 # 仅当你的代理无法提供 X-Forwarded-For 时启用。 allowRealIpFallback: false @@ -435,7 +340,7 @@ 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`。 良好的反向代理行为(覆盖传入的转发头): @@ -452,49 +357,52 @@ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ## HSTS 和来源说明 -- OpenClaw Gateway 网关优先面向本地/loopback。如果你在反向代理处终止 TLS,请在那里为面向代理的 HTTPS 域名设置 HSTS。 -- 如果 gateway 本身终止 HTTPS,你可以设置 `gateway.http.securityHeaders.strictTransportSecurity`,让 OpenClaw 在响应中发出 HSTS 头。 +- OpenClaw Gateway 网关以本地/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: ["*"]` 是显式的允许所有浏览器来源策略,不是加固后的默认值。除非是在严格受控的本地测试中,否则应避免使用。 -- 即使启用了通用的 loopback 豁免,loopback 上的浏览器来源 auth 失败仍会受到速率限制,但锁定键会按规范化后的 `Origin` 值分别限定,而不是共用一个 localhost 桶。 -- `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true` 会启用 Host-header 来源回退模式;请将其视为由操作员主动选择的危险策略。 -- 请将 DNS rebinding 和代理 host header 行为视为部署加固问题;保持 `trustedProxies` 精确收紧,并避免将 gateway 直接暴露到公共互联网。 +- `gateway.controlUi.allowedOrigins: ["*"]` 是显式的允许所有浏览器来源策略,不是加固后的默认值。除严格受控的本地测试外,应避免使用。 +- 即使启用了一般性的 loopback 豁免,loopback 上的浏览器来源认证失败仍会受到速率限制,但锁定键是按归一化后的 `Origin` 值分别作用域,而不是共用一个 localhost 桶。 +- `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true` 会启用 Host 头来源回退模式;应将其视为由操作员主动选择的危险策略。 +- 应将 DNS 重绑定和代理 Host 头行为视为部署加固问题;保持 `trustedProxies` 足够严格,并避免将 Gateway 网关直接暴露在公共互联网。 ## 本地会话日志存储在磁盘上 -OpenClaw 会将会话转录存储在磁盘上的 `~/.openclaw/agents//sessions/*.jsonl` 中。 -这对于会话连续性以及(可选的)会话记忆索引是必需的,但这也意味着 -**任何具有文件系统访问权限的进程/用户都可以读取这些日志**。请将磁盘访问视为信任 -边界,并锁定 `~/.openclaw` 的权限(见下方审计部分)。如果你需要在智能体之间实现更强的隔离,请让它们运行在不同的 OS 用户或不同主机下。 +OpenClaw 会将会话转录日志存储在磁盘上的 `~/.openclaw/agents//sessions/*.jsonl`。 +这是实现会话连续性以及(可选)会话记忆索引所必需的,但这也意味着 +**任何具有文件系统访问权限的进程/用户都可以读取这些日志**。应将磁盘访问视为信任 +边界,并锁定 `~/.openclaw` 的权限(见下方审计部分)。如果你需要 +在不同智能体之间实现更强的隔离,请让它们运行在独立的操作系统用户或独立主机下。 -## Node 节点执行(`system.run`) +## 节点执行(`system.run`) -如果已配对一个 macOS node 节点,Gateway 网关可以在该节点上调用 `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` 策略由该节点自己的 exec 审批文件(`exec.approvals.node.*`)决定,它可以比 gateway 的全局命令 ID 策略更严格,也可以更宽松。 -- 以 `security="full"` 和 `ask="off"` 运行的 node 节点是在遵循默认的受信任操作员模型。除非你的部署明确需要更严格的审批或允许列表立场,否则应将其视为预期行为。 -- 审批模式会绑定精确的请求上下文,以及在可能情况下绑定一个具体的本地脚本/文件操作数。若 OpenClaw 无法为解释器/运行时命令识别出恰好一个直接本地文件,则基于审批的执行会被拒绝,而不会承诺提供完整的语义覆盖。 -- 对于 `host=node`,基于审批的运行还会存储一个规范化的已准备 `systemRunPlan`;后续已批准的转发会复用该已存储计划,并且 gateway 验证会拒绝在审批请求创建后由调用方编辑命令/cwd/会话上下文。 -- 如果你不希望进行远程执行,请将 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/会话上下文。 +- 如果你不希望进行远程执行,请将 security 设为 **deny**,并移除该 Mac 的节点配对。 -这一区别对于分流研判很重要: +这个区别对于分级很重要: -- 一个重新连接的已配对 node 节点广播了不同的命令列表,这本身**并不**构成漏洞,只要 Gateway 网关的全局策略和该节点本地的 exec 审批仍然在执行真正的边界控制。 -- 将 node 节点配对元数据视为隐藏的第二层逐命令审批层的报告,通常属于策略/UX 混淆,而不是安全边界绕过。 +- 一个重新连接的已配对节点宣告不同的命令列表,本身并不构成漏洞,只要 Gateway 网关全局策略和节点本地 exec 审批仍然在执行真实的执行边界。 +- 把节点配对元数据视为第二层隐藏的逐命令审批层的报告,通常属于策略/UX 混淆,而不是安全边界绕过。 -## 动态 Skills(watcher / 远程 node 节点) +## 动态 Skills(watcher / 远程节点) OpenClaw 可以在会话中途刷新 Skills 列表: -- **Skills watcher**:对 `SKILL.md` 的更改可以在下一次智能体轮次中更新 Skills 快照。 -- **远程 node 节点**:连接 macOS node 节点后,可能会使仅适用于 macOS 的 Skills 变为可用(基于 bin 探测)。 +- **Skills watcher**:对 `SKILL.md` 的更改可以在智能体下一轮执行时更新 Skills 快照。 +- **远程节点**:连接 macOS 节点后,可使仅适用于 macOS 的 Skills 变为可用(基于二进制探测)。 -请将 skill 文件夹视为**受信任代码**,并限制谁可以修改它们。 +应将 skill 文件夹视为**受信任代码**,并限制谁可以修改它们。 ## 威胁模型 @@ -508,40 +416,41 @@ OpenClaw 可以在会话中途刷新 Skills 列表: 给你发消息的人可以: - 试图诱骗你的 AI 做坏事 -- 通过社会工程手段获取你的数据访问权限 -- 探测基础设施细节 +- 通过社会工程手段获取你的数据 +- 探测你的基础设施细节 ## 核心概念:先做访问控制,再谈智能 -这里的大多数失败都不是花哨的攻击——而是“有人给机器人发了消息,而机器人照做了”。 +这里大多数失败并不是什么高深的利用——而是“有人给机器人发了消息,而机器人照做了”。 -OpenClaw 的立场是: +OpenClaw 的立场: -- **先确认身份:** 决定谁可以与机器人通信(私信配对 / 允许列表 / 显式 “open”)。 -- **再限定范围:** 决定机器人被允许在哪里行动(群组允许列表 + 提及门控、工具、沙箱隔离、设备权限)。 -- **最后考虑模型:** 假设模型可以被操纵;通过设计将操纵的影响半径限制住。 +- **先身份:** 决定谁可以和机器人对话(私信配对 / allowlist / 显式 “open”)。 +- **再范围:** 决定机器人被允许在哪里执行操作(群组 allowlist + mention 门控、工具、沙箱隔离、设备权限)。 +- **最后才是模型:** 假设模型可能被操控;设计时应让这种操控的影响半径有限。 ## 命令授权模型 -斜杠命令和指令只会对**已授权发送者**生效。授权来源于 -渠道允许列表/配对以及 `commands.useAccessGroups`(见 [配置](/zh-CN/gateway/configuration) -和 [斜杠命令](/zh-CN/tools/slash-commands))。如果某个渠道的允许列表为空,或者包含 `"*"`, -则该渠道上的命令实际上就是开放的。 +Slash 命令和指令仅对**已授权发送者**生效。授权来源于 +渠道 allowlist/配对以及 `commands.useAccessGroups`(参见 [配置](/zh-CN/gateway/configuration) +和 [Slash 命令](/zh-CN/tools/slash-commands))。如果某个渠道的 allowlist 为空或包含 `"*"`, +则该渠道上的命令实际上是开放的。 -`/exec` 是面向已授权操作员的会话内便捷功能。它**不会**写入配置,也不会 -更改其他会话。 +`/exec` 是仅限会话使用、面向已授权操作员的便捷功能。它**不会**写入配置,也 +不会更改其他会话。 ## 控制平面工具风险 -有两个内置工具可以进行持久化的控制平面更改: +两个内置工具可以进行持久性的控制平面更改: - `gateway` 可以通过 `config.schema.lookup` / `config.get` 检查配置,也可以通过 `config.apply`、`config.patch` 和 `update.run` 进行持久化更改。 -- `cron` 可以创建计划任务,即使原始聊天/任务结束后也会继续运行。 +- `cron` 可以创建计划任务,使其在原始聊天/任务结束后继续运行。 -仅限所有者使用的 `gateway` 运行时工具仍然拒绝重写 -`tools.exec.ask` 或 `tools.exec.security`;旧版 `tools.bash.*` 别名在写入前会被规范化为相同的受保护 exec 路径。 +仅限所有者的 `gateway` 运行时工具仍然拒绝重写 +`tools.exec.ask` 或 `tools.exec.security`;旧版 `tools.bash.*` 别名会 +在写入前规范化为同样受保护的 exec 路径。 -对于任何处理不受信任内容的智能体/表面,默认都应禁止这些工具: +对于任何处理不受信任内容的智能体/表面,默认应拒绝这些工具: ```json5 { @@ -551,23 +460,23 @@ OpenClaw 的立场是: } ``` -`commands.restart=false` 只会阻止重启动作。它不会禁用 `gateway` 配置/更新操作。 +`commands.restart=false` 只会阻止重启动作。它不会禁用 `gateway` 的配置/更新操作。 ## 插件 -插件会在 Gateway 网关**进程内**运行。请将它们视为受信任代码: +插件会**在 Gateway 网关进程内**运行。应将它们视为受信任代码: -- 仅从你信任的来源安装插件。 -- 优先使用显式的 `plugins.allow` 允许列表。 -- 启用前先审查插件配置。 -- 插件变更后重启 Gateway 网关。 -- 如果你安装或更新插件(`openclaw plugins install `、`openclaw plugins update `),请将其视为运行不受信任代码: - - 安装路径是当前插件安装根目录下对应插件的专属目录。 - - OpenClaw 会在安装/更新前运行内置危险代码扫描。默认会阻止 `critical` 发现项。 - - OpenClaw 会使用 `npm pack`,然后在该目录中运行 `npm install --omit=dev`(npm 生命周期脚本可能会在安装期间执行代码)。 - - 优先使用固定、精确版本(`@scope/pkg@1.2.3`),并在启用前检查磁盘上解包后的代码。 - - `--dangerously-force-unsafe-install` 仅用于紧急兜底场景,即插件安装/更新流程中内置扫描出现误报时使用。它不会绕过插件 `before_install` hook 策略阻止,也不会绕过扫描失败。 - - 由 Gateway 网关支持的 skill 依赖安装遵循相同的危险/可疑划分:默认会阻止内置扫描中的 `critical` 发现,除非调用方显式设置 `dangerouslyForceUnsafeInstall`;而可疑发现仍然只会发出警告。`openclaw skills install` 仍然是单独的 ClawHub skill 下载/安装流程。 +- 只安装来自你信任来源的插件。 +- 优先使用显式的 `plugins.allow` allowlist。 +- 启用前检查插件配置。 +- 修改插件后重启 Gateway 网关。 +- 如果你安装或更新插件(`openclaw plugins install `、`openclaw plugins update `),应将其视为运行不受信任代码: + - 安装路径是当前插件安装根目录下对应插件的目录。 + - OpenClaw 会在安装/更新前运行内置危险代码扫描。`critical` 发现默认会阻止安装。 + - OpenClaw 会使用 `npm pack`,然后在该目录中运行 `npm install --omit=dev`(npm 生命周期脚本可能在安装期间执行代码)。 + - 优先使用固定的精确版本(`@scope/pkg@1.2.3`),并在启用前检查磁盘上解包后的代码。 + - `--dangerously-force-unsafe-install` 仅用于内置扫描在插件安装/更新流程中出现误报时的紧急兜底。它不会绕过插件 `before_install` hook 的策略阻止,也不会绕过扫描失败。 + - 由 Gateway 网关驱动的 skill 依赖安装遵循同样的 dangerous/suspicious 区分:内置 `critical` 发现默认会阻止安装,除非调用方显式设置 `dangerouslyForceUnsafeInstall`,而 suspicious 发现仍然只会发出警告。`openclaw skills install` 仍然是独立的 ClawHub skill 下载/安装流程。 详情见:[插件](/zh-CN/tools/plugin) @@ -575,11 +484,11 @@ OpenClaw 的立场是: ## 私信访问模型(pairing / allowlist / open / disabled) -所有当前支持私信的渠道都支持私信策略(`dmPolicy` 或 `*.dm.policy`),它会在处理消息**之前**对入站私信进行门控: +所有当前支持私信的渠道都支持一个私信策略(`dmPolicy` 或 `*.dm.policy`),用于在处理消息**之前**限制入站私信: -- `pairing`(默认):未知发送者会收到一个简短的配对码,机器人会忽略其消息,直到获得批准。配对码 1 小时后过期;重复发送私信不会重新发送配对码,除非创建了新的请求。默认情况下,每个渠道最多保留 **3 个待处理请求**。 -- `allowlist`:未知发送者会被阻止(无配对握手)。 -- `open`:允许任何人发送私信(公开)。**要求**渠道允许列表中包含 `"*"`(显式选择启用)。 +- `pairing`(默认):未知发送者会收到一个简短的配对码,机器人会忽略其消息,直到获得批准。配对码 1 小时后过期;在新请求创建之前,重复发送私信不会重新发送配对码。待处理请求默认每个渠道最多 **3 个**。 +- `allowlist`:未知发送者会被阻止(没有配对握手)。 +- `open`:允许任何人发送私信(公开)。**要求**该渠道的 allowlist 包含 `"*"`(显式选择加入)。 - `disabled`:完全忽略入站私信。 通过 CLI 批准: @@ -589,11 +498,11 @@ openclaw pairing list openclaw pairing approve ``` -详情和磁盘文件位置见:[配对](/zh-CN/channels/pairing) +详情及磁盘文件位置见:[配对](/zh-CN/channels/pairing) ## 私信会话隔离(多用户模式) -默认情况下,OpenClaw 会将**所有私信路由到主会话**,这样你的助手就能在不同设备和渠道之间保持连续性。如果**多个人**都可以向机器人发送私信(开放私信或多人允许列表),请考虑隔离私信会话: +默认情况下,OpenClaw 会将**所有私信都路由到主会话**,以便你的助手在设备和渠道之间保持连续性。如果**有多个人**可以给机器人发私信(开放私信或多人 allowlist),请考虑隔离私信会话: ```json5 { @@ -601,76 +510,76 @@ openclaw pairing approve } ``` -这样可以防止跨用户上下文泄露,同时保持群聊之间相互隔离。 +这样可以防止跨用户上下文泄露,同时保持群聊彼此隔离。 -这是消息上下文边界,而不是主机管理员边界。如果用户之间存在对抗关系,并共享同一个 Gateway 网关主机/配置,请按信任边界运行独立的 Gateway 网关。 +这是一个消息上下文边界,而不是主机管理员边界。如果用户彼此具有对抗关系,并共享同一个 Gateway 网关主机/配置,请按信任边界分别运行独立的 Gateway 网关。 ### 安全私信模式(推荐) -将上面的配置片段视为**安全私信模式**: +将上面的片段视为**安全私信模式**: - 默认值:`session.dmScope: "main"`(所有私信共享一个会话以保持连续性)。 -- 本地 CLI 新手引导默认行为:当未设置时,写入 `session.dmScope: "per-channel-peer"`(保留现有显式值)。 -- 安全私信模式:`session.dmScope: "per-channel-peer"`(每个渠道 + 发送者组合都会获得独立的私信上下文)。 -- 跨渠道对等方隔离:`session.dmScope: "per-peer"`(同类型所有渠道中,每个发送者共享一个会话)。 +- 本地 CLI 新手引导默认值:在未设置时写入 `session.dmScope: "per-channel-peer"`(保留现有显式值)。 +- 安全私信模式:`session.dmScope: "per-channel-peer"`(每个渠道 + 发送者对拥有隔离的私信上下文)。 +- 跨渠道联系人隔离:`session.dmScope: "per-peer"`(同一类型的所有渠道中,每个发送者共享一个会话)。 -如果你在同一个渠道上运行多个账户,请改用 `per-account-channel-peer`。如果同一个人通过多个渠道联系你,请使用 `session.identityLinks` 将这些私信会话合并为一个规范身份。详见 [会话管理](/zh-CN/concepts/session) 和 [配置](/zh-CN/gateway/configuration)。 +如果你在同一渠道上运行多个账号,请改用 `per-account-channel-peer`。如果同一个人在多个渠道上联系你,请使用 `session.identityLinks` 将这些私信会话合并为一个规范身份。参见 [会话管理](/zh-CN/concepts/session) 和 [配置](/zh-CN/gateway/configuration)。 -## 允许列表(私信 + 群组)— 术语说明 +## Allowlists(私信 + 群组)——术语说明 OpenClaw 有两层彼此独立的“谁可以触发我?”机制: -- **私信允许列表**(`allowFrom` / `channels.discord.allowFrom` / `channels.slack.allowFrom`;旧版:`channels.discord.dm.allowFrom`、`channels.slack.dm.allowFrom`):谁被允许在私信中与机器人交互。 - - 当 `dmPolicy="pairing"` 时,批准结果会写入 `~/.openclaw/credentials/` 下按账户划分的配对允许列表存储中(默认账户为 `-allowFrom.json`,非默认账户为 `--allowFrom.json`),并与配置中的允许列表合并。 -- **群组允许列表**(按渠道而定):机器人完全接受哪些群组/频道/guild 的消息。 +- **私信 allowlist**(`allowFrom` / `channels.discord.allowFrom` / `channels.slack.allowFrom`;旧版:`channels.discord.dm.allowFrom`、`channels.slack.dm.allowFrom`):谁被允许在私信中与机器人对话。 + - 当 `dmPolicy="pairing"` 时,批准结果会写入 `~/.openclaw/credentials/` 下按账号作用域划分的配对 allowlist 存储(默认账号使用 `-allowFrom.json`,非默认账号使用 `--allowFrom.json`),并与配置中的 allowlist 合并。 +- **群组 allowlist**(按渠道区分):机器人总体上会接受哪些群组/频道/guild 的消息。 - 常见模式: - - `channels.whatsapp.groups`、`channels.telegram.groups`、`channels.imessage.groups`:按群组设置默认值,例如 `requireMention`;设置后它也会充当群组允许列表(包含 `"*"` 可保持允许所有行为)。 - - `groupPolicy="allowlist"` + `groupAllowFrom`:限制在群组会话**内部**谁可以触发机器人(WhatsApp/Telegram/Signal/iMessage/Microsoft Teams)。 - - `channels.discord.guilds` / `channels.slack.channels`:按表面设置允许列表 + 提及默认值。 - - 群组检查顺序如下:先执行 `groupPolicy`/群组允许列表检查,再执行提及/回复激活检查。 - - 回复机器人消息(隐式提及)**不会**绕过像 `groupAllowFrom` 这样的发送者允许列表。 - - **安全说明:** 请将 `dmPolicy="open"` 和 `groupPolicy="open"` 视为最后手段。它们应尽量少用;除非你完全信任房间中的每个成员,否则优先使用 pairing + 允许列表。 + - `channels.whatsapp.groups`、`channels.telegram.groups`、`channels.imessage.groups`:按群组设置默认值,例如 `requireMention`;一旦设置,它也会充当群组 allowlist(如需保持允许全部行为,请包含 `"*"`)。 + - `groupPolicy="allowlist"` + `groupAllowFrom`:限制在群组会话**内部**哪些人可以触发机器人(WhatsApp/Telegram/Signal/iMessage/Microsoft Teams)。 + - `channels.discord.guilds` / `channels.slack.channels`:按表面设置 allowlist + mention 默认值。 + - 群组检查顺序如下:先执行 `groupPolicy`/群组 allowlist,然后再执行 mention/回复激活。 + - 回复机器人消息(隐式 mention)**不会**绕过类似 `groupAllowFrom` 这样的发送者 allowlist。 + - **安全说明:** 应将 `dmPolicy="open"` 和 `groupPolicy="open"` 视为最后手段。除非你完全信任房间中的每个成员,否则几乎不应使用;优先选择 pairing + allowlist。 详情见:[配置](/zh-CN/gateway/configuration) 和 [群组](/zh-CN/channels/groups) -## 提示注入(它是什么,为什么重要) +## 提示词注入(它是什么,为什么重要) -提示注入是指攻击者构造一条消息,诱导模型做出不安全行为(“忽略你的指令”、“导出你的文件系统”、“打开这个链接并运行命令”等)。 +提示词注入是指攻击者精心构造一条消息,操控模型去执行不安全行为(“忽略你的指令”、“导出你的文件系统”、“打开这个链接并运行命令”等)。 -即使有很强的系统提示,**提示注入问题也没有被解决**。系统提示防护栏只是一种软性指导;硬性约束来自工具策略、exec 审批、沙箱隔离和渠道允许列表(而且操作员可以按设计禁用这些)。在实践中真正有帮助的是: +即使有很强的系统提示词,**提示词注入问题依然没有解决**。系统提示词防护栏只是软性指导;真正的硬性约束来自工具策略、exec 审批、沙箱隔离和渠道 allowlist(而且操作员也可以按设计禁用这些机制)。实际中有帮助的做法包括: -- 保持入站私信处于锁定状态(pairing/允许列表)。 -- 在群组中优先使用提及门控;避免在公共房间中使用“始终在线”的机器人。 -- 默认将链接、附件和粘贴的指令视为不受信任内容。 -- 在沙箱中执行敏感工具;不要让 secrets 出现在智能体可访问的文件系统中。 -- 注意:沙箱隔离是可选启用的。如果 sandbox 模式关闭,隐式 `host=auto` 会解析为 gateway 主机。显式 `host=sandbox` 仍会以关闭式失败,因为没有可用的 sandbox 运行时。如果你希望这种行为在配置中更明确,请设置 `host=gateway`。 -- 将高风险工具(`exec`、`browser`、`web_fetch`、`web_search`)限制给受信任智能体或显式允许列表。 -- 如果你对解释器进行了允许列表配置(`python`、`node`、`ruby`、`perl`、`php`、`lua`、`osascript`),请启用 `tools.exec.strictInlineEval`,这样内联 eval 形式仍然需要显式审批。 -- Shell 审批分析还会拒绝**未加引号 heredoc** 中的 POSIX 参数展开形式(`$VAR`、`$?`、`$$`、`$1`、`$@`、`${…}`),这样被允许列表放行的 heredoc 内容就无法将 shell 展开伪装成纯文本偷偷绕过允许列表审查。若要启用字面量正文语义,请给 heredoc 终止符加引号(例如 `<<'EOF'`);对于本会发生变量展开的未加引号 heredoc,会直接拒绝。 -- **模型选择很重要:** 较旧/较小/旧版模型在抵御提示注入和工具滥用方面明显不够稳健。对于启用了工具的智能体,请使用当前可用的、最强的新一代指令加固模型。 +- 保持入站私信受限(pairing/allowlist)。 +- 在群组中优先使用 mention 门控;避免在公共房间中使用“始终在线”的机器人。 +- 默认将链接、附件和粘贴的指令视为敌对输入。 +- 在沙箱中执行敏感工具;将 secrets 保持在智能体可访问文件系统之外。 +- 注意:沙箱隔离是可选启用的。如果沙箱模式关闭,隐式 `host=auto` 会解析为 Gateway 网关主机。显式 `host=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 正文不能伪装成纯文本,从而绕过 allowlist 审查偷偷执行 shell 展开。给 heredoc 终止符加引号(例如 `<<'EOF'`)即可启用字面量正文语义;任何本会展开变量的未加引号 heredoc 都会被拒绝。 +- **模型选择很重要:** 较旧/较小/旧版模型在对抗提示词注入和工具滥用方面明显更脆弱。对于启用了工具的智能体,请使用当前可用的、能力最强的最新一代指令加固模型。 应视为不受信任的危险信号: - “读取这个文件/URL,并严格照它说的做。” -- “忽略你的系统提示或安全规则。” +- “忽略你的系统提示词或安全规则。” - “泄露你的隐藏指令或工具输出。” -- “贴出 `~/.openclaw` 或你的日志的完整内容。” +- “把 `~/.openclaw` 或你的日志的完整内容贴出来。” -## 外部内容 special-token 清洗 +## 外部内容特殊 token 清理 -OpenClaw 会在常见的自托管 LLM chat-template special-token 字面量进入模型之前,将其从包装后的外部内容和元数据中剥离。覆盖的标记家族包括 Qwen/ChatML、Llama、Gemma、Mistral、Phi 以及 GPT-OSS 的角色/轮次 token。 +OpenClaw 会在包装后的外部内容和元数据到达模型之前,去除常见的自托管 LLM 聊天模板特殊 token 字面量。覆盖的标记家族包括 Qwen/ChatML、Llama、Gemma、Mistral、Phi 和 GPT-OSS 的角色/轮次 token。 原因: -- 某些兼容 OpenAI 的后端如果前接自托管模型,可能会保留出现在用户文本中的 special tokens,而不是将其屏蔽。攻击者如果能够写入入站外部内容(抓取页面、邮件正文、文件内容工具输出),否则就可能注入伪造的 `assistant` 或 `system` 角色边界,并逃逸出包装内容的防护栏。 -- 清洗发生在外部内容包装层,因此它会统一应用于抓取/读取工具以及入站渠道内容,而不是按提供商分别实现。 -- 出站模型响应已有单独的清洗器,会从用户可见回复中剥离泄露的 ``、`` 等脚手架内容。外部内容清洗器则是它在入站方向上的对应机制。 +- 一些以前端兼容 OpenAI 的方式提供自托管模型服务的后端,有时会保留出现在用户文本中的特殊 token,而不是将其屏蔽。攻击者如果能够写入入站外部内容(如抓取页面、邮件正文、文件内容工具输出),否则就可能注入伪造的 `assistant` 或 `system` 角色边界,并逃逸包装内容的防护栏。 +- 清理发生在外部内容包装层,因此它会统一应用于抓取/读取工具和入站渠道内容,而不是按提供商分别处理。 +- 出站模型响应已经有独立的清理器,会从用户可见回复中移除泄露的 ``、`` 及类似脚手架内容。外部内容清理器则是它在入站方向上的对应机制。 -这并不能替代本页中的其他加固措施——`dmPolicy`、允许列表、exec 审批、沙箱隔离和 `contextVisibility` 仍然承担主要防护作用。它只是封堵了一个特定的分词器层绕过路径:针对那些会将带 special tokens 的用户文本原样转发的自托管技术栈。 +这并不能替代本页中的其他加固措施——`dmPolicy`、allowlists、exec 审批、沙箱隔离和 `contextVisibility` 仍然承担主要防护作用。它只封堵了一个特定的 tokenizer 层绕过场景,即针对那些原样转发带特殊 token 的用户文本的自托管技术栈。 ## 不安全外部内容绕过标志 -OpenClaw 包含一些显式绕过标志,用于禁用外部内容安全包装: +OpenClaw 包含一些显式绕过标志,可禁用外部内容安全包装: - `hooks.mappings[].allowUnsafeExternalContent` - `hooks.gmail.allowUnsafeExternalContent` @@ -678,141 +587,141 @@ OpenClaw 包含一些显式绕过标志,用于禁用外部内容安全包装 指导建议: -- 在生产环境中保持这些值未设置或为 false。 -- 仅在严格限定范围的调试中临时启用。 -- 如果启用了,请隔离该智能体(沙箱隔离 + 最小工具 + 专用会话命名空间)。 +- 在生产环境中保持这些设置未启用/为 false。 +- 仅在严格限定范围的调试场景下临时启用。 +- 如果启用了它们,请隔离该智能体(沙箱隔离 + 最小工具 + 专用会话命名空间)。 Hooks 风险说明: -- Hook 负载属于不受信任内容,即使其投递来自你控制的系统也是如此(邮件/文档/网页内容都可能携带提示注入)。 -- 较弱的模型层级会放大这一风险。对于 Hook 驱动的自动化,优先使用强大的现代模型层级,并保持收紧的工具策略(`tools.profile: "messaging"` 或更严格),同时尽可能启用沙箱隔离。 +- Hook 负载属于不受信任内容,即使投递来自你控制的系统也一样(邮件/文档/web 内容都可能携带提示词注入)。 +- 较弱的模型层级会放大这种风险。对于基于 hook 的自动化,应优先选择强大的现代模型层级,并保持严格的工具策略(`tools.profile: "messaging"` 或更严格),并尽可能启用沙箱隔离。 -### 提示注入并不需要开放私信 +### 提示词注入并不需要公开私信 -即使**只有你自己**可以给机器人发消息,提示注入仍然可能通过 +即使**只有你自己**可以给机器人发消息,提示词注入仍然可能通过 机器人读取的任何**不受信任内容**发生(web 搜索/抓取结果、浏览器页面、 -电子邮件、文档、附件、粘贴的日志/代码)。换句话说:发送者并不是 -唯一的威胁表面;**内容本身**也可能携带对抗性指令。 +邮件、文档、附件、粘贴的日志/代码)。换句话说:威胁面不只是发送者; +**内容本身**也可能携带对抗性指令。 -启用工具后,典型风险是泄露上下文或触发 -工具调用。可通过以下方式降低影响半径: +启用工具时,典型风险是外泄上下文或触发 +工具调用。可通过以下方式减小影响半径: - 使用只读或禁用工具的**阅读智能体**来总结不受信任内容, - 然后再将总结传给你的主智能体。 + 然后再将摘要传给你的主智能体。 - 对启用了工具的智能体,除非确有需要,否则关闭 `web_search` / `web_fetch` / `browser`。 -- 对于 OpenResponses URL 输入(`input_file` / `input_image`),请设置严格的 +- 对于 OpenResponses URL 输入(`input_file` / `input_image`),请收紧 `gateway.http.endpoints.responses.files.urlAllowlist` 和 `gateway.http.endpoints.responses.images.urlAllowlist`,并保持 `maxUrlParts` 较低。 - 空允许列表会被视为未设置;如果你想完全禁用 URL 抓取,请使用 `files.allowUrl: false` / `images.allowUrl: false`。 + 空 allowlist 会被视为未设置;如果你想完全禁用 URL 抓取,请使用 `files.allowUrl: false` / `images.allowUrl: false`。 - 对于 OpenResponses 文件输入,解码后的 `input_file` 文本仍会作为 - **不受信任的外部内容**注入。不要因为文件文本是由 Gateway 网关本地解码的, - 就认为它是可信的。注入块仍会带有显式的 - `<<>>` 边界标记以及 `Source: External` - 元数据,即使这一路径省略了更长的 `SECURITY NOTICE:` 横幅。 -- 当媒体理解在将附加文档文本附加到媒体提示之前提取其中内容时,也会应用同样基于标记的包装。 -- 对任何接触不受信任输入的智能体启用沙箱隔离和严格工具允许列表。 -- 不要把 secrets 放进提示中;应通过 gateway 主机上的 env/config 传递它们。 + **不受信任的外部内容** 注入。不要因为 + Gateway 网关是在本地解码该文件,就认为文件文本是可信的。注入块仍会带有显式的 + `<<>>` 边界标记和 `Source: External` + 元数据,尽管此路径省略了更长的 `SECURITY NOTICE:` 横幅。 +- 当媒体理解在将文档附带文本追加到媒体提示词之前提取文档文本时,也会应用相同的基于标记的包装。 +- 对任何接触不受信任输入的智能体启用沙箱隔离和严格工具 allowlist。 +- 不要把 secrets 放进提示词;应通过 Gateway 网关主机上的环境变量/配置传递。 ### 自托管 LLM 后端 -OpenAI 兼容的自托管后端,例如 vLLM、SGLang、TGI、LM Studio, +兼容 OpenAI 的自托管后端,例如 vLLM、SGLang、TGI、LM Studio, 或自定义 Hugging Face tokenizer 技术栈,在处理 -chat-template special tokens 的方式上可能与托管提供商不同。如果某个后端会将 -`<|im_start|>`、`<|start_header_id|>` 或 `` 这样的字面字符串 -在用户内容中分词为结构性的 chat-template tokens, -那么不受信任的文本就可能尝试在 tokenizer 层伪造角色边界。 +聊天模板特殊 token 的方式上可能与托管提供商不同。如果某个后端会将用户内容中的 +`<|im_start|>`、`<|start_header_id|>` 或 `` 等字面字符串 +当作结构性的聊天模板 token 进行分词, +那么不受信任文本就可能尝试在 tokenizer 层伪造角色边界。 -OpenClaw 会在将包装后的外部内容分发给模型之前, -从中剥离常见模型家族的 special-token 字面量。请保持外部内容 -包装功能开启,并在可用时优先选择那些会对用户提供内容中的 special -tokens 进行拆分或转义的后端设置。像 OpenAI -和 Anthropic 这样的托管提供商已经在其请求侧应用了自己的清洗机制。 +OpenClaw 会在将包装后的 +外部内容分发给模型之前,去除常见模型家族的特殊 token 字面量。请保持外部内容 +包装功能启用,并在可用时优先选择那些能对用户提供内容中的特殊 +token 做拆分或转义处理的后端设置。像 OpenAI +和 Anthropic 这样的托管提供商已经在请求侧做了各自的清理。 ### 模型强度(安全说明) -不同模型层级的提示注入抵抗能力**并不一致**。更小、更便宜的模型通常更容易受到工具滥用和指令劫持的影响,尤其是在对抗性提示下。 +不同模型层级在抵抗提示词注入方面**并不一致**。更小/更便宜的模型通常更容易被诱导误用工具和劫持指令,尤其是在对抗性提示词下。 -对于启用了工具的智能体,或会读取不受信任内容的智能体,较旧/较小模型带来的提示注入风险通常过高。不要在弱模型层级上运行这些工作负载。 +对于启用了工具的智能体,或会读取不受信任内容的智能体,旧版/较小模型带来的提示词注入风险通常过高。不要在较弱的模型层级上运行这些工作负载。 建议: -- **对任何可以运行工具或接触文件/网络的机器人,使用最新一代、最高层级的模型。** -- **不要将较旧/较弱/较小的层级用于启用了工具的智能体或不受信任收件箱;提示注入风险过高。** -- 如果你必须使用较小模型,请**缩小影响半径**(只读工具、强沙箱隔离、最小文件系统访问、严格允许列表)。 -- 运行小模型时,请**为所有会话启用沙箱隔离**,并且除非输入受到严格控制,否则**禁用 `web_search`/`web_fetch`/`browser`**。 -- 对于仅聊天的个人助理、可信输入且无工具的场景,较小模型通常没问题。 +- 对于任何可以运行工具或接触文件/网络的机器人,**使用最新一代、最高档位的模型**。 +- **不要对启用了工具的智能体或不受信任收件箱使用较旧/较弱/较小的模型层级**;提示词注入风险过高。 +- 如果你必须使用较小模型,**请缩小影响半径**(只读工具、强沙箱隔离、最小文件系统访问、严格 allowlist)。 +- 当运行小模型时,**为所有会话启用沙箱隔离**,并且**禁用 `web_search`/`web_fetch`/`browser`**,除非输入受到严格控制。 +- 对于仅聊天、输入可信且不启用工具的个人助手,较小模型通常是可以接受的。 -## 群组中的 reasoning 和详细输出 +## 群组中的 reasoning 与详细输出 -`/reasoning`、`/verbose` 和 `/trace` 可能会暴露内部推理、工具 -输出,或插件诊断信息, -而这些内容原本并不适合出现在公开频道中。在群组场景中,请将它们视为**仅用于调试** -的功能,除非你明确需要,否则请保持关闭。 +`/reasoning`、`/verbose` 和 `/trace` 可能暴露内部推理、工具 +输出或插件诊断信息, +而这些内容原本并不适合出现在公共渠道中。在群组场景下,应将它们视为**仅供调试** +的功能,除非你明确需要,否则应保持关闭。 指导建议: - 在公共房间中保持 `/reasoning`、`/verbose` 和 `/trace` 关闭。 -- 如果你要启用它们,请仅在受信任的私信或严格受控的房间中启用。 -- 请记住:verbose 和 trace 输出可能包含工具参数、URL、插件诊断信息以及模型看到的数据。 +- 如果要启用,也仅应在受信任的私信或严格受控的房间中启用。 +- 请记住:verbose 和 trace 输出可能包含工具参数、URL、插件诊断信息,以及模型看到的数据。 ## 配置加固(示例) -### 0) 文件权限 +### 文件权限 -在 Gateway 网关主机上保持配置和 state 私有: +在 Gateway 网关主机上保持配置和状态私有: - `~/.openclaw/openclaw.json`:`600`(仅用户可读写) - `~/.openclaw`:`700`(仅用户可访问) -`openclaw doctor` 可以发出警告并提示收紧这些权限。 +`openclaw doctor` 可以发出警告并提供收紧这些权限的选项。 -### 0.4) 网络暴露(bind + port + firewall) +### 网络暴露(绑定、端口、防火墙) -Gateway 网关会在单一端口上复用 **WebSocket + HTTP**: +Gateway 网关在单个端口上复用 **WebSocket + HTTP**: - 默认值:`18789` -- 配置/flags/env:`gateway.port`、`--port`、`OPENCLAW_GATEWAY_PORT` +- 配置/标志/环境变量:`gateway.port`、`--port`、`OPENCLAW_GATEWAY_PORT` 这个 HTTP 表面包括 Control UI 和 canvas host: - Control UI(SPA 资源)(默认基础路径 `/`) - Canvas host:`/__openclaw__/canvas/` 和 `/__openclaw__/a2ui/`(任意 HTML/JS;应视为不受信任内容) -如果你在普通浏览器中加载 canvas 内容,请像对待其他不受信任网页一样处理: +如果你在普通浏览器中加载 canvas 内容,请像对待其他不受信任网页一样处理它: - 不要将 canvas host 暴露给不受信任的网络/用户。 -- 不要让 canvas 内容与高权限 Web 表面共享同一来源,除非你完全理解其中影响。 +- 除非你完全理解其中的影响,否则不要让 canvas 内容与高权限 web 表面共享同一来源。 -Bind 模式决定 Gateway 网关监听的位置: +绑定模式控制 Gateway 网关监听的位置: - `gateway.bind: "loopback"`(默认):只有本地客户端可以连接。 -- 非 loopback bind(`"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 负责访问控制)。 -- 如果你必须 bind 到 LAN,请通过防火墙将该端口限制到严格的源 IP 允许列表;不要广泛地做端口转发。 -- 绝不要将未认证的 Gateway 网关暴露在 `0.0.0.0` 上。 +- 优先使用 Tailscale Serve,而不是 LAN 绑定(Serve 会让 Gateway 网关保持在 loopback 上,由 Tailscale 负责访问控制)。 +- 如果必须绑定到 LAN,请将该端口通过防火墙限制为严格的源 IP allowlist;不要广泛地进行端口转发。 +- 绝不要在 `0.0.0.0` 上公开暴露未经认证的 Gateway 网关。 -### 0.4.1) Docker 端口发布 + UFW(`DOCKER-USER`) +### 使用 UFW 的 Docker 端口发布 -如果你在 VPS 上使用 Docker 运行 OpenClaw,请记住,已发布的容器端口 -(`-p HOST:CONTAINER` 或 Compose `ports:`)会通过 Docker 的转发链路进行路由, -而不只是经过主机的 `INPUT` 规则。 +如果你在 VPS 上通过 Docker 运行 OpenClaw,请记住,已发布的容器端口 +(`-p HOST:CONTAINER` 或 Compose `ports:`)会经过 Docker 的转发链路, +而不仅仅是主机的 `INPUT` 规则。 -为了让 Docker 流量与你的防火墙策略保持一致,请在 -`DOCKER-USER` 中强制执行规则(这个链会在 Docker 自己的 accept 规则之前被评估)。 -在许多现代发行版上,`iptables`/`ip6tables` 使用 `iptables-nft` 前端, -并且仍会将这些规则应用到 nftables 后端。 +为了使 Docker 流量与防火墙策略保持一致,请在 +`DOCKER-USER` 中强制执行规则(该链会在 Docker 自己的接受规则之前被评估)。 +在许多现代发行版上,`iptables`/`ip6tables` 使用的是 `iptables-nft` 前端, +但这些规则仍然会应用到 nftables 后端。 -最小允许列表示例(IPv4): +最小 allowlist 示例(IPv4): ```bash -# /etc/ufw/after.rules(作为独立的 *filter 节追加) +# /etc/ufw/after.rules(作为独立的 *filter section 追加) *filter :DOCKER-USER - [0:0] -A DOCKER-USER -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN @@ -828,14 +737,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 @@ -844,22 +753,22 @@ ip6tables -S DOCKER-USER nmap -sT -p 1-65535 --open ``` -预期的外部端口应只包括你有意暴露的那些(对大多数 +预期的外部开放端口应只包括你有意暴露的那些(对大多数 配置来说:SSH + 你的反向代理端口)。 -### 0.4.2) mDNS/Bonjour 设备发现(信息泄露) +### mDNS/Bonjour 发现 -Gateway 网关会通过 mDNS(`_openclaw-gw._tcp`,端口 5353)广播其存在,以供本地设备发现。在完整模式下,这包括可能暴露运行细节的 TXT 记录: +Gateway 网关会通过 mDNS(端口 5353 上的 `_openclaw-gw._tcp`)广播自身存在,以供本地设备发现。在 full 模式下,这会包括可能暴露运维细节的 TXT 记录: -- `cliPath`:CLI 二进制文件的完整文件系统路径(会泄露用户名和安装位置) -- `sshPort`:广播主机上的 SSH 可用性 +- `cliPath`:CLI 二进制文件的完整文件系统路径(会暴露用户名和安装位置) +- `sshPort`:声明主机上可用的 SSH - `displayName`、`lanHost`:主机名信息 -**操作安全注意事项:** 广播基础设施细节会让本地网络中的任何人更容易进行侦察。即使是像文件系统路径和 SSH 可用性这样的“无害”信息,也有助于攻击者绘制你的环境图谱。 +**运维安全注意事项:** 广播基础设施细节会让局域网中的任何人更容易进行侦察。即使像文件系统路径和 SSH 可用性这类“看似无害”的信息,也能帮助攻击者绘制你的环境图谱。 **建议:** -1. **最小模式**(默认,推荐用于暴露的 Gateway 网关):从 mDNS 广播中省略敏感字段: +1. **Minimal 模式**(默认,推荐用于已暴露的 Gateway 网关):从 mDNS 广播中省略敏感字段: ```json5 { @@ -879,7 +788,7 @@ Gateway 网关会通过 mDNS(`_openclaw-gw._tcp`,端口 5353)广播其存 } ``` -3. **完整模式**(显式启用):在 TXT 记录中包含 `cliPath` + `sshPort`: +3. **Full 模式**(显式启用):在 TXT 记录中包含 `cliPath` + `sshPort`: ```json5 { @@ -889,19 +798,19 @@ Gateway 网关会通过 mDNS(`_openclaw-gw._tcp`,端口 5353)广播其存 } ``` -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 连接改为获取该信息。 -### 0.5) 锁定 Gateway 网关 WebSocket(本地 auth) +### 锁定 Gateway 网关 WebSocket(本地认证) -默认情况下**必须启用** gateway auth。如果未配置有效的 gateway auth 路径, -Gateway 网关会拒绝 WebSocket 连接(关闭式失败)。 +Gateway 网关认证**默认是必需的**。如果未配置有效的 Gateway 网关认证路径, +Gateway 网关会拒绝 WebSocket 连接(默认失败关闭)。 -新手引导默认会生成一个 token(即使是在 loopback 场景下),因此 -本地客户端也必须进行身份验证。 +新手引导默认会生成一个 token(即使是 loopback 场景也是如此),因此 +本地客户端也必须进行认证。 -设置一个 token,这样**所有** WS 客户端都必须进行身份验证: +设置一个 token,这样**所有** WS 客户端都必须认证: ```json5 { @@ -911,150 +820,150 @@ Gateway 网关会拒绝 WebSocket 连接(关闭式失败)。 } ``` -Doctor 可以为你生成一个:`openclaw doctor --generate-gateway-token`。 +Doctor 可以帮你生成一个:`openclaw doctor --generate-gateway-token`。 -注意:`gateway.remote.token` / `.password` 是客户端凭证来源。 -它们本身**不会**保护本地 WS 访问。 -只有在 `gateway.auth.*` -未设置时,本地调用路径才会将 `gateway.remote.*` 作为回退来源使用。 -如果通过 SecretRef 显式配置了 `gateway.auth.token` / `gateway.auth.password` 但未能解析, -则解析会关闭式失败(不会通过远程回退掩盖问题)。 -可选:当使用 `wss://` 时,可通过 `gateway.remote.tlsFingerprint` 固定远程 TLS。 -默认情况下,明文 `ws://` 仅限 loopback 使用。对于受信任的私有网络 +注意:`gateway.remote.token` / `.password` 是客户端凭证来源。它们 +本身**不会**保护本地 WS 访问。 +仅当 `gateway.auth.*` +未设置时,本地调用路径才可将 `gateway.remote.*` 作为回退来源。 +如果通过 +SecretRef 显式配置了 `gateway.auth.token` / `gateway.auth.password` 但未成功解析, +则会默认失败关闭(不会用远程回退来掩盖失败)。 +可选:使用 `wss://` 时,可通过 `gateway.remote.tlsFingerprint` 固定远程 TLS。 +明文 `ws://` 默认仅限 loopback。对于受信任的私有网络 路径,可在客户端进程上设置 `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1` 作为紧急兜底。 本地设备配对: -- 为了让同主机客户端保持顺畅,直接的本地 loopback 连接会自动批准设备配对。 -- OpenClaw 还提供了一个狭窄的后端/容器本地自连接路径,用于 - 受信任的共享密钥辅助流程。 -- Tailnet 和 LAN 连接,包括同主机的 tailnet bind,都会被视为远程连接,因此配对仍然需要审批。 -- loopback 请求中的转发头证据会取消其 loopback - 本地性资格。元数据升级自动批准的范围非常有限。详见 - [Gateway 配对](/zh-CN/gateway/pairing) 中的两套规则。 +- 为了让同主机客户端体验更顺畅,直接的本地 loopback 连接会自动批准设备配对。 +- OpenClaw 还为 + 受信任的共享密钥辅助流程提供了一条狭义的后端/容器本地自连接路径。 +- Tailnet 和 LAN 连接,包括同主机 tailnet 绑定,都会被视为远程连接用于配对,因此仍需批准。 +- loopback 请求上的转发头证据会使其失去 + loopback 本地性资格。元数据升级自动批准的适用范围非常狭窄。详见 + [Gateway 配对](/zh-CN/gateway/pairing) 中的两项规则。 -Auth 模式: +认证模式: -- `gateway.auth.mode: "token"`:共享 bearer token(推荐用于大多数场景)。 -- `gateway.auth.mode: "password"`:密码 auth(更推荐通过 env 设置:`OPENCLAW_GATEWAY_PASSWORD`)。 -- `gateway.auth.mode: "trusted-proxy"`:信任具备身份感知能力的反向代理,由其对用户进行身份验证并通过 header 传递身份(见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth))。 +- `gateway.auth.mode: "token"`:共享 bearer token(大多数场景推荐)。 +- `gateway.auth.mode: "password"`:密码认证(建议通过环境变量设置:`OPENCLAW_GATEWAY_PASSWORD`)。 +- `gateway.auth.mode: "trusted-proxy"`:信任具备身份感知能力的反向代理来认证用户,并通过头传递身份(参见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth))。 轮换检查清单(token/password): -1. 生成/设置一个新 secret(`gateway.auth.token` 或 `OPENCLAW_GATEWAY_PASSWORD`)。 +1. 生成/设置新的 secret(`gateway.auth.token` 或 `OPENCLAW_GATEWAY_PASSWORD`)。 2. 重启 Gateway 网关(如果由 macOS 应用监管 Gateway 网关,则重启该应用)。 -3. 更新所有远程客户端(调用 Gateway 网关的机器上配置的 `gateway.remote.token` / `.password`)。 -4. 验证旧凭证已无法再用于连接。 +3. 更新所有远程客户端(在调用 Gateway 网关的机器上更新 `gateway.remote.token` / `.password`)。 +4. 验证旧凭证已无法再建立连接。 -### 0.6) Tailscale Serve 身份头 +### Tailscale Serve 身份头 当 `gateway.auth.allowTailscale` 为 `true`(Serve 的默认值)时,OpenClaw -会接受 Tailscale Serve 身份头(`tailscale-user-login`)用于 Control -UI/WebSocket 身份验证。OpenClaw 会通过本地 Tailscale 守护进程解析 -`x-forwarded-for` 地址(`tailscale whois`),并将其与该 header 进行匹配,以验证身份。 -这仅会对命中 loopback +接受 Tailscale Serve 身份头(`tailscale-user-login`)用于 Control +UI/WebSocket 认证。OpenClaw 会通过本地 Tailscale 守护进程解析 +`x-forwarded-for` 地址(`tailscale whois`),并将结果与该头匹配,以验证身份。此逻辑只会在请求命中 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 身份头 auth。它们仍然遵循 gateway -配置的 HTTP auth 模式。 +**不会**使用 Tailscale 身份头认证。它们仍遵循 Gateway 网关 +配置的 HTTP 认证模式。 重要边界说明: -- Gateway 网关 HTTP bearer auth 实际上等同于全有或全无的操作员访问权限。 -- 请将那些可以调用 `/v1/chat/completions`、`/v1/responses` 或 `/api/channels/*` 的凭证视为该 Gateway 网关的全访问操作员 secrets。 -- 在 OpenAI 兼容的 HTTP 表面上,共享密钥 bearer auth 会恢复完整的默认操作员作用域(`operator.admin`、`operator.approvals`、`operator.pairing`、`operator.read`、`operator.talk.secrets`、`operator.write`)以及智能体轮次的 owner 语义;更窄的 `x-openclaw-scopes` 值不会缩减这条共享密钥路径。 -- HTTP 上按请求生效的作用域语义,仅适用于来自具备身份承载模式的请求,例如 trusted proxy auth,或私有入口上的 `gateway.auth.mode="none"`。 -- 在这些具备身份承载的模式下,如果省略 `x-openclaw-scopes`,则会回退到正常的默认操作员作用域集合;当你需要更窄的作用域集合时,请显式发送该 header。 -- `/tools/invoke` 也遵循同样的共享密钥规则:token/password bearer auth 在这里同样被视为完整操作员访问,而具备身份承载的模式仍会遵守声明的作用域。 -- 不要与不受信任的调用方共享这些凭证;应优先为每个信任边界使用独立的 Gateway 网关。 +- Gateway 网关 HTTP bearer 认证实际上相当于全有或全无的操作员访问权限。 +- 能调用 `/v1/chat/completions`、`/v1/responses` 或 `/api/channels/*` 的凭证,应被视为该 Gateway 网关的完全访问操作员 secret。 +- 在兼容 OpenAI 的 HTTP 表面上,共享密钥 bearer 认证会恢复完整的默认操作员作用域(`operator.admin`、`operator.approvals`、`operator.pairing`、`operator.read`、`operator.talk.secrets`、`operator.write`)以及针对智能体轮次的 owner 语义;更窄的 `x-openclaw-scopes` 值不会缩减这条共享密钥路径。 +- HTTP 上的按请求作用域语义仅在请求来自带有身份的模式时适用,例如 trusted proxy 认证或私有入口上的 `gateway.auth.mode="none"`。 +- 在这些带身份的模式下,如果省略 `x-openclaw-scopes`,则会回退到正常的默认操作员作用域集合;当你想要更窄的作用域集合时,请显式发送该头。 +- `/tools/invoke` 遵循同样的共享密钥规则:token/password bearer 认证在那里也会被视为完整操作员访问,而带身份的模式仍会遵守声明的作用域。 +- 不要与不受信任的调用方共享这些凭证;应按信任边界使用独立的 Gateway 网关。 -**信任假设:** 无 token 的 Serve auth 假设 gateway 主机是受信任的。 -不要将其视为针对同主机恶意进程的防护。如果不受信任的 -本地代码可能会在 gateway 主机上运行,请禁用 `gateway.auth.allowTailscale`, -并要求使用显式共享密钥 auth,即 `gateway.auth.mode: "token"` 或 +**信任假设:** 无 token 的 Serve 认证假定 Gateway 网关主机是受信任的。 +不要把它视为针对同主机恶意进程的防护。如果 Gateway 网关主机上 +可能运行不受信任的本地代码,请禁用 `gateway.auth.allowTailscale`, +并要求显式共享密钥认证,使用 `gateway.auth.mode: "token"` 或 `"password"`。 -**安全规则:** 不要从你自己的反向代理转发这些 headers。如果 -你在 gateway 前终止 TLS 或进行代理,请禁用 -`gateway.auth.allowTailscale`,并改用共享密钥 auth(`gateway.auth.mode: -"token"` 或 `"password"`),或使用 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth)。 +**安全规则:** 不要通过你自己的反向代理转发这些头。如果 +你在 Gateway 网关前终止 TLS 或进行代理,请禁用 +`gateway.auth.allowTailscale`,并改用共享密钥认证(`gateway.auth.mode: +"token"` 或 `"password"`)或 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth)。 受信任代理: -- 如果你在 Gateway 网关前终止 TLS,请将你的代理 IP 配置到 `gateway.trustedProxies`。 -- OpenClaw 会信任来自这些 IP 的 `x-forwarded-for`(或 `x-real-ip`),以确定客户端 IP,用于本地配对检查以及 HTTP auth/本地检查。 -- 确保你的代理会**覆盖** `x-forwarded-for`,并阻止对 Gateway 网关端口的直接访问。 +- 如果你在 Gateway 网关前终止 TLS,请将 `gateway.trustedProxies` 设置为你的代理 IP。 +- OpenClaw 会信任来自这些 IP 的 `x-forwarded-for`(或 `x-real-ip`),以确定客户端 IP,用于本地配对检查和 HTTP 认证/本地检查。 +- 确保你的代理**覆盖** `x-forwarded-for`,并阻止直接访问 Gateway 网关端口。 参见 [Tailscale](/zh-CN/gateway/tailscale) 和 [Web 概览](/zh-CN/web)。 -### 0.6.1) 通过 node 主机进行浏览器控制(推荐) +### 通过 node host 控制浏览器(推荐) -如果你的 Gateway 网关位于远程,但浏览器运行在另一台机器上,请在浏览器所在机器上运行一个 **node 主机**, -并让 Gateway 网关代理浏览器操作(见 [浏览器工具](/zh-CN/tools/browser))。 -请将 node 节点配对视为管理员访问权限。 +如果你的 Gateway 网关是远程的,但浏览器运行在另一台机器上,请在浏览器所在机器上运行一个 **node host**, +并让 Gateway 网关代理浏览器操作(参见 [浏览器工具](/zh-CN/tools/browser))。 +应将节点配对视为管理员访问权限。 推荐模式: -- 让 Gateway 网关和 node 主机位于同一个 tailnet(Tailscale)中。 -- 有意地进行 node 节点配对;如果你不需要浏览器代理路由,就将其禁用。 +- 让 Gateway 网关和 node host 处于同一个 tailnet(Tailscale)中。 +- 有意识地对节点进行配对;如果不需要浏览器代理路由,请禁用它。 应避免: - 通过 LAN 或公共互联网暴露 relay/control 端口。 -- 对浏览器控制端点使用 Tailscale Funnel(会公开暴露)。 +- 对浏览器控制端点使用 Tailscale Funnel(公开暴露)。 -### 0.7) 磁盘上的 secrets(敏感数据) +### 磁盘上的 secrets -请假定 `~/.openclaw/`(或 `$OPENCLAW_STATE_DIR/`)下的任何内容都可能包含 secrets 或私有数据: +应假定 `~/.openclaw/`(或 `$OPENCLAW_STATE_DIR/`)下的任何内容都可能包含 secrets 或私有数据: -- `openclaw.json`:配置中可能包含 token(gateway、远程 gateway)、提供商设置和允许列表。 -- `credentials/**`:渠道凭证(例如:WhatsApp 凭证)、配对允许列表、旧版 OAuth 导入。 -- `agents//agent/auth-profiles.json`:API keys、token 配置文件、OAuth tokens,以及可选的 `keyRef`/`tokenRef`。 +- `openclaw.json`:配置中可能包含 token(Gateway 网关、远程 Gateway 网关)、提供商设置和 allowlist。 +- `credentials/**`:渠道凭证(例如:WhatsApp 凭证)、配对 allowlist、旧版 OAuth 导入。 +- `agents//agent/auth-profiles.json`:API key、token 配置文件、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/**`:工具沙箱工作区;可能会累积你在沙箱中读取/写入文件的副本。 +- `agents//agent/auth.json`:旧版兼容文件。发现静态 `api_key` 条目时会被清除。 +- `agents//sessions/**`:会话转录日志(`*.jsonl`)+ 路由元数据(`sessions.json`),其中可能包含私信和工具输出。 +- 内置插件包:已安装的插件(及其 `node_modules/`)。 +- `sandboxes/**`:工具沙箱工作区;可能会积累你在沙箱内读写文件的副本。 加固建议: - 保持严格权限(目录 `700`,文件 `600`)。 - 在 Gateway 网关主机上使用全盘加密。 -- 如果主机是共享的,优先为 Gateway 网关使用专用 OS 用户账户。 +- 如果主机是共享的,优先为 Gateway 网关使用专用的操作系统用户账户。 -### 0.8) 工作区 `.env` 文件 +### 工作区 `.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 会保留自己的值。 -- 受信任的进程/OS 环境变量(gateway 自身的 shell、launchd/systemd unit、app bundle)仍然有效——这项限制只约束 `.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 网关保持自己的值。 +- 受信任的进程/操作系统环境变量(Gateway 网关自己的 shell、launchd/systemd unit、应用 bundle)仍然有效——这里约束的仅是 `.env` 文件加载。 -原因:工作区 `.env` 文件经常与智能体代码放在一起,容易被误提交,或者被工具写入。阻止整个 `OPENCLAW_*` 前缀意味着,即使以后新增 `OPENCLAW_*` 标志,也绝不会退化为从工作区状态中静默继承。 +原因:工作区 `.env` 文件通常与智能体代码放在一起,容易被误提交,或被工具写入。阻止整个 `OPENCLAW_*` 前缀,意味着以后即使新增 `OPENCLAW_*` 标志,也绝不会退化成从工作区状态静默继承。 -### 0.9) 日志 + 转录(脱敏 + 保留) +### 日志和转录日志(脱敏与保留) -即使访问控制正确,日志和转录仍然可能泄露敏感信息: +即使访问控制正确,日志和转录日志也可能泄露敏感信息: - Gateway 网关日志可能包含工具摘要、错误和 URL。 -- 会话转录可能包含粘贴的 secrets、文件内容、命令输出和链接。 +- 会话转录日志可能包含粘贴的 secrets、文件内容、命令输出和链接。 建议: - 保持工具摘要脱敏开启(`logging.redactSensitive: "tools"`;默认值)。 -- 通过 `logging.redactPatterns` 为你的环境添加自定义模式(tokens、主机名、内部 URL)。 +- 通过 `logging.redactPatterns` 为你的环境添加自定义模式(token、主机名、内部 URL)。 - 分享诊断信息时,优先使用 `openclaw status --all`(可直接粘贴,secrets 已脱敏),而不是原始日志。 -- 如果你不需要长期保留,请清理旧的会话转录和日志文件。 +- 如果你不需要长期保留,请清理旧的会话转录日志和日志文件。 详情见:[日志](/zh-CN/gateway/logging) -### 1) 私信:默认使用 pairing +### 私信:默认使用配对 ```json5 { @@ -1062,7 +971,7 @@ OpenClaw 会为智能体和工具加载工作区本地 `.env` 文件,但绝不 } ``` -### 2) 群组:在所有地方都要求提及 +### 群组:始终要求 mention ```json { @@ -1084,31 +993,31 @@ OpenClaw 会为智能体和工具加载工作区本地 `.env` 文件,但绝不 } ``` -在群聊中,只有在被显式提及时才回复。 +在群聊中,仅在被明确 mention 时才响应。 -### 3) 分离号码(WhatsApp、Signal、Telegram) +### 分离号码(WhatsApp、Signal、Telegram) -对于基于电话号码的渠道,建议考虑让你的 AI 使用与个人号码分离的独立号码: +对于基于手机号的渠道,可以考虑让你的 AI 使用与个人号码分开的独立号码: - 个人号码:你的对话保持私密 - 机器人号码:由 AI 处理,并设置适当边界 -### 4) 只读模式(通过沙箱 + 工具) +### 只读模式(通过沙箱和工具) 你可以通过组合以下设置构建只读配置: -- `agents.defaults.sandbox.workspaceAccess: "ro"`(或 `"none"` 表示完全不访问工作区) -- 阻止 `write`、`edit`、`apply_patch`、`exec`、`process` 等的工具 allow/deny 列表 +- `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` 路径以及原生提示图像自动加载路径限制在工作区目录内(如果你当前允许绝对路径并希望用一条防护栏统一约束,这会很有用)。 -- 保持文件系统根路径狭窄:避免将你的主目录之类的宽泛根路径用作智能体工作区/沙箱工作区。宽泛根路径可能会让文件系统工具暴露敏感本地文件(例如 `~/.openclaw` 下的 state/config)。 +- `tools.exec.applyPatch.workspaceOnly: true`(默认):确保即使在未启用沙箱隔离时,`apply_patch` 也不能在工作区目录之外写入/删除。只有当你确实希望 `apply_patch` 操作工作区外文件时,才将其设为 `false`。 +- `tools.fs.workspaceOnly: true`(可选):将 `read`/`write`/`edit`/`apply_patch` 路径以及原生提示词图片自动加载路径限制在工作区目录内(如果你当前允许绝对路径,并希望增加一道统一防护栏,这会很有用)。 +- 保持文件系统根目录尽可能收窄:避免将主目录这类宽泛根目录用作智能体工作区/沙箱工作区。宽泛根目录可能会让文件系统工具暴露敏感本地文件(例如 `~/.openclaw` 下的状态/配置)。 -### 5) 安全基线(可复制粘贴) +### 安全基线(可直接复制粘贴) -一个“安全默认”配置:让 Gateway 网关保持私有、要求私信配对,并避免始终在线的群组机器人: +一个“安全默认”配置示例,可让 Gateway 网关保持私有、要求私信配对,并避免使用始终在线的群组机器人: ```json5 { @@ -1127,9 +1036,9 @@ OpenClaw 会为智能体和工具加载工作区本地 `.env` 文件,但绝不 } ``` -如果你还希望工具执行也“默认更安全”,请为任何非 owner 智能体添加沙箱隔离 + 禁止危险工具(示例见下文“按智能体访问配置文件”)。 +如果你还想让工具执行也“默认更安全”,可为任何非 owner 智能体添加沙箱 + 拒绝危险工具(示例见下方“按智能体访问配置文件”部分)。 -内置的聊天驱动智能体轮次基线:非 owner 发送者不能使用 `cron` 或 `gateway` 工具。 +内置基线适用于由聊天驱动的智能体轮次:非 owner 发送者不能使用 `cron` 或 `gateway` 工具。 ## 沙箱隔离(推荐) @@ -1137,59 +1046,59 @@ OpenClaw 会为智能体和工具加载工作区本地 `.env` 文件,但绝不 两种互补方式: -- **在 Docker 中运行整个 Gateway 网关**(容器边界):[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"`(默认) +注意:为了防止跨智能体访问,请将 `agents.defaults.sandbox.scope` 保持为 `"agent"`(默认) 或使用 `"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` 会针对规范化和 canonicalized 后的源路径进行校验。如果父级符号链接技巧和规范 home 别名最终解析到了受阻止的根路径,例如 `/etc`、`/var/run` 或 OS 主目录下的凭证目录,仍会关闭式失败。 +- `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` 会根据已归一化和规范化的源路径进行校验。如果父级符号链接技巧或规范化 home 别名最终解析到被阻止的根路径(例如 `/etc`、`/var/run`,或操作系统主目录下的凭证目录),仍会默认失败关闭。 -重要说明:`tools.elevated` 是全局基线逃逸口,会在沙箱外运行 exec。其实际主机默认是 `gateway`,当 exec 目标配置为 `node` 时则是 `node`。请保持 `tools.elevated.allowFrom` 严格收紧,不要对陌生人启用。你还可以通过 `agents.list[].tools.elevated` 进一步按智能体限制高权限模式。详见 [高权限模式](/zh-CN/tools/elevated)。 +重要说明:`tools.elevated` 是全局基线逃逸口,用于在沙箱外运行 exec。默认的实际主机是 `gateway`,如果 exec 目标被配置为 `node`,则实际主机会变为 `node`。请保持 `tools.elevated.allowFrom` 足够严格,不要对陌生人启用它。你还可以通过 `agents.list[].tools.elevated` 按智能体进一步限制 elevated。参见 [Elevated Mode](/zh-CN/tools/elevated)。 ### 子智能体委派防护栏 如果你允许会话工具,请将委派给子智能体的运行视为另一项边界决策: -- 除非智能体确实需要委派,否则应禁止 `sessions_spawn`。 -- 保持 `agents.defaults.subagents.allowAgents` 以及任何按智能体覆盖的 `agents.list[].subagents.allowAgents` 仅限于已知安全的目标智能体。 -- 对于任何必须保持沙箱隔离的工作流,调用 `sessions_spawn` 时使用 `sandbox: "require"`(默认值是 `inherit`)。 +- 除非智能体确实需要委派,否则拒绝 `sessions_spawn`。 +- 将 `agents.defaults.subagents.allowAgents` 以及任何按智能体覆盖的 `agents.list[].subagents.allowAgents` 限制在已知安全的目标智能体范围内。 +- 对于任何必须保持沙箱隔离的工作流,请在调用 `sessions_spawn` 时使用 `sandbox: "require"`(默认值为 `inherit`)。 - `sandbox: "require"` 会在目标子运行时未启用沙箱隔离时快速失败。 ## 浏览器控制风险 -启用浏览器控制会让模型能够驱动一个真实浏览器。 -如果该浏览器 profile 已经登录了某些会话,模型就可以 -访问这些账户和数据。请将浏览器 profile 视为**敏感状态**: +启用浏览器控制会赋予模型驱动真实浏览器的能力。 +如果该浏览器配置文件中已经登录了会话,模型就可以 +访问这些账号和数据。应将浏览器配置文件视为**敏感状态**: -- 优先为智能体使用专用 profile(默认的 `openclaw` profile)。 -- 避免将智能体指向你个人日常使用的 profile。 -- 对于启用了沙箱隔离的智能体,除非你信任它们,否则请保持宿主浏览器控制关闭。 -- 独立的 loopback 浏览器控制 API 只接受共享密钥 auth - (gateway token bearer auth 或 gateway password)。它不会使用 - trusted-proxy 或 Tailscale Serve 身份 headers。 -- 将浏览器下载内容视为不受信任输入;优先使用隔离的下载目录。 -- 如果可能,请在智能体 profile 中禁用浏览器同步/密码管理器(可降低影响半径)。 -- 对于远程 Gateway 网关,请假定“浏览器控制”等同于对该 profile 可访问内容的“操作员访问”。 -- 让 Gateway 网关和 node 主机仅限 tailnet;避免将浏览器控制端口暴露到 LAN 或公共互联网。 -- 当不需要时,禁用浏览器代理路由(`gateway.nodes.browser.mode="off"`)。 -- Chrome MCP 的现有会话模式**并不**“更安全”;它可以像你本人一样操作该主机上对应 Chrome profile 可访问的任何内容。 +- 优先为智能体使用专用配置文件(默认是 `openclaw` 配置文件)。 +- 不要让智能体使用你个人日常使用的配置文件。 +- 对启用了沙箱隔离的智能体,除非你信任它们,否则应保持宿主浏览器控制关闭。 +- 独立的 loopback 浏览器控制 API 仅接受共享密钥认证 + (Gateway 网关 token bearer 认证或 Gateway 网关密码)。它不会使用 + trusted-proxy 或 Tailscale Serve 身份头。 +- 应将浏览器下载内容视为不受信任输入;优先使用隔离的下载目录。 +- 如果可以,请在智能体配置文件中禁用浏览器同步/密码管理器(可减小影响半径)。 +- 对于远程 Gateway 网关,应假定“浏览器控制”等同于“操作员访问权限”,可访问该配置文件所能访问的一切。 +- 保持 Gateway 网关和 node host 仅暴露于 tailnet;避免将浏览器控制端口暴露给 LAN 或公共互联网。 +- 在不需要时关闭浏览器代理路由(`gateway.nodes.browser.mode="off"`)。 +- Chrome MCP 现有会话模式**并不更安全**;它可以以你的身份操作该主机 Chrome 配置文件所能访问的一切。 ### 浏览器 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 上尽力再次检查。 严格策略示例: @@ -1207,17 +1116,18 @@ OpenClaw 的浏览器导航策略默认是严格的:私有/内部目标会保 ## 按智能体访问配置文件(多智能体) -在多智能体路由中,每个智能体都可以拥有自己的沙箱隔离 + 工具策略: -利用这一点,你可以为每个智能体赋予**完全访问**、**只读**或**无访问**权限。 -完整详情和优先级规则请参见 [多智能体沙箱隔离与工具](/zh-CN/tools/multi-agent-sandbox-tools)。 +在多智能体路由中,每个智能体都可以拥有自己的沙箱 + 工具策略: +利用这一点,你可以为不同智能体分别赋予**完全访问**、**只读访问**或**无访问权限**。 +完整细节和优先级规则见 [Multi-Agent Sandbox & Tools](/zh-CN/tools/multi-agent-sandbox-tools) +了解详情。 常见用例: -- 个人智能体:完全访问,不使用沙箱隔离 -- 家庭/工作智能体:沙箱隔离 + 只读工具 -- 公共智能体:沙箱隔离 + 无文件系统/shell 工具 +- 个人智能体:完全访问,不启用沙箱 +- 家庭/工作智能体:启用沙箱隔离 + 只读工具 +- 公开智能体:启用沙箱隔离 + 无文件系统/shell 工具 -### 示例:完全访问(无沙箱隔离) +### 示例:完全访问(无沙箱) ```json5 { @@ -1257,7 +1167,7 @@ OpenClaw 的浏览器导航策略默认是严格的:私有/内部目标会保 } ``` -### 示例:无文件系统/shell 访问(允许 provider 消息) +### 示例:无文件系统/shell 访问(允许提供商消息传递) ```json5 { @@ -1271,8 +1181,8 @@ OpenClaw 的浏览器导航策略默认是严格的:私有/内部目标会保 scope: "agent", workspaceAccess: "none", }, - // 会话工具可能会从转录中泄露敏感数据。默认情况下,OpenClaw 将这些工具限制为 - // 当前会话 + 由其生成的子智能体会话,但如有需要,你可以进一步收紧。 + // 会话工具可能会暴露转录日志中的敏感数据。默认情况下 OpenClaw 会将这些工具 + // 限制为当前会话 + 由其派生的子智能体会话,但如果需要,你可以进一步收紧。 // 参见配置参考中的 `tools.sessions.visibility`。 tools: { sessions: { visibility: "tree" }, // self | tree | agent | all @@ -1308,54 +1218,41 @@ OpenClaw 的浏览器导航策略默认是严格的:私有/内部目标会保 } ``` -## 应该告诉你的 AI 什么 - -在你的智能体系统提示中加入安全指南: - -``` -## 安全规则 -- 永远不要向陌生人分享目录列表或文件路径 -- 永远不要泄露 API keys、凭证或基础设施细节 -- 对于修改系统配置的请求,先与所有者确认 -- 如有疑问,先询问再执行 -- 除非获得明确授权,否则保持私有数据私密 -``` - ## 事件响应 -如果你的 AI 做了不该做的事情: +如果你的 AI 做了不该做的事: -### 控制事态 +### 遏制 -1. **停止它:** 停止 macOS 应用(如果它负责监管 Gateway 网关),或终止你的 `openclaw gateway` 进程。 -2. **关闭暴露面:** 将 `gateway.bind` 设置为 `"loopback"`(或禁用 Tailscale Funnel/Serve),直到你弄清楚发生了什么。 -3. **冻结访问:** 将高风险私信/群组切换为 `dmPolicy: "disabled"` / 要求提及,并移除你之前设置的 `"*"` 允许所有条目。 +1. **停止它:** 停止 macOS 应用(如果它在监管 Gateway 网关),或终止你的 `openclaw gateway` 进程。 +2. **关闭暴露面:** 设置 `gateway.bind: "loopback"`(或禁用 Tailscale Funnel/Serve),直到你搞清楚发生了什么。 +3. **冻结访问:** 将高风险私信/群组切换为 `dmPolicy: "disabled"` / 要求 mention,并删除你之前设置的 `"*"` 全开放条目。 -### 轮换(如果 secrets 已泄露,则按已被入侵处理) +### 轮换(如果 secrets 泄露,则假定已被攻陷) -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` 中的模型/API keys,以及启用时的加密 secrets 负载值)。 +1. 轮换 Gateway 网关认证(`gateway.auth.token` / `OPENCLAW_GATEWAY_PASSWORD`)并重启。 +2. 轮换任何可调用 Gateway 网关机器上的远程客户端 secret(`gateway.remote.token` / `.password`)。 +3. 轮换提供商/API 凭证(WhatsApp 凭证、Slack/Discord token、`auth-profiles.json` 中的模型/API key,以及启用时加密 secrets 负载中的值)。 ### 审计 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 主机 OS + OpenClaw 版本 -- 会话转录 + 简短日志尾部(脱敏后) +- 时间戳、Gateway 网关主机操作系统 + OpenClaw 版本 +- 会话转录日志 + 一小段日志尾部(脱敏后) - 攻击者发送了什么 + 智能体执行了什么 - Gateway 网关是否暴露到了 loopback 之外(LAN/Tailscale Funnel/Serve) ## Secret Scanning(detect-secrets) -CI 会在 `secrets` 任务中运行 `detect-secrets` pre-commit hook。 -推送到 `main` 时始终会执行全文件扫描。Pull request 在存在基准 commit 时会使用已更改文件的快速路径, -否则会回退到全文件扫描。如果失败,说明存在尚未加入基线的新候选项。 +CI 会在 `secrets` job 中运行 `detect-secrets` pre-commit hook。 +推送到 `main` 时总是进行全文件扫描。Pull request 在存在基准提交时会使用变更文件 +快速路径,否则回退为全文件扫描。如果它失败了,说明存在尚未纳入基线的新候选项。 ### 如果 CI 失败 @@ -1367,26 +1264,26 @@ CI 会在 `secrets` 任务中运行 `detect-secrets` pre-commit hook。 2. 了解这些工具: - pre-commit 中的 `detect-secrets` 会使用仓库的 - baseline 和排除项来运行 `detect-secrets-hook`。 - - `detect-secrets audit` 会打开一个交互式审查界面,用于将 baseline 中的每一项 + 基线和排除项运行 `detect-secrets-hook`。 + - `detect-secrets audit` 会打开交互式审查界面,以将基线中的每一项 标记为真实 secret 或误报。 -3. 对于真实 secrets:轮换/移除它们,然后重新运行扫描以更新 baseline。 -4. 对于误报:运行交互式审查,并将它们标记为误报: +3. 对于真实 secret:轮换/删除它们,然后重新运行扫描以更新基线。 +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` 标志重新生成 + 基线(该配置文件仅供参考;detect-secrets 不会自动读取它)。 -当更新后的 `.secrets.baseline` 反映出预期状态后,请将其提交。 +当更新后的 `.secrets.baseline` 反映了预期状态后,再提交它。 ## 报告安全问题 在 OpenClaw 中发现了漏洞?请负责任地报告: -1. 邮箱:[security@openclaw.ai](mailto:security@openclaw.ai) -2. 在修复之前不要公开发布 -3. 我们会向你致谢(除非你希望匿名) +1. 发送邮件至:[security@openclaw.ai](mailto:security@openclaw.ai) +2. 在修复前不要公开发布 +3. 我们会注明致谢(除非你希望匿名)