Appearance
密钥管理
OpenClaw 支持增量式 SecretRef,让受支持的凭据无需以明文形式存储在配置中。
明文方式依然可用,SecretRef 是逐字段可选的。
目标与运行时模型
密钥被解析到内存中的运行时快照。
- 解析在激活期间立即执行,而不是延迟到请求路径上。
- 若有效活跃的 SecretRef 无法解析,启动时快速失败。
- 重新加载使用原子交换:完全成功,或保留上一次已知正确快照。
- 运行时请求只从活跃的内存快照读取。
- 出站投递路径(例如 Discord 回复/线程投递和 Telegram 动作发送)也从该活跃快照读取,不会在每次发送时重新解析 SecretRef。
这让密钥提供商中断不会影响热请求路径。
活跃面过滤
SecretRef 仅在有效活跃的面上验证。
- 已启用的面:未解析的 ref 会阻断启动/重新加载。
- 未活跃的面:未解析的 ref 不会阻断启动/重新加载。
- 未活跃的 ref 会触发非致命诊断,代码为
SECRETS_REF_IGNORED_INACTIVE_SURFACE。
未活跃面的示例:
- 已禁用的频道/账户条目。
- 没有已启用账户继承的顶层频道凭据。
- 已禁用的工具/功能面。
- 未被
tools.web.search.provider选中的 Web 搜索 provider 专属 key。 在自动模式(未设置 provider)下,key 按优先级顺序用于 provider 自动检测,直到有一个解析成功。选定后,未被选中的 provider key 将被视为未活跃直到被选中。 - 沙盒 SSH 认证材料(
agents.defaults.sandbox.ssh.identityData、certificateData、knownHostsData,以及按 Agent 覆盖)仅在默认 Agent 或已启用 Agent 的有效沙盒后端为ssh时活跃。 - 满足以下任一条件时,
gateway.remote.token/gateway.remote.passwordSecretRef 活跃:gateway.mode=remote- 配置了
gateway.remote.url gateway.tailscale.mode为serve或funnel- 在不具备上述远端面的本地模式下:
- 当 token auth 可以胜出且未配置 env/auth token 时,
gateway.remote.token活跃。 - 当 password auth 可以胜出且未配置 env/auth password 时,
gateway.remote.password活跃。
- 当 token auth 可以胜出且未配置 env/auth token 时,
- 当设置了
OPENCLAW_GATEWAY_TOKEN时,gateway.auth.tokenSecretRef 对启动 auth 解析而言是未活跃的,因为 env token 输入在该运行时中优先。
Gateway auth 面诊断
当 gateway.auth.token、gateway.auth.password、gateway.remote.token 或 gateway.remote.password 上配置了 SecretRef 时,Gateway 启动/重新加载会显式记录面状态:
active:SecretRef 是有效 auth 面的一部分,必须解析成功。inactive:由于另一个 auth 面优先,或远端 auth 未启用/不活跃,该 SecretRef 在本次运行时被忽略。
这些条目以 SECRETS_GATEWAY_AUTH_SURFACE 记录,并包含活跃面策略使用的原因,方便你了解凭据为何被视为活跃或未活跃。
引导参考预检
当引导流程以交互模式运行且你选择 SecretRef 存储时,OpenClaw 在保存前运行预检验证:
- Env ref:验证环境变量名,并确认在配置期间有可见的非空值。
- Provider ref(
file或exec):验证 provider 选择,解析id,检查解析值类型。 - Quickstart 复用路径:若
gateway.auth.token已是 SecretRef,引导流程在 probe/dashboard 引导启动前解析它(对env、file、execref 使用相同的快速失败门禁)。
验证失败时,引导流程会显示错误并允许重试。
SecretRef 规范
处处使用同一个对象格式:
json5
{ source: "env" | "file" | "exec", provider: "default", id: "..." }source: "env"
json5
{ source: "env", provider: "default", id: "OPENAI_API_KEY" }验证规则:
provider必须匹配^[a-z][a-z0-9_-]{0,63}$id必须匹配^[A-Z][A-Z0-9_]{0,127}$
source: "file"
json5
{ source: "file", provider: "filemain", id: "/providers/openai/apiKey" }验证规则:
provider必须匹配^[a-z][a-z0-9_-]{0,63}$id必须是绝对 JSON pointer(/...)- 段中 RFC6901 转义:
~=>~0,/=>~1
source: "exec"
json5
{ source: "exec", provider: "vault", id: "providers/openai/apiKey" }验证规则:
provider必须匹配^[a-z][a-z0-9_-]{0,63}$id必须匹配^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$id不得包含以斜杠分隔的.或..路径段(例如a/../b会被拒绝)
Provider 配置
在 secrets.providers 下定义 provider:
json5
{
secrets: {
providers: {
default: { source: "env" },
filemain: {
source: "file",
path: "~/.openclaw/secrets.json",
mode: "json", // 或 "singleValue"
},
vault: {
source: "exec",
command: "/usr/local/bin/openclaw-vault-resolver",
args: ["--profile", "prod"],
passEnv: ["PATH", "VAULT_ADDR"],
jsonOnly: true,
},
},
defaults: {
env: "default",
file: "filemain",
exec: "vault",
},
resolution: {
maxProviderConcurrency: 4,
maxRefsPerProvider: 512,
maxBatchBytes: 262144,
},
},
}Env provider
- 可选的
allowlist白名单。 - 缺失/空环境变量值会导致解析失败。
File provider
- 从
path读取本地文件。 mode: "json"期望 JSON 对象载荷,以指针解析id。mode: "singleValue"期望 ref id 为"value",返回文件内容。- 路径必须通过所有权/权限检查。
- Windows 安全关闭注意:若路径的 ACL 验证不可用,解析失败。对于受信路径,可在该 provider 设置
allowInsecurePath: true绕过路径安全检查。
Exec provider
- 运行配置的绝对二进制路径,不使用 shell。
- 默认情况下,
command必须指向普通文件(非软链接)。 - 设置
allowSymlinkCommand: true允许软链接命令路径(例如 Homebrew shim)。OpenClaw 会验证解析后的目标路径。 - 将
allowSymlinkCommand与trustedDirs组合用于包管理器路径(例如["/opt/homebrew"])。 - 支持超时、无输出超时、输出字节限制、env 白名单和受信目录。
- Windows 安全关闭注意:若命令路径的 ACL 验证不可用,解析失败。对于受信路径,可设置
allowInsecurePath: true绕过路径安全检查。
请求载荷(stdin):
json
{ "protocolVersion": 1, "provider": "vault", "ids": ["providers/openai/apiKey"] }响应载荷(stdout):
jsonc
{ "protocolVersion": 1, "values": { "providers/openai/apiKey": "<openai-api-key>" } }可选的按 id 错误:
json
{
"protocolVersion": 1,
"values": {},
"errors": { "providers/openai/apiKey": { "message": "not found" } }
}Exec 集成示例
1Password CLI
json5
{
secrets: {
providers: {
onepassword_openai: {
source: "exec",
command: "/opt/homebrew/bin/op",
allowSymlinkCommand: true, // Homebrew 软链接二进制必须
trustedDirs: ["/opt/homebrew"],
args: ["read", "op://Personal/OpenClaw QA API Key/password"],
passEnv: ["HOME"],
jsonOnly: false,
},
},
},
models: {
providers: {
openai: {
baseUrl: "https://api.openai.com/v1",
models: [{ id: "gpt-5", name: "gpt-5" }],
apiKey: { source: "exec", provider: "onepassword_openai", id: "value" },
},
},
},
}HashiCorp Vault CLI
json5
{
secrets: {
providers: {
vault_openai: {
source: "exec",
command: "/opt/homebrew/bin/vault",
allowSymlinkCommand: true, // Homebrew 软链接二进制必须
trustedDirs: ["/opt/homebrew"],
args: ["kv", "get", "-field=OPENAI_API_KEY", "secret/openclaw"],
passEnv: ["VAULT_ADDR", "VAULT_TOKEN"],
jsonOnly: false,
},
},
},
models: {
providers: {
openai: {
baseUrl: "https://api.openai.com/v1",
models: [{ id: "gpt-5", name: "gpt-5" }],
apiKey: { source: "exec", provider: "vault_openai", id: "value" },
},
},
},
}sops
json5
{
secrets: {
providers: {
sops_openai: {
source: "exec",
command: "/opt/homebrew/bin/sops",
allowSymlinkCommand: true, // Homebrew 软链接二进制必须
trustedDirs: ["/opt/homebrew"],
args: ["-d", "--extract", '["providers"]["openai"]["apiKey"]', "/path/to/secrets.enc.json"],
passEnv: ["SOPS_AGE_KEY_FILE"],
jsonOnly: false,
},
},
},
models: {
providers: {
openai: {
baseUrl: "https://api.openai.com/v1",
models: [{ id: "gpt-5", name: "gpt-5" }],
apiKey: { source: "exec", provider: "sops_openai", id: "value" },
},
},
},
}沙盒 SSH 认证材料
核心 ssh 沙盒后端也支持 SSH 认证材料的 SecretRef:
json5
{
agents: {
defaults: {
sandbox: {
mode: "all",
backend: "ssh",
ssh: {
target: "user@gateway-host:22",
identityData: { source: "env", provider: "default", id: "SSH_IDENTITY" },
certificateData: { source: "env", provider: "default", id: "SSH_CERTIFICATE" },
knownHostsData: { source: "env", provider: "default", id: "SSH_KNOWN_HOSTS" },
},
},
},
},
}运行时行为:
- OpenClaw 在沙盒激活期间解析这些 ref,而不是在每次 SSH 调用时延迟解析。
- 解析的值写入具有严格权限的临时文件,并用于生成的 SSH 配置。
- 若有效的沙盒后端不是
ssh,这些 ref 保持未活跃状态,不会阻断启动。
支持的凭据面
支持和不支持的凭据的权威列表见:
运行时铸造的或轮换中的凭据以及 OAuth 刷新材料,有意从只读 SecretRef 解析中排除。
必须行为与优先级
- 没有 ref 的字段:保持不变。
- 有 ref 的字段:在激活期间的活跃面上必须解析成功。
- 若明文和 ref 同时存在,在支持优先级路径上 ref 优先。
警告和审计信号:
SECRETS_REF_OVERRIDES_PLAINTEXT(运行时警告)REF_SHADOWED(当auth-profiles.json凭据优先于openclaw.jsonref 时的审计发现)
Google Chat 兼容行为:
serviceAccountRef优先于明文serviceAccount。- 设置了 sibling ref 时忽略明文值。
激活触发点
密钥激活在以下时机运行:
- 启动(预检 + 最终激活)
- 配置热加载路径
- 配置重载重启检查路径
- 通过
secrets.reload手动重载
激活规范:
- 成功时原子交换快照。
- 启动失败时中止 Gateway 启动。
- 运行时重载失败时保留上一次已知正确快照。
- 为出站 helper/tool 调用提供显式的按调用 channel token 不触发 SecretRef 激活;激活点仍为启动、重载和显式
secrets.reload。
降级与恢复信号
重载时激活失败(在健康状态后),OpenClaw 进入密钥降级状态。
一次性系统事件和日志代码:
SECRETS_RELOADER_DEGRADEDSECRETS_RELOADER_RECOVERED
行为:
- 降级:运行时保留上一次已知正确快照。
- 恢复:下次成功激活后触发一次。
- 已处于降级状态时重复失败会记录警告,但不会重复发送事件。
- 启动快速失败不触发降级事件,因为运行时从未变为活跃状态。
命令路径解析
命令路径可通过 Gateway 快照 RPC 选择加入受支持的 SecretRef 解析。
有两种宽泛的行为:
- 严格命令路径(例如
openclaw memory远端内存路径和openclaw qr --remote)从活跃快照读取,在所需 SecretRef 不可用时快速失败。 - 只读命令路径(例如
openclaw status、openclaw status --all、openclaw channels status、openclaw channels resolve、openclaw security audit以及只读 doctor/config repair 流程)也优先使用活跃快照,但在该命令路径中目标 SecretRef 不可用时降级,而不是中止。
只读行为:
- Gateway 运行时,这些命令优先从活跃快照读取。
- 若 Gateway 解析不完整或 Gateway 不可用,对特定命令面尝试目标化的本地回退。
- 若目标 SecretRef 仍不可用,命令继续运行并输出降级的只读结果,附带明确诊断信息(如"在此命令路径中已配置但不可用")。
- 此降级行为仅限当前命令。不会削弱运行时启动、重载或发送/auth 路径。
其他说明:
- 后端密钥轮换后刷新快照通过
openclaw secrets reload处理。 - 这些命令路径使用的 Gateway RPC 方法:
secrets.resolve。
审计与配置工作流
默认 operator 流程:
bash
openclaw secrets audit --check
openclaw secrets configure
openclaw secrets audit --checksecrets audit
审计发现包括:
- 明文存储的值(
openclaw.json、auth-profiles.json、.env及生成的agents/*/agent/models.json) - 生成的
models.json条目中明文敏感 provider header 残留 - 未解析的 ref
- 优先级遮蔽(
auth-profiles.json优先于openclaw.jsonref) - 遗留残留(
auth.json、OAuth 提醒)
Exec 注意:
- 默认情况下,audit 跳过 exec SecretRef 可解析性检查,以避免命令副作用。
- 使用
openclaw secrets audit --allow-exec在 audit 期间执行 exec provider。
Header 残留注意:
- 敏感 provider header 检测基于名称启发式(常见 auth/凭据 header 名称和片段,如
authorization、x-api-key、token、secret、password、credential)。
secrets configure
交互式助手,功能包括:
- 优先配置
secrets.providers(env/file/exec,添加/编辑/删除) - 在
openclaw.json和auth-profiles.json(一个 agent 作用域)中选择受支持的密钥字段 - 可直接在目标选择器中创建新的
auth-profiles.json映射 - 采集 SecretRef 详情(
source、provider、id) - 运行预检解析
- 可立即应用
Exec 注意:
- 除非设置了
--allow-exec,预检跳过 exec SecretRef 检查。 - 若从
configure --apply直接应用且计划包含 exec ref/provider,apply 步骤也要保持--allow-exec。
实用模式:
openclaw secrets configure --providers-onlyopenclaw secrets configure --skip-provider-setupopenclaw secrets configure --agent <id>
configure 应用默认行为:
- 清理
auth-profiles.json中目标 provider 的匹配静态凭据 - 清理
auth.json中遗留的静态api_key条目 - 清理
<config-dir>/.env中已知的密钥行
secrets apply
应用已保存的计划:
bash
openclaw secrets apply --from /tmp/openclaw-secrets-plan.json
openclaw secrets apply --from /tmp/openclaw-secrets-plan.json --allow-exec
openclaw secrets apply --from /tmp/openclaw-secrets-plan.json --dry-run
openclaw secrets apply --from /tmp/openclaw-secrets-plan.json --dry-run --allow-execExec 注意:
- dry-run 默认跳过 exec 检查,除非设置了
--allow-exec。 - 包含 exec SecretRef/provider 的计划在写入模式下被拒绝,除非设置了
--allow-exec。
严格目标/路径规范和确切拒绝规则详见:
单向安全策略
OpenClaw 有意不写入包含历史明文密钥值的回滚备份。
安全模型:
- 预检必须在写入模式前成功
- 在提交前验证运行时激活
- apply 使用原子文件替换更新文件,失败时尽力恢复
遗留 auth 兼容说明
对于静态凭据,运行时不再依赖明文遗留 auth 存储。
- 运行时凭据来源是已解析的内存快照。
- 发现遗留静态
api_key条目时会被清理。 - OAuth 相关兼容行为保持独立。
Web UI 说明
部分 SecretInput union 在原始编辑器模式下比表单模式更容易配置。
相关文档
- CLI 命令:secrets
- 计划规范详情:Secrets Apply 计划规范
- 凭据面:SecretRef 凭据面
- Auth 配置:Authentication
- 安全态势:Security
- 环境变量优先级:环境变量