| 维度 | 企业做法 | 我们 | 评价 |
|---|---|---|---|
| 部署凭据 | OIDC 联合身份,无长期密钥 | 长期 ed25519 + forced command | ⚠️ 落后,但裸 VPS 无IAM 可联合 |
| 镜像引用 | digest 钉死 | digest 钉死 | ✅ 很多团队还在部署 :latest |
| 镜像可信 | cosign 签名 + SLSA 溯源 + 准入控制拒绝未签名 | 仅 Trivy 扫描 | ❌ 最值得补的一项 |
| 密钥管理 | Vault / Secrets Manager,可轮换可审计 | 服务器上一个 600 的明文文件 | ❌ 最弱环节 |
| 审批 | 变更管理 + 职责分离(作者不能批自己的) | 必需审批人(同一人) | 单人项目的固有限制 |
| 发布策略 | 金丝雀/蓝绿 + SLO 自动回滚 | up -d 硬切换 | 单节点单用户,金丝雀无意义 |
| 版本可追溯 | 部署标记打进 APM | 构建→标签→healthz→metrics→部署后核验 | ✅ 比多数小团队做得好 |
| 数据库迁移 | 独立步骤 + expand-contract | 容器启动时 alembic upgrade head | ❌ 公认反模式 |
IAM联合是什么?
文章目录
- IAM 联合(OIDC Federation)
- IAM(Identity and Access Management)
- OIDC 联合(OpenID Connect Federation)
- 为什么这比我们好?
- 为什么我们暂时不这么做?
IAM 联合(OIDC Federation)
这是企业级部署中解决"CI 怎么安全地拿到部署权限"的标准做法。拆开来说:
IAM(Identity and Access Management)
云厂商提供的身份与权限管理系统。核心能力:
- 创建角色(Role):一组权限,比如"可以拉镜像"、“可以部署到 K8s 集群”
- 临时凭证(Temporary Credentials):不是长期密钥,而是有效期很短(比如 15 分钟)的 token
- 策略(Policy):精确控制谁能做什么
OIDC 联合(OpenID Connect Federation)
让 CI 平台(如 GitHub Actions)和云平台的 IAM 互相信任,不需要给 CI 发任何密钥。
工作流程:
1. GitHub Actions 运行 workflow ↓ 2. GitHub 发一个 OIDC token 给 workflow (token 里写着:这个 job 来自 repo X 的 branch Y,由 workflow Z 触发) ↓ 3. Workflow 拿着这个 token 去找云平台的 IAM ↓ 4. IAM 验证 token 的签名(信任 GitHub 是合法的 token 发行方) ↓ 5. IAM 检查:repo X 的 branch Y 是否被允许扮演角色 R? ↓ 6. 如果允许 → 发放临时凭证(有效期 15 分钟) ↓ 7. Workflow 用临时凭证执行部署 ↓ 8. 凭证自动过期,即使泄露也无法使用为什么这比我们好?
| OIDC 联合(企业) | 我们的做法 | |
|---|---|---|
| 凭证类型 | 临时 token,自动过期 | 长期 ed25519 密钥 |
| 泄露后果 | 最多 15 分钟有效 | 永久有效,直到手动轮换 |
| 权限粒度 | 可以限制到"只有 main 分支的这条 workflow 能部署" | 密钥要么能用要么不能用 |
| 密钥管理 | 根本没有密钥需要管理 | 密钥存在 GitHub Secrets 里 |
为什么我们暂时不这么做?
因为我们部署目标是裸 VPS。裸 VPS 没有 IAM 系统——它就是 SSH 登录。你不能让 VPS 去验证一个 OIDC token 然后给你临时 SSH 权限(至少没有现成的、简单的基础设施来做这件事)。
如果将来迁移到托管 K8s(EKS/GKE/AKS),OIDC 联合就是自然的选择,因为云平台原生支持它。但在裸 VPS 上,SSH 密钥 + forced command 已经是在没有 IAM 的情况下能做到的最合理的方案了。
一句话总结:裸 VPS 是一台只有 SSH 的远程机器,IAM 联合是让 CI 不用拿长期密钥就能安全部署的机制——前者限制了后者,所以我们用长期密钥 + forced command 来弥补。