教程 08

教程 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..." }
}

安全要求:文件必须是当前用户所有,且权限不超过 600chmod 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 值才会注入,不会覆盖系统已存在的同名变量
  • PATHLD_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.json

OpenClaw 要求密钥文件权限不超过 600,且文件必须归当前用户所有(不能是 root 所有但运行用户可读)。

exec source 的脚本超时了怎么处理?

增大 timeoutMs(最大 120000ms)。最常见的原因是外部命令需要登录态,例如 1Password CLI 需要先 op signin。建议在脚本中加入自动重新登录的逻辑,或将 session token 缓存到文件中。

.env 文件和 openclaw.json 里的 env 块有什么区别?

.env 文件是系统级环境变量,对所有进程生效;openclaw.jsonenv.vars 块只在 OpenClaw 网关进程内生效,不影响其他程序。两者都支持用 ${VAR_NAME}apiKey 等字段中引用,推荐用 .env 存敏感数据,env.vars 存 OpenClaw 专用的非敏感配置(如代理地址)。

可以同时存在多个配置文件吗?

OpenClaw 支持配置合并("mode": "merge"),但主配置文件路径固定为 ~/.openclaw/openclaw.json。你可以在 openclaw.json 中通过 import 字段引入其他配置文件片段,实现配置的模块化管理。


下一步

  • 教程 05 — 配置多个模型 Provider,自动切换
  • 教程 03 — 给 AI 加自定义技能

关注我们,获取最新 AI 动态

在 X 上关注 @lanmiaoai,第一时间获取教程更新、AI 工具推荐。

立即关注