跳至主要内容

在 HashiCorp Vault 中配置 OpenID Connect

在您的工作流程中使用 OpenID Connect 来验证 HashiCorp Vault。

概述

OpenID Connect (OIDC) 允许您的 GitHub Actions 工作流程使用 HashiCorp Vault 来验证并检索密钥。

本指南概述了如何配置 HashiCorp Vault 以信任 GitHub 的 OIDC 作为联合身份,并演示了如何在 hashicorp/vault-action 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://token.actions.githubusercontent.com。这些参数允许 Vault 服务器在身份验证过程中验证收到的 JSON Web 令牌 (JWT)。

    Shell
    vault auth enable jwt
    
    Shell
    vault write auth/jwt/config \
      bound_issuer="https://token.actions.githubusercontent.com" \
      oidc_discovery_url="https://token.actions.githubusercontent.com"
    
  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 action 将 OIDC 令牌 (JWT) 交换为云访问令牌。

注意

当在工作流程或 OIDC 策略中使用环境时,我们建议为环境添加保护规则以增强安全性。例如,您可以配置环境上的部署规则,以限制哪些分支和标签可以部署到环境或访问环境密钥。更多信息,请参阅“管理部署环境”。

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

  • 授予从 GitHub OIDC 提供程序获取令牌的权限
    • 工作流程需要 permissions: 设置,其中 id-token 值设置为 write。这允许您从工作流程中的每个作业中获取 OIDC 令牌。
  • 从 GitHub OIDC 提供程序请求 JWT,并将其呈现给 HashiCorp Vault 以接收访问令牌

此示例演示了如何使用官方 action 将 OIDC 与 HashiCorp Vault 请求密钥一起使用。

添加权限设置

作业或工作流程运行需要一个 permissions 设置,其中包含 id-token: write,以允许 GitHub 的 OIDC 提供程序为每次运行创建一个 JSON Web 令牌。如果 id-tokenpermissions 未设置为 write,则您将无法请求 OIDC JWT ID 令牌,但是此值并不意味着授予对任何资源的写入访问权限,而只是能够为 action 或步骤获取和设置 OIDC 令牌,以启用使用短期访问令牌进行身份验证。任何实际的信任设置都是使用 OIDC 声明定义的,有关更多信息,请参阅“关于使用 OpenID Connect 加强安全性”。

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

  • 在运行程序上使用环境变量 (ACTIONS_ID_TOKEN_REQUEST_URLACTIONS_ID_TOKEN_REQUEST_TOKEN)。
  • 使用 Actions 工具包中的 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 令牌。

更多信息,请参阅“重用工作流程”。

注意

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

请求访问令牌

hashicorp/vault-action action 从 GitHub OIDC 提供程序接收 JWT,然后从您的 HashiCorp Vault 实例请求访问令牌以检索密钥。更多信息,请参阅 HashiCorp Vault GitHub Action 文档

此示例演示了如何创建一个从 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.

注意

  • 如果您的 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

进一步阅读