密钥管理
Open-ACE 的加密密钥派生、轮换和安全最佳实践。
概述
Open-ACE 使用 Fernet 对称加密保护静态敏感数据:
- 远程工作区的 API Key(
api_key_store表) - SMTP 密码(
smtp_settings表) - Model Gateway API Key(
model_gateway_config表)
Proxy Token 使用 HMAC-SHA256 签名(非 Fernet)进行认证。
密钥派生
加密密钥从 OPENACE_ENCRYPTION_KEY 环境变量派生:
OPENACE_ENCRYPTION_KEY (环境变量,>= 32 字符)
│
│ SHA-256 哈希
▼
32 字节密钥
│
│ base64.urlsafe_b64encode
▼
Fernet 密钥 (44 字符)
│
├────────────────┬────────────────┐
▼ ▼ ▼
API Key SMTP 密码 Model Gateway
加密 加密 加密
│
│ 同一密钥用于 HMAC-SHA256
▼
Proxy Token
签名
密钥派生代码:
import hashlib
import base64
key_env = os.environ.get("OPENACE_ENCRYPTION_KEY")
derived_key = hashlib.sha256(key_env.encode()).digest()
fernet_key = base64.urlsafe_b64encode(derived_key)
密钥共享影响面
同一密钥用于:
- API Key 加密 -
api_key_store.encrypted_key - SMTP 密码加密 -
smtp_settings.encrypted_password - Model Gateway 加密 -
model_gateway_config.encrypted_api_key - Proxy Token 签名 - 远程代理认证的 HMAC-SHA256 签名
影响:
- 密钥轮换需要重新加密三个数据存储
- 使用旧密钥签名的活跃 Proxy Token 轮换后验证失败
- 密钥泄露影响四个安全域
密钥轮换
当前限制
- 单密钥 Fernet:不支持 MultiFernet 多密钥解密
- 轮换需停机:无法在不重启服务的情况下轮换密钥
- 手动流程:无自动化密钥轮换机制
轮换方法
方法 A:停机轮换(推荐用于小规模部署)
前提条件:
- 数据库备份能力
- 计划维护窗口
- 环境变量的 root 访问权限
步骤:
-
备份数据库
# PostgreSQLpg_dump openace > openace_backup_$(date +%Y%m%d).sql# SQLitecp app.db app_backup_$(date +%Y%m%d).db -
导出加密数据
python scripts/export_encrypted_data.py --output encrypted_data_backup.json导出内容:
api_key_store.encrypted_key→ 明文 API Keysmtp_settings.encrypted_password→ 明文 SMTP 密码model_gateway_config.encrypted_api_key→ 明文 Gateway Key
-
生成并设置新密钥
# 生成新的 32 字节密钥NEW_KEY=$(openssl rand -hex 32)echo "新密钥: $NEW_KEY"# 更新环境变量# Docker Compose: 编辑 .env 文件# Kubernetes: 更新 Secret# Systemd: 编辑 /etc/open-ace/environment -
重启服务
# Docker Composedocker-compose restart# Systemdsudo systemctl restart open-ace -
重加密并导入数据
python scripts/import_encrypted_data.py --input encrypted_data_backup.json -
验证功能
- 测试 API Key 存储和读取
- 测试 SMTP 邮件发送
- 测试 Model Gateway 调用
- 注意:现有 Proxy Token 将失效(用户需重启会话)
-
安全清理
# 验证后删除明文备份rm encrypted_data_backup.json# 可选:归档加密数据库备份gzip openace_backup_*.sql