fischer-agentkit/docs/deployment/key-rotation-runbook.md

298 lines
8.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Fischer AgentKit — 密钥轮换 Runbook
本文档给出全部 10 个 secret slotKTD-4 / R2a的轮换操作流程。
所有轮换遵循「双密钥并行 → 切换 → 旧密钥退役」原则,避免服务中断。
## 通用轮换原则
1. **零停机**:新密钥生效后再淘汰旧密钥,避免单点切换失败。
2. **审计先行**轮换前记录当前密钥指纹hash8轮换后校验变更。
3. **回滚预案**:保留旧密钥值至少一个轮换周期,便于快速回滚。
4. **权限最小化**:轮换操作仅限归属角色,操作全程审计日志。
5. **后端无关**:以下步骤适用于 Sealed Secrets 与 External Secrets 两种后端,
差异处单独标注。
---
## Slot 1JWT 签名密钥90 天)
**影响**:所有签发的 JWT access/refresh token 失效,用户需重新登录。
**步骤**
```bash
# 1) 生成新密钥32 字节随机串base64
NEW_KEY=$(openssl rand -base64 32)
# 2) 更新密钥后端
# Sealed Secrets
kubectl create secret generic agentkit-secrets-new --dry-run=client -o yaml \
--from-literal=jwt-signing-key="${NEW_KEY}" | \
kubeseal --controller-name=sealed-secrets --controller-namespace=kube-system \
--format yaml --merge-into agentkit-sealedsecret.yaml
# External Secrets在 Vault/SM 中更新 agentkit/jwt-signing-key
# 3) 应用并等待同步
kubectl apply -f agentkit-sealedsecret.yaml -n agentkit
kubectl rollout restart deployment/agentkit-agentkit -n agentkit
# 4) 验证
kubectl exec -n agentkit deploy/agentkit-agentkit -- \
python -c "import os; print('jwt key len:', len(os.environ['JWT_SIGNING_KEY']))"
# 5) 用户重新登录(旧 token 失效)
```
**回滚**:保留旧密钥值,若新密钥异常,恢复 SealedSecret/ExternalSecret 并 restart。
---
## Slot 2API Key180 天)
**影响**:使用旧 API Key 的客户端调用失败。
**步骤**
```bash
# 1) 生成新 API Key
NEW_KEY=$(openssl rand -hex 32)
# 2) 更新密钥后端(同 Slot 1 步骤 2key=api-key
# 3) 通知所有使用 API Key 的客户端更新agentkit pair 重新生成)
# 4) 应用并 restart
kubectl rollout restart deployment/agentkit-agentkit -n agentkit
# 5) 验证:用新 key 调用 /api/v1/auth/me 或 SCIM 端点
```
**回滚**:恢复旧 key 值。
---
## Slot 3DB 凭据 / DATABASE_URL90 天)
**影响**:数据库连接断开,需与 DBA 协同。
**步骤**
```bash
# 1) DBA 在 PostgreSQL 创建新密码(或新用户)
psql -U postgres -c "ALTER USER agentkit WITH PASSWORD 'new-pg-pwd';"
# 2) 更新 DATABASE_URL含新密码
NEW_URL="postgresql+asyncpg://agentkit:new-pg-pwd@postgres:5432/agentkit"
# 3) 更新密钥后端key=database-url
# 4) restart pod连接池重建
kubectl rollout restart deployment/agentkit-agentkit -n agentkit
# 5) 验证:触发一次 DB 操作(如 GET /api/v1/memory
# 6) DBA 回收旧密码(确认新连接正常后)
```
**注意**PostgreSQL `ALTER USER` 立即生效,旧连接保持直到连接池重建。
建议在低峰期操作。
**回滚**DBA 恢复旧密码 + 恢复 DATABASE_URL。
---
## Slot 4IDP 签名证书365 天)
**影响**OIDC/SAML 登录校验失败。多 IDP 时仅影响轮换的 IdP。
**步骤**
```bash
# 1) 从 IdP 管理后台导出新签名证书 PEM
# 2) 更新 JSON map保留其他 IdP 证书不变)
# 例如轮换 feishu 证书:
NEW_CERTS='{"feishu":"-----BEGIN CERTIFICATE-----\n新证书\n-----END CERTIFICATE-----","azure_ad":"<原证书>"}'
# 3) 更新密钥后端key=idp-signing-certs
# 4) restart pod证书热轮换不重启但 Helm 部署需 restart 加载新 Secret
kubectl rollout restart deployment/agentkit-agentkit -n agentkit
# 5) 验证:通过该 IdP 发起一次 SSO 登录
```
**回滚**:恢复旧证书 JSON map。
---
## Slot 5第三方 API Key / LLM providers90 天)
**影响**:对应 provider 的 LLM 调用失败。JSON map 结构,单 provider 轮换不影响其他。
**步骤**
```bash
# 1) 在 provider 控制台生成新 keyDashScope / DeepSeek / OpenAI / Anthropic
# 2) 更新 JSON map保留其他 provider 不变)
NEW_KEYS='{"dashscope":"sk-new1","deepseek":"sk-new2","openai":"sk-old"}'
# 3) 更新密钥后端key=third-party-api-keys
# 4) restart pod
kubectl rollout restart deployment/agentkit-agentkit -n agentkit
# 5) 验证:调用对应 provider 的模型(如 agentkit chat 发一条测试消息)
# 6) 在 provider 控制台撤销旧 key
```
**回滚**:恢复旧 key需 provider 控制台未撤销旧 key建议保留旧 key 一个周期)。
---
## Slot 6TLS 服务器证书365 天)
**影响**Ingress TLS 终止证书过期,浏览器告警 / mTLS 客户端握手失败。
**步骤**
```bash
# 1) 签发新证书cert-manager 自动续期,或手动从 CA 申请)
# cert-manager 模式:证书到期前自动续期,无需手动操作。
# 2) 若手动:更新 kubernetes.io/tls 类型 Secret
kubectl create secret tls agentkit-tls \
--cert=new.crt --key=new.key --dry-run=client -o yaml | \
kubectl apply -f - -n agentkit
# 3) Ingress controller 自动感知新证书(无需 restart
# 4) 验证
echo | openssl s_client -connect agentkit.your-domain.com:443 -servername agentkit.your-domain.com 2>/dev/null | openssl x509 -noout -dates
```
**注意**:本 slot 不在 SealedSecret/ExternalSecret 的 encryptedData 内统一管理
TLS Secret 类型为 `kubernetes.io/tls`,与普通 Secret 不同)。
SealedSecret 模板中登记仅用于清单追踪,实际由 cert-manager 或运维单独管理。
**回滚**:恢复旧证书 Secret。
---
## Slot 7mTLS 客户端证书180 天)
**影响**与下游服务KMS/HSM、内部 APImTLS 握手失败。
**步骤**
```bash
# 1) 从内部 PKI 签发新客户端证书 + 私钥 + CA 证书
# 2) 更新密钥后端key=mtls-client-certPEM 文本)
NEW_PEM="$(cat client.crt client.key ca.crt)"
# 3) 更新密钥后端
# 4) restart pod
kubectl rollout restart deployment/agentkit-agentkit -n agentkit
# 5) 验证:触发一次 mTLS 调用(如 KMS 签名操作)
```
**回滚**:恢复旧 PEM。
---
## Slot 8KMS/HSM PKCS#11 PIN365 天)
**影响**HSM 访问失败,密钥托管 / 签名 / 解密不可用。
**步骤**
```bash
# 1) HSM 管理员通过 HSM 管理工具轮换 PIN具体命令依 HSM 型号)
# 2) 更新密钥后端key=kms-hsm-pin
NEW_PIN='<new-pin>'
# 3) restart pod
kubectl rollout restart deployment/agentkit-agentkit -n agentkit
# 4) 验证:触发一次 HSM 操作(如 PKCS#11 签名)
```
**注意**HSM PIN 轮换需物理 / 管理员协同,建议提前预约维护窗口。
**回滚**:恢复旧 PINHSM 管理工具支持回滚 PIN
---
## Slot 9OTel exporter token90 天)
**影响**遥测数据上报失败trace/metrics 丢失)。服务本身不受影响。
**步骤**
```bash
# 1) 在 OTel collector / 可观测性平台生成新 token
# 2) 更新密钥后端key=otel-exporter-token格式 'Authorization: Bearer <token>'
NEW_TOKEN='Bearer new-otel-token'
# 3) restart pod
kubectl rollout restart deployment/agentkit-agentkit -n agentkit
# 4) 验证:在 collector 端确认收到新 trace/metrics
```
**回滚**:恢复旧 token。
---
## Slot 10Redis-PG 密码90 天)
**影响**Redis / PostgreSQL 连接断开。需与基础设施层协同。
**步骤**
```bash
# 1) Redis 轮换密码
redis-cli -a '<old-redis-pwd>' CONFIG SET requirepass '<new-redis-pwd>'
# 2) PostgreSQL 轮换密码DBA
psql -U postgres -c "ALTER USER agentkit WITH PASSWORD 'new-pg-pwd';"
# 3) 更新密钥后端(两个 keyredis-password + postgres-password
# 4) 更新 Redis 服务配置(若 Redis 由 docker-compose / StatefulSet 管理,
# 需同步更新 requirepass 并 restart Redis
# 5) restart agentkit pod
kubectl rollout restart deployment/agentkit-agentkit -n agentkit
# 6) 验证
kubectl exec -n agentkit deploy/agentkit-agentkit -- \
python -c "import redis,os; redis.from_url(os.environ['REDIS_URL'],password=os.environ['REDIS_PASSWORD']).ping()"
```
**注意**Redis `CONFIG SET requirepass` 立即生效,旧连接保持到断开。
建议低峰期操作,且 Redis 持久化配置redis.conf需同步更新避免重启后失效。
**回滚**:恢复 Redis / PG 旧密码 + 恢复 Secret。
---
## 紧急轮换(泄露响应)
发生密钥泄露时,立即按以下流程处置:
1. **隔离**撤销泄露密钥provider 控制台 / HSM / CA
2. **轮换**:按上述对应 slot 步骤紧急轮换
3. **审计**:检索泄露密钥的使用日志,确认无异常调用
4. **通报**:通知安全团队 + 受影响用户
5. **复盘**:记录泄露原因,加固访问控制
紧急轮换不遵循「双密钥并行」原则,直接切换到新密钥并废弃旧密钥。