4、CI/CD流水线中的身份与访问管理:服务账号管理、密钥管理、OIDC集成、短期凭证最佳实践

在平台工程视角下,CI/CD流水线的身份与访问管理(IAM)是权限模型落地的核心执行层。流水线在执行构建、测试、部署时,需要以非人身份(Non-Person Identity)访问各类目标系统(代码仓库、制品库、Kubernetes集群、云服务API)。本章聚焦服务账号生命周期、密钥托管策略、OIDC联邦集成以及短期凭证的工程化实践。

4.1 服务账号管理:从静态凭据到身份边界

服务账号是流水线在目标系统中的“数字身份”。传统做法是将云服务商的长期访问密钥(Access Key/Secret Key)直接写入流水线变量,这种做法存在严重的安全风险:密钥泄露后无法快速轮转、权限范围难以追溯、无法实施最小权限原则。

平台工程核心原则: 每个流水线执行单元(Pipeline Run)应拥有独立的、临时的、权限受限的身份,而非共享一个长期有效的服务账号。

服务账号管理的关键维度对比:

维度 传统静态账号 平台工程推荐模式
生命周期 长期有效(月/年) 按需创建,执行结束后自动销毁
权限粒度 粗粒度(项目/环境级别) 细粒度(仅本次部署所需资源)
密钥存储 明文变量/硬编码 密钥管理服务(KMS/Vault)
审计追溯 难以定位到具体流水线 通过身份标签关联到Pipeline Run ID
轮转策略 手动轮转,易遗漏 自动轮转,与流水线触发绑定

4.2 密钥管理:分层存储与动态注入

密钥(Secrets)包括数据库密码、API令牌、TLS证书、云服务密钥等敏感信息。在CI/CD流水线中,密钥管理必须遵循“零信任”原则:流水线运行时按需获取,运行结束后立即失效。

推荐的密钥管理分层架构:

  1. 第一层:外部密钥引擎 — 使用HashiCorp Vault、AWS Secrets Manager、Azure Key Vault等专用服务作为密钥的单一可信源。
  2. 第二层:平台代理层 — 平台工程团队构建密钥代理服务(Secret Broker),负责从外部引擎获取密钥并注入到流水线上下文,避免流水线直接访问密钥引擎。
  3. 第三层:运行时注入 — 通过环境变量、临时卷挂载或Sidecar模式将密钥注入到构建/部署容器,确保密钥不在日志或持久化存储中留下痕迹。
实践建议: 禁止在流水线YAML中直接引用密钥明文。使用类似 ${SECRET_ARN} 的引用方式,由平台运行时在启动前解析并注入。

密钥管理常见陷阱与规避:

  • 陷阱1: 将密钥放在构建日志中打印 — 应在构建工具中配置密钥脱敏规则(如GitHub Actions的::add-mask::)。
  • 陷阱2: 密钥轮转导致流水线中断 — 平台应提供密钥版本管理,流水线通过版本号引用,轮转时自动切换。
  • 陷阱3: 跨环境密钥混用 — 开发/测试/生产环境的密钥必须物理隔离,通过环境标签强制绑定。

4.3 OIDC集成:消除长期密钥的联邦身份模式

OpenID Connect(OIDC)是解决CI/CD流水线长期密钥问题的关键协议。通过OIDC,流水线可以在运行时向云服务商或目标系统证明自己的身份,无需预置任何静态密钥。

OIDC集成的工作流程:

  1. 流水线触发时,CI/CD平台(如GitHub Actions、GitLab CI、Jenkins)向自身的OIDC提供商请求一个短期身份令牌(ID )。
  2. 该ID 包含流水线的唯一标识(如仓库名、环境、分支、Run ID)。
  3. 流水线使用该ID 向目标云服务(AWS、GCP、Azure、Kubernetes)请求临时凭证。
  4. 目标云服务验证ID 的签名和声明(Claims),如果匹配预先配置的信任策略,则颁发临时访问凭证。
安全注意: OIDC信任策略必须严格限定。例如,在AWS IAM OIDC身份提供商中,应使用 sub 和 aud 声明精确匹配到具体的仓库、环境甚至分支,避免同一CI平台的所有流水线都能获取高权限凭证。

