前言

在使用 OpenClaw 的过程中,我们不可避免地会接触到各种 API 密钥:Discord Bot Token、Kimi API Key、GitHub PAT 等。这些密钥如果明文存储在配置文件中,存在严重的安全隐患。

本文将系统性地介绍 OpenClaw 2026.3.2 引入的 SecretRef 功能,帮助你把明文密钥迁移到安全存储,实现生产级的密钥管理。

一、明文存储的风险

1.1 当前密钥分布现状

密钥类型典型存储位置风险等级
Discord Tokenopenclaw.json🔴 高
AI API Keysauth-profiles.json🔴 高
GitHub PATgit remote URL🔴 高
OAuth Tokens配置文件🟡 中

1.2 OpenClaw 2026.3.2 自动迁移范围

升级到 2026.3.2 后,以下配置会被自动迁移:

配置项自动迁移迁移后格式说明
channels.discord.token✅ 是${env:DISCORD_TOKEN}自动转为 env 引用
channels.telegram.token✅ 是${env:TELEGRAM_TOKEN}自动转为 env 引用
其他 channel tokens✅ 是${env:XXX_TOKEN}自动转为 env 引用
auth-profiles.json API Keys❌ 否仍是明文需要手动迁移
Git remote URL 中的 PAT❌ 否仍是明文需要手动迁移

检查自动迁移结果:

# 检查 channel 配置是否已迁移
grep -E '\$\{env:' ~/.openclaw/openclaw.json

# 检查 auth-profiles 是否仍是明文
grep -E '"key":\s*"sk-' ~/.openclaw/agents/main/agent/auth-profiles.json

# 检查 git remote 是否仍是明文
git remote -v | grep 'ghp_'

1.3 明文存储的安全隐患

// 危险:明文存储在配置文件中
{
  "channels": {
    "discord": {
      "token": "MTQ2Njc4MDY2NzgwNjIyMDM2NA.GvboSs.xxx"  // ❌ 泄露风险
    }
  }
}

潜在风险:

  • 配置文件可能被提交到 Git 仓库
  • 多人协作时密钥暴露范围扩大
  • 日志中可能意外打印敏感信息
  • 无法满足合规审计要求

二、SecretRef 架构介绍

2.1 核心概念

SecretRef(密钥引用) 是一种"引用而非持有"的安全模型:

传统方式:配置文件持有明文密钥
    ↓
SecretRef 方式:配置文件只存储引用,密钥存储在安全后端

2.2 工作原理

# 传统方式(明文)
token: "sk-xxx1234567890abcdef"

# SecretRef 方式(安全引用)
token: "${secret:discord-token}"

工作流程:

  1. 配置文件只包含 ${secret:key-name} 格式的引用
  2. OpenClaw 启动时从安全后端获取实际密钥
  3. 密钥在内存中使用,不持久化到配置文件
  4. 支持运行时重载,无需重启 Gateway

2.3 支持的存储后端

后端类型适用场景
keychain系统钥匙串macOS 用户首选
passPassword StoreLinux 用户首选
file加密文件跨平台兼容
env环境变量容器化部署
vaultHashiCorp Vault企业级部署

三、实战迁移操作

3.1 准备工作

第一步:备份当前配置

# 创建配置备份目录
mkdir -p ~/.openclaw/backups

# 备份关键配置文件
cp ~/.openclaw/openclaw.json ~/.openclaw/backups/openclaw.json.bak.$(date +%Y%m%d_%H%M%S)
cp ~/.openclaw/agents/main/agent/auth-profiles.json ~/.openclaw/backups/auth-profiles.json.bak.$(date +%Y%m%d_%H%M%S)

# 备份博客仓库的 git 配置
cd ~/.openclaw/workspace/duranblog
git remote get-url origin > ~/.openclaw/backups/git-remote-backup.txt

echo "✅ 备份完成"

第二步:检查当前密钥状态

# 审计检查
openclaw secrets audit

实际输出示例:

Secrets audit: findings. plaintext=2, unresolved=0, shadowed=0, legacy=1.
- [PLAINTEXT_FOUND] /home/warwick/.openclaw/openclaw.json:channels.discord.token channels.discord.token is stored as plaintext.
- [LEGACY_RESIDUE] /home/warwick/.openclaw/agents/main/agent/auth-profiles.json:profiles.qwen-portal:default OAuth credentials are present (out of scope for static SecretRef migration).
- [PLAINTEXT_FOUND] /home/warwick/.openclaw/agents/main/agent/auth-profiles.json:profiles.kimi-coding:default.key Auth profile API key is stored as plaintext.

审计结果解读:

发现项位置状态说明
Discord Tokenopenclaw.json🔴 明文需要迁移
Kimi API Keyauth-profiles.json🔴 明文需要迁移
Qwen OAuthauth-profiles.json🟡 遗留OAuth 不支持静态迁移

注意: secrets audit 不会检查 git remote 中的 GitHub PAT,需要手动确认:

# 检查 git remote 是否包含明文 PAT
cd ~/.openclaw/workspace/duranblog
git remote -v

