Skip to main content

HashiCorp Vault での OpenID Connect の構成

ワークフロー内で OpenID Connect を使用して HashiCorp Vault で認証します。

概要

OpenID Connect (OIDC) を使うと、GitHub Actions ワークフローが HashiCorp Vault で認証し、シークレットを取得できます。

このガイドでは、HashiCorp Vault が GitHub の OIDC をフェデレーション ID として信頼するように構成する方法の概要について説明します。また、この構成を hashicorp/vault-action アクションで使って HashiCorp Vault からシークレットを取得する方法を示します。

前提条件

  • GitHub が OpenID Connect (OIDC) を使用する方法の基本的な概念とそのアーキテクチャと利点については、「OpenID Connect を使ったセキュリティ強化について」を参照してください。

  • 先に進む前に、アクセス トークンが予測可能な方法でのみ割り当てられるようにセキュリティ戦略を計画する必要があります。 クラウド プロバイダーがアクセス トークンを発行する方法を制御するには、少なくとも 1 つの条件を定義し、信頼できないリポジトリがクラウド リソースにアクセス トークンを要求できないようにする必要があります。 詳しくは、「OpenID Connect を使ったセキュリティ強化について」を参照してください。

HashiCorp Vault への ID プロバイダーの追加

HashiCorp Vault と共に OIDC を使うには、GitHub OIDC プロバイダーの信頼構成を追加する必要があります。 詳細については、HashiCorp Vault のドキュメントを参照してください。

認証に JSON Web トークン (JWT) を受け入れるように Vault サーバーを構成します。

  1. JWT auth メソッドを有効にし、write を使用して Vault に構成を適用します。 oidc_discovery_url および bound_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 パラメーターがセキュリティ要件に対して定義されており、少なくとも 1 つの条件があることを確認します。 必要に応じて、bound_subject だけでなく、bound_audiences パラメーターも設定できます。
  • 受信した JWT ペイロード内の任意の要求を確認するために、bound_claims パラメーターには一連の要求とその必須の値が含まれています。 上記の例では、ロールは、user-or-org-name アカウントによって所有される repo-name リポジトリからの受信認証要求を受け取ります。
  • GitHub の OIDC プロバイダーでサポートされているすべての可能な要求を確認するには、「OpenID Connect を使ったセキュリティ強化について」をご覧ください。

詳細については、HashiCorp Vault のドキュメントを参照してください。

GitHub Actions ワークフローを更新する

OIDC のワークフローを更新するには、YAML に 2 つの変更を行う必要があります。

  1. トークンのアクセス許可設定を追加します。
  2. この hashicorp/vault-action アクションを使って、OIDC トークン (JWT) をクラウド アクセス トークンと交換します。

独自のカスタム保護規則を有効にして、サードパーティ サービスを使ったデプロイを制御できます。 たとえば、Datadog、Honeycomb、ServiceNow などのサービスを使用し、GitHub への展開に対して自動承認を提供できます。

Vault のシークレットにアクセスできるようにワークフローに OIDC 統合を追加するには、次のコード変更を追加する必要があります。

  • GitHub OIDC プロバイダーからトークンをフェッチするアクセス許可を付与します。
    • ワークフローには、id-token の値が write に設定された permissions: 設定が必要です。 これにより、ワークフロー内のすべてのジョブから OIDC トークンをフェッチすることができます。
  • GitHub OIDC プロバイダーに JWT を要求し、それを HashiCorp Vault に提示してアクセス トークンを受け取ります。
    • hashicorp/vault-action アクションを使って、JWT をフェッチし、Vault からアクセス トークンを受け取ることができます。または、Actions ツールキットを使ってジョブのトークンをフェッチすることもできます。

この例は、HashiCorp Vault からシークレットを要求するために、公式のアクションと共に OIDC を使う方法を示しています。

アクセス許可設定の追加

ジョブまたはワークフローの実行には、GitHub の OIDC プロバイダーが実行ごとに JSON Web Token を作成できるようにするために、id-token: write を含む permissions 設定が必要です。 id-tokenpermissionswrite に設定されていない場合、OIDC JWT ID トークンを要求することはできません。ただし、この値はリソースへの書き込みアクセスを許可することを意味せず、アクションまたはステップの OIDC トークンをフェッチして設定し、有効期間の短いアクセス トークンを使用して認証を有効にできるだけです。 実際の信頼の設定は OIDC 要求を使用して定義されます。詳細については、「OpenID Connect を使ったセキュリティ強化について」を参照してください。

この id-token: write 設定により、次のいずれかの方法を使用して、GitHub の OIDC プロバイダーから JWT を要求できます。

  • ランナーで環境変数を使用する (ACTIONS_ID_TOKEN_REQUEST_URL および ACTIONS_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

1 つのジョブに対して OIDC トークンのみをフェッチする必要がある場合は、そのジョブ内でこのアクセス許可を設定できます。 次に例を示します。

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

ワークフローの要件に応じて、ここで追加のアクセス許可を指定する必要がある場合があります。

呼び出し元ワークフローと同じユーザー、Organization、または Enterprise が所有する再利用可能なワークフローの場合、再利用可能なワークフローで生成された OIDC トークンに呼び出し元のコンテキストからアクセスできます。 Enterprise または Organization 外部の再利用可能なワークフローについては、id-tokenpermissions 設定を、呼び出し元ワークフロー レベル、または再利用可能ワークフローを呼び出す特定のジョブで write に設定してください。 これにより、再利用可能なワークフローで生成された OIDC トークンは、意図した場合にのみ呼び出し元ワークフローで使用できるようになります。

詳しくは、「ワークフローの再利用」を参照してください。

:

permissions キーを使用すると、すべての未指定のアクセス許可が "アクセスなし" に設定されます。ただし、メタデータ スコープは例外であり、常に "読み取り" アクセス権を取得します。__ __ その結果、contents: read のような他のアクセス許可を追加することが必要になる場合があります。 詳しくは、「自動トークン認証」を参照してください。

アクセス トークンの要求

hashicorp/vault-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-NAMESPACE は、Vault Enterprise (HCP Vault を含む) デプロイに対して設定する必要があります。 詳しくは、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

参考資料