4. 流水线中的身份与访问管理
CI/CD流水线本质上是自动化程序在代表人类执行操作。每一次代码推送、构建、测试、部署,背后都涉及一个“身份”在访问资源。如果这个身份的管理出现漏洞,攻击者就能通过流水线横向移动、窃取数据或篡改制品。本章聚焦流水线中四种核心身份与访问管理要素:服务账号、个人令牌、OIDC集成和密钥管理基础。
4.1 服务账号:流水线的“机器人身份”
服务账号(Service Account)是流水线执行任务时使用的非人类身份。与个人账号不同,服务账号不应绑定到具体员工,而是绑定到工作负载或项目。
| 特性 | 服务账号 | 个人账号 |
|---|---|---|
| 归属 | 项目/流水线/工作负载 | 自然人 |
| 生命周期 | 与项目共存亡 | 随员工入职/离职变化 |
| 权限范围 | 最小必要权限,通常只读+执行 | 可能包含管理权限 |
| 密钥轮换 | 必须定期自动轮换 | 依赖用户主动更新 |
| 审计追踪 | 操作记录明确关联流水线ID | 关联个人,但离职后难以追溯 |
安全风险警示: 许多团队直接使用个人账号的令牌作为流水线凭证。一旦该员工离职,流水线立即中断;更危险的是,离职员工的令牌可能仍有效,形成权限残留。服务账号是解决此问题的标准方案。
4.2 个人令牌:临时性与作用域控制
个人令牌(Personal Access Token, PAT)是用户身份的一种临时凭证。在流水线上下文中,PAT通常用于触发跨系统操作(如从GitHub触发Jenkins构建)。
- 最小作用域原则: 令牌只应授予完成特定任务所需的最小权限。例如,用于读取代码的令牌不应具有写入或管理权限。
- 过期时间: 所有PAT必须设置过期时间(建议不超过90天)。长期有效的令牌是重大安全隐患。
- 令牌轮换自动化: 通过脚本或密钥管理工具在令牌过期前自动生成新令牌并更新到流水线变量中。
- 禁止硬编码: 令牌绝不应出现在代码仓库、日志或构建产物中。必须通过密钥管理服务注入。
最佳实践: 在GitHub/GitLab中,为每个流水线任务创建独立的、具有明确过期时间的机器用户令牌,而非使用个人开发者的PAT。机器用户令牌的权限更容易审计和回收。
4.3 OIDC集成:消除静态密钥
OpenID Connect (OIDC) 是OAuth 2.0之上的身份层协议。在CI/CD中,OIDC允许流水线向云服务商(AWS、GCP、Azure)或第三方系统证明自己的身份,而无需存储任何长期密钥。
OIDC工作流程的核心是临时令牌交换:流水线从CI平台获取一个短期JWT,然后将其交换为目标云平台的临时凭证。
实施建议: 主流CI平台(GitHub Actions、GitLab CI、CircleCI、Jenkins)均已支持OIDC。优先为云资源访问启用OIDC集成,逐步淘汰基于静态密钥的认证方式。这是从“密钥管理”走向“零信任”的关键一步。
4.4 密钥管理基础:从存储到生命周期
密钥管理不是简单的“把密码放到变量里”。一个完整的密钥管理体系覆盖以下维度:
| 维度 | 说明 | 常见错误 |
|---|---|---|
| 存储 | 密钥必须存储在专用的密钥管理服务(KMS/Vault)中,而非CI平台的明文变量 | 将密钥写在YAML文件或Dockerfile中 |
| 传输 | 密钥在流水线内部传输时必须使用TLS加密通道 | 通过HTTP明文传递密钥 |
| 使用 | 密钥仅在运行时注入到内存中,使用后立即清除 | 将密钥写入日志或构建产物 |
| 轮换 | 密钥必须定期自动轮换,且旧密钥立即失效 | 使用永久有效的密钥,从不轮换 |
| 审计 | 每次密钥访问都应记录:谁、何时、哪个作业、访问了哪个密钥 | 没有审计日志,泄露后无法溯源 |
| 回收 | 项目下线或服务账号废弃时,密钥必须立即吊销 | 废弃项目的密钥仍有效,形成影子凭证 |
4.5 四种身份模式的对比与选择
在实际流水线中,这四种身份模式往往混合使用。以下对比表帮助你在不同场景下做出选择:
| 场景 | 推荐方案 | 不推荐方案 |
|---|---|---|
| 流水线访问云资源(AWS/GCP/Azure) | OIDC集成 + 临时凭证 | 在CI变量中存储云平台AK/SK |
| 流水线触发跨CI平台操作 | 服务账号 + 短期令牌 | 使用个人PAT |
| 流水线访问内部API/数据库 | 密钥管理服务 + 动态凭证 | 硬编码密码或API Key |
| 开发者本地调试流水线 | 个人令牌 + 最小作用域 + 短过期 | 使用生产环境服务账号 |
| 跨组织协作(第三方CI触发) | OIDC联邦 + 信任策略 | 共享静态令牌 |
4.6 密钥泄露的应急响应
即使有最好的预防措施,密钥泄露仍可能发生。以下是一旦发现密钥泄露的标准响应流程:
- 立即吊销: 在密钥管理系统中立即吊销泄露的密钥,使其失效。
- 轮换所有关联密钥: 如果泄露的密钥是服务账号的一部分,轮换该服务账号下的所有密钥。
- 审计访问日志: 检查泄露密钥在有效期内是否被异常使用,确定影响范围。
- 更新流水线配置: 确保新密钥通过安全通道注入,并检查是否有其他流水线使用了相同的泄露密钥。
- 根因分析: 密钥是如何泄露的?是日志泄露、代码仓库泄露还是员工失误?修复根本原因。
- 改进策略: 根据事件改进密钥管理策略,例如缩短密钥有效期、强制OIDC集成、增加审计告警。
自动化检测: 在流水线中集成密钥扫描工具(如GitLeaks、TruffleHog),在代码提交和构建阶段自动检测是否有密钥被意外提交。这是防止密钥泄露的第一道防线。
4.7 合规边界验证要点
在合规审计中,身份与访问管理是重点检查项。以下是针对流水线身份管理的合规验证清单:
- 服务账号清单: 是否所有服务账号都有明确的负责人、用途和过期时间?是否存在无人认领的僵尸服务账号?
- 令牌有效期: 所有个人令牌和服务账号密钥是否设置了过期时间?是否存在超过1年未轮换的密钥?
- OIDC覆盖率: 云资源访问是否已全部迁移到OIDC?是否仍有使用静态密钥的遗留配置?
- 密钥存储: 密钥是否存储在专用密钥管理服务中?CI平台的变量是否仅用于非敏感配置?
- 最小权限: 每个服务账号的权限是否经过最小权限原则审查?是否存在权限过大的服务账号?
- 审计日志: 密钥访问日志是否保留至少90天?是否配置了异常访问告警?
身份与访问管理是流水线安全的基础。从服务账号的规范化管理,到OIDC的零信任架构,再到密钥的全生命周期治理,每一步都在缩小攻击面。下一层安全防线将聚焦于代码与制品完整性——确保进入流水线的代码和产出的制品都是可信的。