为什么需要 secrets

玩 OpenClaw 久了,你一定会往里塞各种密钥:模型服务商的 API Key、支付网关的 Secret、飞书/企业微信的 App Secret、各种第三方平台的 Token。

最容易踩的坑,是把这些明文直接写进:

  • 聊天里(让 AI「帮我配一下这个 Key:sk-xxxx」)
  • shell 命令的参数(curl -H "Authorization: Bearer sk-xxxx")
  • 配置文件的裸字段
  • 环境变量脚本,然后被 env / 日志打印出来

这些地方的明文会出现在聊天记录、shell history、进程环境、构建日志里,任何能读到这些位置的人都能拿走。OpenClaw 提供了一套 secrets 机制,核心目标就一句:密钥明文只在受保护的共享保险库里走一遭,模型、聊天、命令参数都拿不到它。

secrets 的三条铁律

  1. 列表只给元数据:secrets list 返回名称、用途、允许访问的主机(allowedHosts)、更新时间,绝不返回值本身
  2. 请求走人工遮罩输入:新密钥由你(人类)在遮罩框里输入,直接进共享保险库,不经过模型的上下文,也不进聊天记录。
  3. 配置用 SecretRef 引用:配置文件里不放明文,而是放一个引用;运行时由运行时自动注入一个不透明环境变量给需要的字段。

常用命令与示例

1. 先看已有哪些凭据

不需要记脑子,先列一遍:

secrets list

返回的是元数据清单,类似:

OPENAI_API_KEY      secret   api.openai.com       updated 2026-09-10
FEISHU_APP_SECRET   secret   open.feishu.cn        updated 2026-09-08

注意:这里看不到任何 sk- 开头的值,只能看到「有这么个东西、给哪个域名用」。

2. 申请一个新的凭据

格式是 secrets request,带三个关键信息:

  • name:大写、环境变量形态,例如 STRIPE_API_KEY
  • reason:一句话说明用途(会展示给人类)
  • allowedHosts:精确的主机名列表(不带协议和端口),例如 ["api.stripe.com"]
secrets request
  name: STRIPE_API_KEY
  reason: 接收 Stripe 支付回调时校验签名
  allowedHosts: ["api.stripe.com"]

提交后,人类在遮罩框里输入真实值,值直接进共享保险库,你拿回来的是一个 SecretRef(引用),而不是明文。之后配置里就填这个引用。

3. 删除一个不再用的凭据

secrets delete
  name: OLD_PROVIDER_KEY

在配置里怎么用 SecretRef

模型服务商、网关、各种集成配置里,原本填明文 Key 的字段,改成引用形式。以模型供应商配置为例:

{
  "provider": "openai",
  "apiKey": { "secret": "OPENAI_API_KEY" }
}

运行时看到 { "secret": "OPENAI_API_KEY" } 就会去保险库取对应值,并自动注入一个不透明的环境变量哨兵(同名环境变量),你的代码/进程读到的是注入后的变量,不是你手敲的明文。原生 shell / sandbox / node 里没有这个受保护注入,只有网关主机命令才会自动拿到那个哨兵变量。

网关出口的两个硬约束

如果你的 OpenClaw 走网关出网,记住两点,否则密钥能存对、请求却出不去:

  • 必须开启代理(proxy)+ 精确 allowedHosts:没有 allowedHosts 就禁止出网替换,配置里的 SecretRef 还能用,但出网会被拦。
  • 没有明文兜底:网关出口不允许把密钥当明文回填到 URL/日志。老老实实走 SecretRef + allowedHosts。

上线前自检清单

发布任何接第三方服务的配置前,逐项打勾:

  • 配置/脚本里 grep 不到任何真实 Key 明文
  • secrets list 能看到对应条目且 allowedHosts 精确到域名
  • 聊天记录里没有贴过 Key(贴过就视为已泄露,立即轮换)
  • 网关场景已开 proxy 且 allowedHosts 匹配
  • 删除/替换老 Key 后,旧明文已从 history / 日志里清掉

踩过的坑(真实)

  • 审批预览别带 Key:需要人工 /approve 的命令,预览里只放命令本身,绝不要把 Key 拼进命令字符串当审批 id 或参数——审批界面会显示它。
  • late save 要等一轮:保险库第一次被某命令读取时会给本次运行「拍快照」;如果运行中途才新存一个 Key,要等下一轮运行才能被那条命令读到,别以为当场就能用。
  • shell 变量别插值明文:export K="sk-xxx"curl ... $K 等于把明文放进环境和历史,等于没用 secrets。要么走 SecretRef 自动注入,要么干脆不在这层碰明文。
  • allowedHosts 越宽越危险:只给真正要请求的域名,别图省事写 *,否则一个泄露的 Key 可能被拿去打别的站。

一句话总结

密钥管理的底线不是「藏得好」,而是「根本不出现在它不该出现的地方」。OpenClaw 的 secrets 把明文收敛到受保护保险库,配置用引用、运行用注入、列表只给元数据——照这套走,AI、日志、聊天都拿不到你的 Key。


扫码关注公众号,获取更多 OpenClaw 实操技巧:

公众号二维码