主流CI/CD平台的OIDC配置对比:

平台 OIDC提供商URL 常用声明(Claims) 令牌有效期
GitHub Actions .actions.githubusercontent.com sub: repo:org/repo:ref:refs/heads/main 5分钟
GitLab CI gitlab.com project_path: group/project, ref_type: branch 1小时
Jenkins (OIDC Plugin) 自定义Jenkins URL jenkins_job: job/pipeline-name 可配置(建议≤15分钟)
CI/CD流水线OIDC集成流程 CI/CD流水线OIDC集成与短期凭证获取流程 CI/CD平台 (GitHub/GitLab/Jenkins) OIDC提供商 (平台内置) 目标云服务 (AWS/GCP/K8s) 请求ID 返回ID 携带ID 请求凭证 信任策略验证 签名 + Claims匹配 转发验证 验证通过 短期凭证 有效期:5~60分钟 返回临时AK/SK或 关键说明: • 流水线无需存储任何长期密钥,身份证明由OIDC ID 提供。 • 信任策略在目标云服务侧配置,可精确到仓库、分支、环境。 • 短期凭证自动过期,即使泄露,攻击者利用窗口极短。

4.4 短期凭证最佳实践:最小化暴露窗口

短期凭证(Short-lived Credentials)是OIDC集成的自然产物,但即使在没有OIDC的场景下,平台工程团队也应主动设计凭证生命周期管理策略。

短期凭证的核心优势:

  • 自动过期: 凭证在预设时间后自动失效,无需手动撤销。
  • 降低泄露影响: 即使凭证在流水线日志中被意外打印,攻击者获取时可能已过期。
  • 强制轮转: 每次流水线执行都获取新凭证,天然实现轮转。
  • 审计绑定: 凭证颁发时可嵌入流水线Run ID,便于事后追溯。
平台工程度量指标: 建议将“流水线中长期密钥的使用比例”作为平台安全成熟度的关键指标,目标值应低于5%。超过该比例的流水线应触发平台告警并强制迁移至OIDC或短期凭证模式。

短期凭证的工程化实现路径:

实现方式 适用场景 凭证类型 推荐有效期
AWS STS AssumeRole 部署到AWS的流水线 临时AK/SK + SessionToken 15分钟~1小时
GCP Workload Identity Federation 部署到GCP的流水线 OAuth 2.0 Access 1小时(可刷新)
Azure Federated Identity Credential 部署到Azure的流水线 Azure AD 1小时
Kubernetes TokenRequest API 部署到K8s的流水线 ServiceAccount (绑定了Pod) 1小时(默认)
HashiCorp Vault Dynamic Secrets 数据库/中间件访问 数据库用户名/密码(动态生成) 7天(可配置更短)

4.5 平台工程视角的落地检查清单

在实施CI/CD流水线身份与访问管理时,平台工程团队应逐项确认以下实践是否到位:

  1. 服务账号映射: 每个流水线是否映射到唯一的服务账号或身份,而非共享账号?
  2. 密钥零存储: 流水线配置中是否不存在任何明文密钥或长期访问密钥?
  3. OIDC覆盖度: 是否所有云服务/目标系统的访问都通过OIDC联邦实现?
  4. 凭证有效期: 所有临时凭证的有效期是否控制在1小时以内?
  5. 信任策略最小化: OIDC信任策略是否精确到仓库、分支、环境级别?
  6. 密钥轮转自动化: 对于无法使用短期凭证的场景(如第三方),是否实现了自动轮转机制?
  7. 审计日志: 每次凭证颁发和访问是否记录了流水线Run ID、操作人和目标资源?
平台工程自动化建议: 构建一个“流水线安全扫描”工具,在每次流水线执行前自动检查配置中是否存在长期密钥、是否启用了OIDC、凭证有效期是否合规。将检查结果作为流水线的一个阶段,不通过则阻断执行。

通过上述实践,平台工程团队可以将CI/CD流水线的身份安全从“静态、共享、难追溯”转变为“动态、唯一、可审计”,为整个服务目录权限模型提供坚实的执行层保障。