第35章|GitHub Actions Secrets 与 OIDC:短期凭证访问云资源

把云账号的长期密钥塞进仓库,是“把万能钥匙复印件贴在玻璃上”——CI 一次泄露,攻击面是整朵云。 本章把路拆成两条:Secrets 在 GitHub 侧怎么存、怎么用; OIDC 怎么让 GitHub 在运行时换取短期凭证,把 AWS / Azure / GCP 的访问变成可审计、可收紧、可轮换的信任关系。

Secrets

托管与范围

  • repo / env / org
  • vars vs secrets
  • fork PR 与 secrets
OIDC

联邦信任

  • JWT from GitHub IdP
  • trust policy on cloud
  • id-token: write
Governance

治理与运维

  • least privilege IAM
  • audit & rotation
  • no secrets in logs

1. Secrets 与 Vars:谁该进保险柜?

secrets.* 存放敏感值(API key、token、私钥);vars.* 适合非敏感配置(region、feature flag)。 在仓库 Settings → Secrets and variables 中配置;Environment 可以挂更细粒度 secrets(并配合 protection rules)。

硬规则:永远不要把云长期密钥写进 YAML 或代码;日志里若出现疑似密钥,按 泄露事件 处理并轮换。
Static keys vs OIDC federation long-lived key in repo IAM user / static access key high blast radius avoid X OIDC + cloud role JWT from GitHub IdP AssumeRole / federated creds short-lived
图 1:目标是把「长期密钥进仓库」换成「运行时联邦信任 + 短期会话」。OIDC 是云厂商官方推荐的 GitHub Actions 集成路径之一。

2. OIDC 信任链:谁签发 JWT,谁验证,谁发云凭证?

GitHub Actions 作为 OpenID Connect IdP 向 job 签发 id_token(JWT)。 在 AWS 侧通过 IAM 信任策略(sts:AssumeRoleWithWebIdentity)或 Azure/GCP 的 federated credential 校验 subject / audience, 再下发短期凭证给该次 workflow run。

Workflow 必须声明 permissions: id-token: write,否则拿不到 id token。

OIDC chain: GitHub JWT → cloud trust → session GitHub Actions job requests id_token GitHub OIDC IdP signs JWT Cloud trust validate sub + aud session STS / temp Tune trust: repository, ref, environment — match your IAM trust policy
图 2:运行时链路:job 取 JWT → 云侧校验信任条件 → 下发短期凭证。密钥不再长期躺在 CI 配置里。

3. 最小权限:IAM / 角色边界与 trust 条件

在云上为 CI 单独建角色(或 workload identity),并限制: 哪个仓库哪个分支/tag哪个 environment 可以 assume。 权限只给部署所需:例如只写特定 ECR 仓库、只对某 S3 前缀 PutObject

4. AWS 示例:configure-aws-credentials + role

典型模式:仓库只保存 role ARN(可用 varssecrets,视组织策略而定), 由 action 通过 OIDC 完成 AssumeRoleWithWebIdentity

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: us-east-1
      - run: aws sts get-caller-identity

Azure / GCP 使用对应官方文档中的 federated credential 与 workload identity;思路一致:信任条件绑定 GitHub 的 OIDC 主体。

5. Secrets 分层:仓库、环境、组织

Environment secrets 适合生产:与 approvals、deployment branches 一起用。 Organization secrets 适合多仓库共享;注意范围与可见性。

Secret scopes: repo → env → org repository secrets for this repo environment prod / staging organization shared across repos
图 3:越往上(org)影响面越大;生产密钥优先放在 environment 与治理规则绑定。

6. 审计、轮换与“绝不打印 secrets”

启用云侧与 GitHub 侧审计:谁在何时 assume 了角色、哪次 workflow 触发了部署。 定期轮换仍存在的 secrets;OIDC 让长期密钥数量自然下降。

Governance loop improve audit rotate tighten
图 4:治理闭环:从审计与告警发现异常访问 → 轮换与收紧 IAM → 复盘模板与 trust 条件。

7. 最小清单

  1. 新集成优先 OIDC;避免在仓库里放长期云密钥。
  2. Workflow 加 permissions:,且 OIDC 场景必须 id-token: write
  3. 云侧 trust 条件绑定到仓库、分支、environment;IAM 权限最小化。
  4. 生产 secrets 放 environment,与审批与环境门禁一致。
  5. 禁止在日志中打印 secrets;泄露按事件流程轮换。
← 上一章:矩阵与并行(matrix) 下一章:可复用组件(composite / reusable)→