教程 08 — 配置系统深度解析:API Key 的正确存法
目标:理解 OpenClaw 的三层配置体系,掌握 Secret Provider 的三种模式,让你的密钥既安全又灵活。
你会学到什么
- OpenClaw 配置文件的结构和读取顺序
- API Key 的三种写法:字符串 / 环境变量引用 / 外部命令
- Secret Provider 系统的安全设计
- 如何对接 1Password、Vault 等密钥管理工具
一、配置文件在哪里
OpenClaw 的配置存放在 ~/.openclaw/openclaw.json(或 .yaml),网关启动时自动读取。
# 查看当前配置
openclaw config show
# 通过命令行设置某个字段
openclaw config set gateway.mode local整体结构如下:
{
"gateway": { ... }, // 网关运行模式
"agents": { ... }, // AI 代理默认行为
"models": { ... }, // 模型提供商列表
"channels": { ... }, // 消息渠道(Telegram、Discord 等)
"env": { ... }, // 运行时注入的环境变量
"secrets": { ... }, // Secret Provider 配置(高级)
"hooks": { ... } // 生命周期钩子
}二、API Key 的三种写法
方式 A:直接写字符串(快速体验用)
最简单,但不推荐在生产或多人共用场景使用,因为密钥会明文保存在配置文件里。
{
"models": {
"providers": {
"openai": {
"apiKey": "sk-proj-xxxxxxxxxxxxxxxx"
}
}
}
}方式 B:环境变量引用(日常推荐)
用 ${VAR_NAME} 占位符引用系统环境变量,配置文件里不存真实密钥。
第一步:在 shell 里 export,或写入 ~/.profile:
export OPENAI_API_KEY="sk-proj-xxxxxxxxxxxxxxxx"
export MINIMAX_API_KEY="eyJhbGci..."第二步:配置文件里用占位符引用:
{
"models": {
"providers": {
"openai": {
"apiKey": "${OPENAI_API_KEY}"
},
"minimax": {
"apiKey": "${MINIMAX_API_KEY}"
}
}
}
}也可以用结构化写法(更明确):
{
"apiKey": { "source": "env", "provider": "default", "id": "OPENAI_API_KEY" }
}工作原理:网关启动时,OpenClaw 匹配 ${VAR_NAME} 模式,从 process.env 读取对应值,仅在内存中解析,不写入磁盘。
方式 C:Secret Provider(团队 / 服务器部署)
这是最安全、也是最灵活的方式,适合:
- 服务器上不想设置环境变量
- 团队共用网关,密钥集中管理
- 接入 1Password CLI、HashiCorp Vault 等工具
Secret Provider 有三种 source:
source: "file" — 从文件读取
适合把密钥存在权限严格的文件里(OpenClaw 会验证文件权限,不允许 group-writable):
{
"secrets": {
"providers": {
"my-keys": {
"source": "file",
"path": "~/.openclaw/secrets.json",
"mode": "json"
}
}
},
"models": {
"providers": {
"openai": {
"apiKey": { "source": "file", "provider": "my-keys", "id": "/openai/apiKey" }
}
}
}
}对应的 ~/.openclaw/secrets.json:
{
"openai": { "apiKey": "sk-proj-xxxxxxxx" },
"minimax": { "apiKey": "eyJhbGci..." }
}安全要求:文件必须是当前用户所有,且权限不超过
600(chmod 600 ~/.openclaw/secrets.json)。
source: "exec" — 调用外部程序
适合对接 1Password CLI、Vault、系统钥匙串:
{
"secrets": {
"providers": {
"op-vault": {
"source": "exec",
"command": "/usr/local/bin/op-resolver",
"timeoutMs": 5000
}
}
},
"models": {
"providers": {
"openai": {
"apiKey": { "source": "exec", "provider": "op-vault", "id": "openai/api-key" }
}
}
}
}外部程序通过 stdin 接收请求,通过 stdout 返回结果,协议如下:
# stdin 收到(JSON):
{ "protocolVersion": 1, "provider": "op-vault", "ids": ["openai/api-key"] }
# stdout 返回(JSON):
{ "protocolVersion": 1, "values": { "openai/api-key": "sk-proj-xxx" } }
三、1Password 接入示例
如果你用 1Password 存 API Key,可以写一个简单的 resolver 脚本:
#!/usr/bin/env bash
# ~/.openclaw/op-resolver.sh
# 权限设置:chmod 700 ~/.openclaw/op-resolver.sh
set -euo pipefail
INPUT=$(cat)
ID=$(echo "$INPUT" | jq -r '.ids[0]')
# 从 1Password 读取
VALUE=$(op read "op://Private/$ID" 2>/dev/null)
echo "{\"protocolVersion\":1,\"values\":{\"$ID\":\"$VALUE\"}}"然后配置:
{
"secrets": {
"providers": {
"1password": {
"source": "exec",
"command": "/Users/你的用户名/.openclaw/op-resolver.sh",
"timeoutMs": 8000
}
}
}
}注意:
command必须是绝对路径,且文件不能被其他用户写入。
四、配置中的 env 块
除了 Secret Provider,env 块提供了另一种简便方式——直接在配置文件里声明运行时环境变量:
{
"env": {
"vars": {
"HTTP_PROXY": "http://127.0.0.1:7890",
"OPENAI_BASE_URL": "https://api.openai.com"
}
}
}规则:
- 只有配置文件中的
env.vars值才会注入,不会覆盖系统已存在的同名变量 PATH、LD_PRELOAD等危险变量名被自动屏蔽,无法通过此方式注入
五、敏感字段自动脱敏
OpenClaw 用 Zod sensitive registry 标记所有密钥字段。当配置信息暴露给 Dashboard 或日志时,这些字段会自动替换为 [REDACTED]:
# 日志或 API 响应里看到的是:
{ "apiKey": "[REDACTED]" }
# 内存里真实值不会出现在日志
六、完整配置示例(多模型 + 安全密钥)
{
"gateway": { "mode": "local" },
"secrets": {
"providers": {
"env-keys": { "source": "env" }
},
"defaults": { "env": "env-keys" }
},
"agents": {
"defaults": {
"model": { "primary": "openai/gpt-4o" }
}
},
"models": {
"mode": "merge",
"providers": {
"openai": {
"apiKey": "${OPENAI_API_KEY}",
"models": [
{ "id": "gpt-4o", "name": "GPT-4o" }
]
},
"minimax": {
"baseUrl": "https://api.minimax.io/anthropic",
"apiKey": "${MINIMAX_API_KEY}",
"api": "anthropic-messages",
"models": [
{
"id": "MiniMax-M2.1",
"name": "MiniMax M2.1",
"contextWindow": 200000,
"maxTokens": 8192
}
]
}
}
},
"channels": {
"telegram": {
"token": "${TELEGRAM_BOT_TOKEN}"
}
}
}对应的环境变量(写入 ~/.profile 或 .env):
export OPENAI_API_KEY="sk-proj-..."
export MINIMAX_API_KEY="eyJhbGci..."
export TELEGRAM_BOT_TOKEN="8543054163:AAH..."七、常见问题
配置改了为什么没生效?
网关需要重启才会重新读取配置,技能(SKILL.md)除外:
openclaw gateway restart怎么验证密钥被正确读取了?
openclaw models list
# 看到对应 provider 的模型就说明 apiKey 解析成功如果模型列表为空,运行 openclaw config show 查看配置是否被正确解析,检查 ${VAR_NAME} 占位符对应的环境变量是否已 export。
文件 source 报权限错误怎么办?
chmod 600 ~/.openclaw/secrets.json
# 确保文件属于当前用户
ls -la ~/.openclaw/secrets.jsonOpenClaw 要求密钥文件权限不超过 600,且文件必须归当前用户所有(不能是 root 所有但运行用户可读)。
exec source 的脚本超时了怎么处理?
增大 timeoutMs(最大 120000ms)。最常见的原因是外部命令需要登录态,例如 1Password CLI 需要先 op signin。建议在脚本中加入自动重新登录的逻辑,或将 session token 缓存到文件中。
.env 文件和 openclaw.json 里的 env 块有什么区别?
.env 文件是系统级环境变量,对所有进程生效;openclaw.json 的 env.vars 块只在 OpenClaw 网关进程内生效,不影响其他程序。两者都支持用 ${VAR_NAME} 在 apiKey 等字段中引用,推荐用 .env 存敏感数据,env.vars 存 OpenClaw 专用的非敏感配置(如代理地址)。
可以同时存在多个配置文件吗?
OpenClaw 支持配置合并("mode": "merge"),但主配置文件路径固定为 ~/.openclaw/openclaw.json。你可以在 openclaw.json 中通过 import 字段引入其他配置文件片段,实现配置的模块化管理。