如果输出包含 https://用户名:[email protected]/...,说明 PAT 是明文存储的。

3.2 手动迁移剩余密钥

如果 OpenClaw 2026.3.2 升级后仍有明文密钥(auth-profiles.json 中的 API Keys 和 git remote 中的 PAT),按以下步骤手动迁移:

迁移 auth-profiles.json 中的 API Keys

第一步:检查当前明文密钥

# 查看 auth-profiles.json 中的明文 API Key
cat ~/.openclaw/agents/main/agent/auth-profiles.json | grep -E '"key":\s*"sk-'

第二步:更新 gateway.env 文件

将 API Key 添加到环境变量文件:

# 编辑 env 文件
vim ~/.openclaw/secrets/gateway.env

添加 Kimi API Key:

# 已有的 Discord Token
DISCORD_TOKEN=MTQ2Njc4MDY2NzgwNjIyMDM2NA.GvboSs.xxx

# 添加 Kimi API Key(从 auth-profiles.json 中复制)
KIMI_API_KEY=sk-kimi-xxx

第三步:修改 auth-profiles.json 使用 SecretRef

编辑 ~/.openclaw/agents/main/agent/auth-profiles.json

{
  "profiles": {
    "kimi-coding:default": {
      "type": "api_key",
      "provider": "kimi-coding",
      "key": "${env:KIMI_API_KEY}"
    }
  }
}

第四步:重载配置

openclaw secrets reload

迁移 Git Remote 中的 GitHub PAT

第一步:备份当前 remote URL

cd ~/.openclaw/workspace/duranblog
git remote get-url origin > ~/.openclaw/backups/git-remote-backup.txt

第二步:添加 GitHub PAT 到 env 文件

# 编辑 env 文件
vim ~/.openclaw/secrets/gateway.env

添加 GitHub PAT:

DISCORD_TOKEN=MTQ2Njc4MDY2NzgwNjIyMDM2NA.GvboSs.xxx
KIMI_API_KEY=sk-kimi-xxx
GITHUB_PAT=ghp_xxx

第三步:更新 git remote URL

cd ~/.openclaw/workspace/duranblog

# 更新为使用 env 变量
git remote set-url origin 'https://openduran:${env:GITHUB_PAT}@github.com/openduran/duranblog.git'

# 验证
git remote -v

注意:git 本身不支持 ${env:...} 语法,需要通过 credential helper 或手动配置 git 来支持。

替代方案(推荐):使用 Git Credential Manager 或手动输入密码:

# 移除 URL 中的密码
git remote set-url origin 'https://[email protected]/openduran/duranblog.git'

# 配置 git 缓存密码
git config --global credential.helper cache

第四步:重启 Gateway

openclaw gateway restart

3.3 使用交互式配置向导(可选)

对于更复杂的场景,可以使用交互式配置向导:

openclaw secrets configure

注意:交互式向导适合初次配置或需要添加新的 provider(如 file/exec),对于已有 env provider 的情况,直接编辑配置文件更简单。


第三步:启动配置向导

openclaw secrets configure

配置流程(完整步骤):

1. 初始界面

Configure secret providers (only env refs are available until file/exec providers are added)

● Add provider (Define a new env/file/exec provider)

Select: 1  # 选择 Add provider

2. 选择 Provider Source

Provider source

1) env  - Environment variables
2) file - Read from file (JSON or single-value)
3) exec - Execute command and read stdout

Select: 2  # 选择 file

3. 配置 File Provider

File path (absolute): /home/warwick/.openclaw/secrets/credentials.json

File mode

1) json        - Read multiple key-value pairs from JSON file
2) singleValue - Read a single value from file

Select: 1  # 选择 json

Timeout ms (blank for default):    # 按回车

Max bytes (blank for default):     # 按回车

4. 回到 Provider 配置界面

Configure secret providers

● Continue (Continue to credential field mapping)

Select: 1  # 选择 Continue

5. 选择要配置的凭证字段

Select credential field

● discord-token       (openclaw.json)
● kimi-api-key        (auth-profiles.json)
○ Create auth profile mapping
○ Done

Select: 1  # 选择 discord-token

6. 配置 Secret 引用

Secret source

1) file

Select: 1  # 选择 file

Provider alias: default  # 输入或确认 provider 别名

Secret id: discord-token  # 输入密钥在 JSON 文件中的 key

此时会验证引用是否能解析到值。

7. 继续配置其他字段

Configure another credential? (Y/n): Y

# 重复步骤 5-6,选择 kimi-api-key 等其他字段

8. 完成配置

Select credential field

○ discord-token       (configured)
○ kimi-api-key        (configured)
● Done                (Finish and run preflight)

Select: 3  # 选择 Done

9. Preflight 检查和 Apply

Preflight: changed=true, files=2, warnings=0.
Plan: targets=2, providerUpserts=1, providerDeletes=0.

Apply this plan now? (Y/n): Y

This migration is one-way for migrated plaintext values. Continue with apply? (Y/n): Y

Secrets applied. Updated 2 file(s).

