Skip to main content

在 HashiCorp Vault 中配置 OpenID Connect

在工作流程中使用 OpenID Connect 通过 HashiCorp Vault 进行身份验证。

Note

GitHub Enterprise Server 目前不支持 GitHub 托管的运行器。 可以在 GitHub public roadmap 上查看有关未来支持计划的更多信息。

概述

OpenID Connect (OIDC) 允许您的 GitHub Actions 工作流程使用 HashiCorp Vault 进行身份验证以检索机密。

本指南概述如何将 HashiCorp Vault 配置为信任作为联合标识的 GitHub 的 OIDC,并演示如何在 hashicorp/vault-action 操作中使用此配置从 HashiCorp Vault 检索机密。

先决条件

  • 若要了解 GitHub 如何使用 OpenID Connect (OIDC) 及其体系结构和优势的基本概念,请参阅“关于使用 OpenID Connect 进行安全强化”。

  • 在继续之前,必须规划安全策略,以确保仅以可预测的方式分配访问令牌。 要控制云提供商颁发访问令牌的方式,必须至少定义一个条件,以便不受信任的存储库无法为云资源请求访问令牌。 有关详细信息,请参阅“关于使用 OpenID Connect 进行安全强化”。

将身份提供商添加到 HashiCorp Vault

要将 OIDC 与 HashiCorp Vault 配合使用,您需要为 GitHub OIDC 提供商添加信任配置。 有关详细信息,请参阅 HashiCorp Vault 文档

将 Vault 服务器配置为接受 JSON Web 令牌 (JWT) 进行身份验证:

  1. 启用 JWT auth 方法,并使用 write 将配置应用于 Vault。 对于 oidc_discovery_urlbound_issuer 参数,请使用 https://HOSTNAME/_services/token。 这些参数使 Vault 服务器可以在身份验证过程中验证收到的 JSON Web 令牌 (JWT)。

    Shell
    vault auth enable jwt
    
    Shell
    vault write auth/jwt/config \
      bound_issuer="https://HOSTNAME/_services/token" \
      oidc_discovery_url="https://HOSTNAME/_services/token"
    
  2. 配置策略以便仅授予对工作流将用于检索机密的特定路径的访问权限。 有关更高级的策略,请参阅 HashiCorp Vault 策略文档

    Shell
    vault policy write myproject-production - <<EOF
    # Read-only permission on 'secret/data/production/*' path
    
    path "secret/data/production/*" {
      capabilities = [ "read" ]
    }
    EOF
    
  3. 配置角色以将不同策略分组在一起。 如果身份验证成功,这些策略会附加到生成的 Vault 访问令牌。

    Shell
    vault write auth/jwt/role/myproject-production -<<EOF
    {
      "role_type": "jwt",
      "user_claim": "actor",
      "bound_claims": {
        "repository": "user-or-org-name/repo-name"
      },
      "policies": ["myproject-production"],
      "ttl": "10m"
    }
    EOF
    
  • ttl 定义所生成的访问令牌的有效性。
  • 确保针对安全要求定义 bound_claims 参数,并且该参数至少有一个条件。 (可选)还可以设置 bound_subjectbound_audiences 参数。
  • 为了检查收到的 JWT 有效负载中的任意声明,bound_claims 参数包含一组声明及其所需值。 在上面的示例中,角色会接受来自 user-or-org-name 帐户拥有的 repo-name 存储库的任何传入身份验证请求。
  • 若要查看 GitHub 的 OIDC 提供商支持的所有可用声明,请参阅“关于使用 OpenID Connect 进行安全强化”。

有关详细信息,请参阅 HashiCorp Vault 文档

更新 GitHub Actions 工作流程

要更新 OIDC 的工作流程,您需要对 YAML 进行两项更改:

  1. 为令牌添加权限设置。
  2. 使用操作 hashicorp/vault-action 将 OIDC 令牌 (JWT) 交换为云访问令牌。

Note

在工作流或 OIDC 策略中使用环境时,建议将保护规则添加到环境中以提高安全性。 例如,可以在环境中配置部署规则,以限制可以部署到环境或访问环境机密的分支和标记。 有关详细信息,请参阅“管理部署环境”。

要将 OIDC 集成添加到您的工作流程中,以允许他们访问 Vault 中的密钥,您需要添加以下代码更改:

  • 授予从 GitHub OIDC 提供程序提取令牌的权限:
    • 工作流需要将 id-token 值设置为 writepermissions: 设置。 这样,便可以从工作流中的每个作业中提取 OIDC 令牌。
  • 向 GitHub OIDC 提供商请求 JWT,并将其提供给 HashiCorp Vault 以接收访问令牌:

此示例演示如何将 OIDC 与官方操作结合使用,以向 HashiCorp Vault 请求机密。

添加权限设置

