1d85329a6a
Build and Test Quality Gate / Contract Web typecheck and build (pull_request) Successful in 9m12s
Build and Test Quality Gate / Isolated Alibaba and Tencent KMS gateway (pull_request) Failing after 4m53s
Build and Test Quality Gate / Python tests and Contract API migration (pull_request) Failing after 24m55s
Security Quality Gate / npm audit, Bandit, pip-audit, detect-secrets (pull_request) Failing after 8m42s
150 lines
8.1 KiB
Markdown
150 lines
8.1 KiB
Markdown
# 企业 Playbook 云 KMS 重包裹与故障演练手册
|
||
|
||
版本:`2026-08-25.p1-04.9.2`
|
||
适用范围:企业日历凭据从旧本地 Fernet 密文迁移到阿里云 KMS 或腾讯云 KMS,以及托管不可用和 SLO 外部升级通知演练。跨两个外部托管后端迁移需要同时保留来源适配器,不属于本批处理范围。
|
||
|
||
## 1. 角色与安全原则
|
||
|
||
- 租户管理员:创建清单、审批迁移窗口、选择通知演练通道。
|
||
- 平台运维:部署 KMS Gateway、配置私网/TLS/服务 token、运行 Worker、处理托管错误。
|
||
- 安全管理员:创建最小权限 CMK 与云身份、保管 ClientKey/API 凭据、批准旧恢复密钥撤除。
|
||
- 事故负责人:接管失败任务和通知死信,不通过数据库直接标记成功。
|
||
|
||
任何日志、工单、截图、报告和 API 响应都不得包含明文、完整密文、ClientKey、密码、SecretKey、服务 token 或旧 Fernet key。只使用任务 ID、字段指纹、提供方 RequestId 和脱敏错误分类协作。
|
||
|
||
## 2. 部署选择
|
||
|
||
阿里云部署叠加:
|
||
|
||
```text
|
||
docker-compose.production.yml
|
||
docker-compose.production.kms-aliyun.yml
|
||
```
|
||
|
||
腾讯云部署叠加:
|
||
|
||
```text
|
||
docker-compose.production.yml
|
||
docker-compose.production.kms-tencent.yml
|
||
```
|
||
|
||
两套 overlay 不得同时启用。网关不对公网暴露,只允许合同 API、治理 Worker 和受控运维探针访问。
|
||
|
||
### 阿里云文件材料
|
||
|
||
- KMS 实例专属 endpoint。
|
||
- 只允许目标 CMK encrypt/decrypt 的 ClientKey JSON。
|
||
- 独立 ClientKey 密码文件。
|
||
- KMS 实例 CA 文件。
|
||
- 网关服务 token、网关 TLS 证书和私钥。
|
||
|
||
### 腾讯云文件材料
|
||
|
||
腾讯云凭据文件必须为只读 JSON:
|
||
|
||
```json
|
||
{"secret_id":"REPLACE_AT_DEPLOYMENT","secret_key":"REPLACE_AT_DEPLOYMENT","token":"OPTIONAL_STS_TOKEN"}
|
||
```
|
||
|
||
优先使用短期 STS 凭据;若部署体系只能使用长期子账号密钥,必须限制到指定 KMS 操作、纳入轮换并禁止复用到其他服务。
|
||
|
||
## 3. 上线前检查
|
||
|
||
1. 校验凭据文件属主和权限;容器内只读挂载,应用配置只引用路径。
|
||
2. 校验 `KMS_GATEWAY_ALLOWED_KEY_IDS` 只包含本平台 CMK。
|
||
3. 校验 endpoint、region、DNS、私网路由、证书主机名和 CA 链。
|
||
4. `/health` 必须显示正确 provider、`configured=true`、`fail_closed=true`,但该结果不代替加解密测试。
|
||
5. 在管理端执行即时恢复演练,再执行持久化 canary;记录演练 ID、RequestId、耗时与摘要匹配。
|
||
6. 若任一检查失败,不启用批量 `execute`,也不删除旧恢复 key。
|
||
|
||
## 4. 批量重包裹操作
|
||
|
||
### 4.1 只盘点
|
||
|
||
在管理端填写至少八个字符的变更原因,选择“只盘点并生成证据”。核对:
|
||
|
||
- 租户与目标 backend/key reference 正确。
|
||
- 总数符合日历源和未过期 OAuth state 的预期。
|
||
- 清单只含允许的表和字段,来源 backend 合理。
|
||
- 任务状态为 `inventory_complete`,业务数据指纹没有变化。
|
||
|
||
### 4.2 小批执行
|
||
|
||
1. 在低峰期选择批次 1–10 创建 `execute`。
|
||
2. Worker 领取任务后应进入 `running`,字段依次变为 `rewrapped`、`skipped` 或 `failed`。
|
||
3. `rewrapped` 表示已完成旧解密、新托管加密、新托管回读和乐观指纹校验。
|
||
4. `skipped` 常见于业务并发更新;重新盘点后再迁移,不覆盖新值。
|
||
5. `failed` 必须按错误分类修复外部条件后使用 `retry_failed`;不得修改任务计数。
|
||
|
||
### 4.3 暂停、取消与恢复
|
||
|
||
- `pause`:停止后续批次,已完成字段不回滚。
|
||
- `resume`:从仍为 queued/planned 的字段继续。
|
||
- `cancel`:只取消未处理字段,已重包裹字段保持有效。
|
||
- `retry_failed`:仅重置失败字段并保留旧尝试证据。
|
||
|
||
完成标准:`succeeded + failed + skipped = total`,且业务连接抽查、恢复 canary、同步试运行全部通过。
|
||
|
||
## 5. 托管不可用故障演练
|
||
|
||
管理端提供三种隔离模拟,不会关闭真实云服务:
|
||
|
||
| 场景 | 预期分类 | 必须结果 |
|
||
|---|---|---|
|
||
| `timeout` | timeout | 新凭据写入被阻止,密文字段数与摘要不变 |
|
||
| `authorization` | authorization | 不回退本地密钥,不扩大权限,不写入 |
|
||
| `provider_unavailable` | provider_unavailable | 不静默降级,保留失败演练证据 |
|
||
|
||
成功判定必须同时满足 `write_blocked=true`、演练前后 count 一致、aggregate digest 一致。仅显示“发生了预期错误”但摘要变化,应按安全事故处理。
|
||
|
||
真实断网/禁权演练应只在隔离预发布进行:先暂停 Worker,备份任务和连接证据,按变更单撤销网络或权限,执行受控写入探针,恢复外部条件后运行 canary,再恢复 Worker。不得在生产直接删除 CMK、ClientKey 或密文。
|
||
|
||
## 6. SLO 外部升级通知演练
|
||
|
||
1. 建立专用测试 webhook/邮箱通道,启用并完成握手。
|
||
2. 确认事件订阅包含 `playbook_calendar_slo_escalated`。
|
||
3. 先执行 `dry_run`;预期 `succeeded` 且 `external_side_effect=false`。
|
||
4. 确认接收方值班人员和时间窗口后执行“真实入队演练”;前端使用固定确认短语。
|
||
5. 预期先为 `queued`,随后由通知 Worker 更新为 `delivered`;接收内容必须带演练标识。
|
||
6. 若为 `retry_scheduled`,检查网络、握手、签名和接收方状态;若进入 `dead_letter`,由事故负责人接管并保存外部工单。
|
||
|
||
严禁选择真实客户群发通道进行首次演练。演练通知不得伪装成真实事故,也不得绕过通道握手与事件订阅门禁。
|
||
|
||
## 7. 错误分类与处置
|
||
|
||
| 分类 | 自动重试 | 处置 |
|
||
|---|---|---|
|
||
| `authorization` | 否 | 检查云身份、CMK policy、ClientKey/STS 有效性;按最小权限修复 |
|
||
| `configuration` | 否 | 检查文件路径、endpoint、region、CA、key allowlist 和 encryption context |
|
||
| `invalid_request` | 否 | 核对 key ID、密文 envelope 与 4 KiB 限制,不篡改密文重试 |
|
||
| `invalid_response` | 否 | 暂停迁移,保存 RequestId,向云厂商升级并补回归样本 |
|
||
| `timeout` | 有限 | 检查国内私网、DNS、TLS 和 SDK 超时;指数退避后转人工 |
|
||
| `rate_limit` | 有限 | 降低 Worker 批次和并发,按云限额退避 |
|
||
| `provider_unavailable` | 有限 | 确认云状态与网络;保持 fail-closed,不回退本地加密 |
|
||
| `provider_error` | 谨慎 | 依据脱敏云错误码和 RequestId 分类,未知错误先暂停批量任务 |
|
||
|
||
## 8. 回退与旧密钥撤除
|
||
|
||
- 外部托管失败时暂停重包裹;已成功字段可继续由当前 KMS 解密,不把它们改回本地密钥。
|
||
- 旧密文依赖独立 legacy recovery key 双读;该文件只能保留到所有清单项完成、失败闭环、恢复 canary 与业务抽查通过。
|
||
- 撤除前创建最终 `inventory`,目标应没有仍需迁移的旧后端项;保存任务 ID 和审批记录。
|
||
- 撤除后再次执行持久化 canary 与日历同步试运行。失败时从批准的密钥备份恢复文件,不在代码或环境变量中粘贴 key。
|
||
- CMK 删除保护、轮换周期、跨区备份和恢复由云安全流程负责;应用批处理不替代云密钥生命周期治理。
|
||
|
||
## 9. 交接证据
|
||
|
||
- 部署版本、provider、region、脱敏 endpoint、CMK 引用和 key allowlist 摘要。
|
||
- 网关健康时间、恢复演练 ID、云 RequestId、摘要匹配与耗时。
|
||
- 重包裹任务 ID、总数、成功/失败/跳过、失败分类和人工动作。
|
||
- 托管故障演练 ID、场景、前后 count/digest 与零写入结论。
|
||
- SLO 演练 ID、通道 ID、通知/投递 ID、最终投递状态和外部工单。
|
||
- legacy recovery key 撤除审批与撤除后的 canary 结果。
|
||
|
||
## 10. 官方依据
|
||
|
||
- 阿里云 KMS 实例 SDK for Python:<https://help.aliyun.com/en/kms/key-management-service/developer-reference/kms-instance-sdk-for-python/>
|
||
- 阿里云 KMS SDK 用户指南:<https://help.aliyun.com/en/kms/key-management-service/developer-reference/sdk-user-guide/>
|
||
- 腾讯云 KMS Python SDK:<https://cloud.tencent.com/document/product/573/38366>
|
||
- 腾讯云 Encrypt API:<https://cloud.tencent.com/document/api/573/34420>
|
||
- 腾讯云 Decrypt API:<https://cloud.tencent.com/document/product/573/34429>
|