注意

  • 配置向导会自动创建 JSON 密钥文件并写入密钥值
  • 如果过程中出错,可以使用 --plan-out 参数生成计划文件检查
  • 或者在出错时选择不 apply,然后使用手动配置方式

当前版本限制

  • 仅支持 env/file/exec 三种 provider,不支持 keychain/pass/vault
  • 配置流程分为两个阶段:先配置 provider,再配置密钥映射

3.4 验证迁移结果

验证配置

# 检查配置文件(应显示引用而非明文)
cat ~/.openclaw/openclaw.json | grep -A2 '"discord"'

预期输出:

"discord": {
  "token": "${env:DISCORD_TOKEN}",
  "enabled": true
}

注意:根据使用的 provider 不同,引用格式也不同:

  • ${env:VAR_NAME} - 环境变量 provider(OpenClaw 自动迁移使用)
  • ${file:/path/to/file:key} - 文件 provider(手动配置使用)

功能测试

# 测试 Discord 连接
openclaw message send --channel discord --to "channel:ID" --message "测试消息"

# 测试 AI 功能
openclaw chat "你好"

# 测试 Git 推送
cd ~/.openclaw/workspace/duranblog
git push origin main --dry-run

四、GitHub PAT 特殊处理

4.1 更新 Git Remote URL

手动配置时,使用 file provider 格式更新 remote:

cd ~/.openclaw/workspace/duranblog

# 查看当前 remote
git remote -v

# 更新为引用格式(使用 file provider)
git remote set-url origin 'https://openduran:${file:/home/warwick/.openclaw/secrets/credentials.json:github-pat}@github.com/openduran/duranblog.git'

# 验证
git remote -v

### 4.2 配置 Git Credential Helper

为了让 git 能够解析 SecretRef,需要配置自定义 credential helper:

```bash
# 配置 git 使用 OpenClaw 作为 credential helper
git config --global credential.helper '!openclaw secrets git-credential'

五、后续维护

5.1 定期审计

# 每月执行一次审计
openclaw secrets audit

5.2 密钥轮换

当密钥泄露或需要轮换时:

如果是 env provider(OpenClaw 自动迁移的格式):

# 1. 直接编辑 env 文件更新密钥值
vim ~/.openclaw/secrets/gateway.env

# 2. 重载配置
openclaw secrets reload

# 3. 验证
openclaw gateway status

如果是手动配置的 file provider:

# 1. 编辑密钥文件
vim ~/.openclaw/secrets/credentials.json

# 2. 重载配置
openclaw secrets reload

# 3. 验证
openclaw gateway status

5.3 安全删除旧配置备份

迁移完成后,旧备份文件仍包含明文密钥,建议安全删除:

# 安全删除(覆盖后删除)
shred -u ~/.openclaw/backups/openclaw.json.bak.*
shred -u ~/.openclaw/backups/auth-profiles.json.bak.*

六、常见问题

Q1: 迁移后启动报错 “无法解析 SecretRef”

原因: 密钥文件路径错误或格式不正确

解决:

# 检查密钥文件是否存在
ls -la ~/.openclaw/secrets/credentials.json

# 检查 JSON 格式是否正确
jq . ~/.openclaw/secrets/credentials.json

# 检查文件权限(应为 600)
chmod 600 ~/.openclaw/secrets/credentials.json

# 检查配置文件中的引用路径是否正确
grep "file:" ~/.openclaw/openclaw.json

# 重载配置
openclaw secrets reload

Q2: OAuth 凭证如何处理?

OAuth 凭证(如 Qwen)不支持静态迁移,因为:

  • OAuth Token 会定期过期刷新
  • 需要动态获取而非静态存储

建议: 继续使用 OAuth 原生流程,不要尝试静态迁移。

Q3: 如何查看当前有哪些 SecretRef?

# 检查配置文件中的引用
grep -r "\${file:" ~/.openclaw/

# 或者查看所有 SecretRef 引用
grep -rE '\$\{(file|env|exec|secret):' ~/.openclaw/

Q4: 如何回滚到明文配置?

# 使用备份恢复
cp ~/.openclaw/backups/openclaw.json.bak.xxx ~/.openclaw/openclaw.json
cp ~/.openclaw/backups/auth-profiles.json.bak.xxx ~/.openclaw/agents/main/agent/auth-profiles.json

# 重启 Gateway
openclaw gateway restart

七、总结

迁移前后对比

维度迁移前迁移后
存储方式明文存储分离存储(密钥文件 + 配置引用)
安全风险高(配置文件泄露=密钥泄露)低(配置文件只含引用)
审计合规不满足满足
密钥轮换需修改多处只需更新密钥文件
团队协作密钥共享困难可安全共享配置(不含密钥)

核心优势

安全:密钥不再明文存储在配置文件中
灵活:支持多种存储后端,适应不同环境
便捷:运行时重载,无需重启服务
合规:满足企业安全审计要求


参考文档:

本文环境:

  • OpenClaw: 2026.3.2
  • OS: Debian 13
  • Date: 2026-03-03