安全与密钥管理手册
最后更新:2025-11-10 · 负责人:Security/DevOps
这是 Python/FastAPI + React 技术栈的安全指引单一事实源。
1. 威胁模型速览
2. Provider 密钥生命周期
- 存储:Provider API keys 在写入 Postgres 前先使用 AES-GCM 加密。
ENCRYPTION_KEY必须是 32-byte hex 字符串,并在 backend、Celery worker、Celery beat 之间保持一致。 - 轮换节奏:至少每月轮换一次,或在发生安全事件后立即轮换。通过
PATCH /providers/{id}原子替换加密后的 payload,然后在上游 provider 侧吊销旧 key。 - 备份:
ENCRYPTION_KEY必须与数据库备份分开保存。一份存放在硬件密码管理器中,另一份放在云端 secret vault 中。每次轮换都记录到specs/4_notes.md。 - 访问边界:只有
backend和celery-worker容器应接触 provider secrets。前端构建绝不能嵌入 API keys;一律通过应用内 Provider manager 管理。
3. 应用凭据矩阵
新增变量时,请同步更新 配置说明、.env.example 和 release notes。
4. 网络与平台控制
- 分段隔离:通过反向代理(Traefik/Caddy/Nginx)暴露 FastAPI。除非必须,外部只开放
80/443(前端/代理)和22(SSH)。禁止从公网直接访问 Postgres/Redis。 - TLS:在代理层或 Kubernetes Ingress 上终止 HTTPS,并使用托管证书(ACM、Cert-Manager)。测试期至少启用
min-age ≥ 1 day的 HSTS,稳定后在生产环境提升到≥ 6 months。 - 安全头:确保启用
Strict-Transport-Security、Content-Security-Policy 'self' data: blob:、X-Frame-Options DENY、Referrer-Policy strict-origin-when-cross-origin。在specs/4_notes.md中跟踪覆盖情况。 - 容器:所有 Docker 镜像都以
eval752用户运行。Bind mount 目录应归该 UID 所有,或至少对所属组可写。如果编排平台支持,请为前端容器启用只读 root filesystem。
5. 运维护栏
- 推送前在本地运行
uvx pre-commit run -a,确保 secret 扫描器与 lint 规则和 CI 使用同一份代码树。 - CI 流水线必须从 repository/environment secrets 中获取所有敏感信息,不能把明文值写入 workflow YAML。
- 在任何非一次性环境中,必须先替换示例
.env中的占位值,再存入真实 provider keys。 - 即使使用 Docker Compose,也优先使用基础设施 secret store(AWS Secrets Manager、Azure Key Vault、Doppler、1Password Connect);通过自动化生成
.env文件挂载到服务器,而不是手工编辑。
6. 事件响应清单
- 轮换
ENCRYPTION_KEY(需要维护窗口,以便重新加密 provider keys)。执行期间建议暂停 Celery beat,避免并发条件竞争。 - 在 eval_752 中轮换受影响的 provider 凭据,并在上游彻底吊销旧 key。
- 撤销 HF/LiteLLM token,并重新生成 CI/自动化使用的服务账号。
- 重建 Docker 镜像并重新部署,确认没有残留 pod/container 仍引用被污染的 secrets。
- 在
specs/4_notes.md中记录时间线与缓解措施,并在specs/3_tasks.md中开闭相关 follow-up 任务。 - 运行
scripts/tests/run_docker_integration.sh --full-run,确认事件后系统仍满足基线能力。
7. 季度审计清单
- 确认每个环境使用独立的 Postgres 与 Redis 凭据
- 确认 vault / backup 中保存的是当前
ENCRYPTION_KEY - 审查 CI 配置,确保无明文 secrets
- 抽查日志,确认 secrets 已脱敏
- 运行容器与依赖扫描(Grype/Trivy +
pip-audit)并记录结果