作业或工作流运行需要使用 id-token: writepermissions 设置,以允许 GitHub 的 OIDC 提供程序为每个运行创建 JSON Web 令牌。 如果 id-tokenpermissions 未设置为 write,则无法请求 OIDC JWT ID 令牌,但是此值并不表示授予对任何资源的写权限,而只能提取和设置操作或步骤的 OIDC 令牌,以启用通过短期访问令牌进行身份验证。 任何实际信任设置均通过 OIDC 声明定义,有关详细信息,请参阅“关于使用 OpenID Connect 进行安全强化”。

id-token: write 设置允许使用下列方法之一从 GitHub 的 OIDC 提供程序请求 JWT:

  • 在运行器上使用环境变量(ACTIONS_ID_TOKEN_REQUEST_URLACTIONS_ID_TOKEN_REQUEST_TOKEN)。
  • 使用“操作”工具包中的 getIDToken()

如果需要为工作流提取 OIDC 令牌,则可以在工作流级别设置权限。 例如:

YAML
permissions:
  id-token: write # This is required for requesting the JWT
  contents: read  # This is required for actions/checkout

如果只需要为单个作业提取 OIDC 令牌,则可在该作业中设置此权限。 例如:

YAML
permissions:
  id-token: write # This is required for requesting the JWT

可能需要在此处指定额外权限,具体取决于你的工作流要求。

对于与调用方工作流属于同一用户、组织或企业的可重用工作流,可以从调用方的上下文访问在可重用工作流中生成的 OIDC 令牌。 对于企业或组织外部的可重用工作流,应在调用方工作流级别或在调用可重用工作流的特定作业中将 id-tokenpermissions 设置显式设置为 write。 这可确保仅允许可重用工作流中生成的 OIDC 令牌按预期在调用方工作流中使用。

有关详细信息,请参阅“重新使用工作流”。

Note

使用 permissions 密钥时,所有未指定的权限都设置为无访问权限,但元数据范围除外,它始终拥有读取访问权限 。 因此,可能需要添加其他权限,例如 contents: read。 有关详细信息,请参阅自动令牌身份验证

请求访问令牌

hashicorp/vault-action 操作从 GitHub OIDC 提供程序接收 JWT,然后从 HashiCorp Vault 实例请求访问令牌以检索机密。 有关详细信息,请参阅 HashiCorp Vault GitHub 操作文档

此示例演示如何创建从 HashiCorp Vault请求机密的作业。

  • VAULT-URL:将此替换为 HashiCorp Vault 的 URL。
  • VAULT-NAMESPACE:将此值替换为在 HashiCorp Vault 中设置的命名空间。 例如:admin
  • ROLE-NAME:将此值替换为在 HashiCorp Vault 信任关系中设置的角色。
  • SECRET-PATH:将此值替换为从 HashiCorp Vault 检索的机密的路径。 例如:secret/data/production/ci npmToken
YAML
jobs:
  retrieve-secret:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - name: Retrieve secret from Vault
        uses: hashicorp/vault-action@9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b
        with:
          method: jwt
          url: VAULT-URL
          namespace: VAULT-NAMESPACE # HCP Vault and Vault Enterprise only
          role: ROLE-NAME
          secrets: SECRET-PATH

      - name: Use secret from Vault
        run: |
          # This step has access to the secret retrieved above; see hashicorp/vault-action for more details.

Note

  • 如果无法从公共网络访问 Vault 服务器,请考虑将自承载运行程序与其他可用 Vault 身份验证方法配合使用。 有关详细信息,请参阅“关于自托管运行程序”。
  • 必须针对 Vault Enterprise(包括 HCP Vault)部署设置 VAULT-NAMESPACE。 有关详细信息,请参阅 Vault 命名空间

撤销访问令牌

默认情况下,Vault 服务器会在 TTL 过期时自动撤销访问令牌,因此无需手动撤销访问令牌。 但是,如果确实要在作业完成或失败后立即撤销访问令牌,则可以使用 Vault API 手动撤销颁发的令牌。

  1. exportToken 选项设置为 true(默认值:false)。 这会将颁发的 Vault 访问令牌导出为环境变量:VAULT_TOKEN
  2. 添加一个步骤以调用撤销令牌(自行) Vault API 来撤销访问令牌。
YAML
jobs:
  retrieve-secret:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - name: Retrieve secret from Vault
        uses: hashicorp/vault-action@9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b
        with:
          exportToken: true
          method: jwt
          url: VAULT-URL
          role: ROLE-NAME
          secrets: SECRET-PATH

      - name: Use secret from Vault
        run: |
          # This step has access to the secret retrieved above; see hashicorp/vault-action for more details.

      - name: Revoke token
        # This step always runs at the end regardless of the previous steps result
        if: always()
        run: |
          curl -X POST -sv -H "X-Vault-Token: ${{ env.VAULT_TOKEN }}" \
            VAULT-URL/v1/auth/token/revoke-self

延伸阅读