OpenClaw 支持一套可选启用的 SecretRef(密钥引用)机制,让敏感凭据不必以明文形式存放在配置文件中。本文基于官方文档详解 SecretRef 的运行模型、生效范围判定逻辑,以及具体的配置写法。
明文依然可用,SecretRef 是按凭据可选启用的
明文配置方式依然完全可用
SecretRef 是针对每一项凭据可选启用(opt-in)的
这意味着你可以渐进式迁移——不需要一次性把所有配置都改成引用方式,可以先给最敏感的几个凭据(比如 Gateway 认证 Token)切换成 SecretRef,其余保持明文也不影响运行。
运行时模型:解析成内存快照
密钥被解析进一个内存中的运行时快照
- 解析发生在"激活"阶段,是即时(eager)的,不是请求路径上
按需(lazy)解析的
- 启动时,如果一个"实际生效"的 SecretRef 无法解析,
会直接快速失败(fail fast)
- 重新加载(reload)采用原子交换:要么完全成功,
要么保留上一次"已知良好"的快照
- 违反 SecretRef 策略的配置(比如 OAuth 模式的认证配置
混用了 SecretRef 输入)会在运行时交换之前就导致激活失败
- 运行时请求只从当前生效的内存快照读取
- 出站投递路径(比如 Discord 回复/线程投递、
Telegram 动作发送)同样只读取这个已激活的快照,
不会在每次发送时重新解析 SecretRef
这套设计的核心价值是——把密钥提供方的故障隔离在"热请求路径"之外。如果密钥提供方(比如某个云端密钥管理服务)临时不可用,不会导致每一次实际请求都跟着失败,因为运行时只依赖已经加载好的内存快照,而不是每次都重新去请求密钥提供方。
生效范围判定:只校验"实际活跃"的 Surface
- 已启用的 Surface:未解析的引用会阻塞启动/重载
- 未启用的 Surface:未解析的引用不会阻塞启动/重载,
只会产生一条非致命诊断信息,代码为
SECRETS_REF_IGNORED_INACTIVE_SURFACE
"未启用 Surface"的典型例子:
- 被禁用的渠道/账号条目
- 没有任何已启用账号继承的顶层渠道凭据
- 被禁用的工具/功能 Surface
- 未被 tools.web.search.provider 选中的
特定网页搜索提供商密钥
(auto 模式下会按优先级依次尝试,直到某个解析成功;
一旦选定,未被选中的provider密钥会被视为未启用)
- 沙箱 SSH 认证材料(identityData/certificateData/
knownHostsData等)只在有效沙箱后端确实是 ssh 时才算启用
- gateway.remote.token / gateway.remote.password 的 SecretRef
仅在以下情况之一成立时才算启用:
gateway.mode=remote,或配置了 gateway.remote.url,
或 gateway.tailscale.mode 为 serve/funnel,
或本地模式下没有上述远程 Surface 时按 token/password
认证是否会"胜出"来判定
- 当设置了 OPENCLAW_GATEWAY_TOKEN 环境变量时,
gateway.auth.token 的 SecretRef 对启动认证解析视为未启用
(因为环境变量输入在该运行时中优先)
这套细粒度的判定逻辑,本质上是为了避免"因为一个你根本没在用的功能的密钥引用解析失败,就把整个 Gateway 启动卡住"这种不合理的阻塞。
Gateway 认证 Surface 诊断日志
当 gateway.auth.token、gateway.auth.password、gateway.remote.token 或 gateway.remote.password 配置了 SecretRef 时,Gateway 启动/重载会显式记录该Surface 的状态:
active — 该 SecretRef 属于当前生效的认证 Surface,必须能解析
inactive — 因为其他认证 Surface 胜出,或远程认证被禁用/未激活,
该 SecretRef 被忽略
这些条目以 SECRETS_GATEWAY_AUTH_SURFACE 代码记录,并附带具体判定原因,方便排查"为什么这个凭据被当作active/inactive"这类问题。
SecretRef 的统一写法
{ source: "env" | "file" | "exec", provider: "default", id: "..." }source: "env" —— 从环境变量读取:
{ source: "env", provider: "default", id: "OPENAI_API_KEY" }校验规则:
provider 必须匹配 ^[a-z][a-z0-9_-]{0,63}$
id 必须匹配 ^[A-Z][A-Z0-9_]{0,127}$
除了 env,还支持 file(从文件读取)和 exec(从执行命令的输出读取)两种来源,具体校验规则可参考官方文档 SecretRef 契约章节的完整说明。
引导流程(Onboarding)预检
交互式引导过程中如果选择 SecretRef 存储方式,OpenClaw 会在保存前先跑一遍预检——环境变量引用会校验变量名并确认配置过程中能看到非空值;文件/命令类引用会校验 Provider 选择、解析 ID、检查解析出的值类型;如果 gateway.auth.token 已经是 SecretRef,还会在探测/仪表盘引导之前先按同一套快速失败逻辑解析它。校验失败时,引导流程会展示错误信息并允许重试。
实战建议
1. 优先给 Gateway 认证凭据(token/password)配置 SecretRef,
这是暴露面最大、风险最高的一类密钥
2. 渐进式迁移,不需要一次性把所有明文配置都改掉
3. 排查"为什么密钥没生效"类问题时,注意区分 active/inactive
两种状态——inactive 的引用即便解析失败也不会报错,
容易造成"配置了但没生效"的误判
4. 用 exec 类型引用对接企业内部密钥管理系统时,
注意该来源的具体校验规则(建议查阅官方文档的
完整契约章节)
总结
SecretRef 的设计核心是渐进式、故障隔离、精细化生效判定——不强制一次性迁移,密钥提供方的故障不会拖垮热请求路径,且只对"实际在用"的 Surface 做强制校验。对于任何计划把 OpenClaw 部署到生产环境、需要认真对待凭据管理的团队,这是配置阶段值得优先了解的一块。
来源:Secrets Management — OpenClaw 官方文档