メモ
GitHub ホステッド ランナーは、現在 GitHub Enterprise Server ではサポートされていません。
概要
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 サーバーを構成します。
-
JWT
authメソッドを有効にし、writeを使用して Vault に構成を適用します。`oidc_discovery_url` および `bound_issuer` パラメーターの場合は、`https://HOSTNAME/_services/token` を使います。 これらのパラメーターを使用すると、Vault サーバーは認証プロセス中に受信した JSON Web トークン (JWT) を確認できます。Shell vault auth enable jwt
vault auth enable jwtShell vault write auth/jwt/config \ bound_issuer="https://HOSTNAME/_services/token" \ oidc_discovery_url="https://HOSTNAME/_services/token"
vault write auth/jwt/config \ bound_issuer="https://HOSTNAME/_services/token" \ oidc_discovery_url="https://HOSTNAME/_services/token"これらのステップを実行してください:
-
ワークフローがシークレットの取得に使用する特定のパスへのアクセスのみを許可するポリシーを構成します。 詳細なポリシーについては、HashiCorp Vault の 「ポリシー」のドキュメントを参照してください。
Shell vault policy write myproject-production - <<EOF # Read-only permission on 'secret/data/production/*' path path "secret/data/production/*" { capabilities = [ "read" ] } EOFvault policy write myproject-production - <<EOF # Read-only permission on 'secret/data/production/*' path path "secret/data/production/*" { capabilities = [ "read" ] } EOF -
異なるポリシーをグループ化するようにロールを構成します。 認証が成功した場合、これらのポリシーは結果の 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" } EOFvault 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パラメーターには一連の要求とその必須の値が含まれています。 上記の例では、ロールは、repo-nameアカウントによって所有されるuser-or-org-nameリポジトリからの受信認証要求を受け取ります。 - GitHub の OIDC プロバイダーでサポートされているすべての可能な要求を確認するには、「OpenID Connect」を参照してください。
詳細については、HashiCorp Vault のドキュメントを参照してください。
GitHub Actions ワークフローを更新する
OIDC のワークフローを更新するには、YAML に 2 つの変更を行う必要があります。
- トークンのアクセス許可設定を追加します。
- OIDC トークン (JWT) をクラウド アクセス トークンと交換するには、
hashicorp/vault-actionアクションを使用します。
メモ
環境がワークフローまたは OIDC ポリシーで使われる場合は、セキュリティを強化するために環境に保護規則を追加することをお勧めします。 たとえば、環境のデプロイ規則を構成して、環境にデプロイできるブランチとタグを制限したり、環境シークレットにアクセスしたりできます。 詳しくは、「デプロイメント用の環境管理」をご覧ください。
Vault のシークレットにアクセスできるようにワークフローに OIDC 統合を追加するには、次のコード変更を追加する必要があります。
- GitHub OIDC プロバイダーからトークンを取得する権限を付与してください。
- ワークフローには、
permissions:の値がid-tokenに設定されたwrite設定が必要です。 これにより、ワークフロー内のすべてのジョブから OIDC トークンをフェッチすることができます。
- ワークフローには、
- GitHub OIDC プロバイダーに JWT を要求し、それを HashiCorp Vault に提示してアクセス トークンを受け取ります。
*
hashicorp/vault-actionアクションを使って、JWT をフェッチし、Vault からアクセス トークンを受け取ることができます。または、Actions ツールキットを使ってジョブのトークンをフェッチすることもできます。
この例は、HashiCorp Vault からシークレットを要求するために、公式のアクションと共に OIDC を使う方法を示しています。
アクセス許可設定の追加
GitHub の OIDC プロバイダーが実行ごとに JSON Web Token を生成できるようにするためには、permissions``id-token: write を用いた設定がジョブまたはワークフロー実行に必要です。
メモ
ワークフローのアクセス許可で id-token: write を設定しても、リソースへの変更または書き込みを行うアクセス許可はワークフローに付与されません。 そうではなく、ワークフローは、アクションまたはステップのための OIDC トークンを要求 (フェッチ) して使用 (設定) することのみが許可されます。 その後、このトークンは、有効期間の短いアクセス トークンを使って外部サービスで認証を行うために使われます。
必要なアクセス許可、構成例、高度なシナリオについて詳しくは、「OpenID Connect リファレンス」をご覧ください。
メモ
`permissions` キーを使用すると、すべての未指定のアクセス許可が "アクセスなし" に設定されます。ただし、メタデータ スコープは例外であり、常に "読み取り" アクセス権を取得します。____ その結果、`contents: read` のような他のアクセス許可を追加することが必要になる場合があります。 詳しくは、「[自動トークン認証](/actions/security-guides/automatic-token-authentication)」を参照してください。
アクセス トークンの要求
`hashicorp/vault-action` アクションは、GitHub OIDC プロバイダーから JWT を受け取り、HashiCorp Vault インスタンスにアクセス トークンを要求し、シークレットを取得します。 詳細については、HashiCorp Vault GitHub Action [documentation](https://github.com/hashicorp/vault-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`と指定します。
# このワークフローはGitHubによって認定されていないアクションを使用します。
# それらはサードパーティによって提供され、
# 別個の利用規約、プライバシーポリシー、
# ドキュメントを参照してください。
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.
# このワークフローはGitHubによって認定されていないアクションを使用します。
# それらはサードパーティによって提供され、
# 別個の利用規約、プライバシーポリシー、
# ドキュメントを参照してください。
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 名前空間](https://www.vaultproject.io/docs/enterprise/namespaces)に関するページを参照してください。
アクセス トークンの取り消し
既定で、Vault サーバーでは TTL の有効期限が切れたときにアクセス トークンを自動的に取り消します。そのため、アクセス トークンを手動で取り消す必要はありません。 ただし、ジョブが完了または失敗した直後にアクセス トークンを取り消す場合は、Vault API を使用して発行されたトークンを手動で取り消すことができます。
-
`exportToken` オプションを `true` (既定値: `false`) に設定します。 これにより、発行された Vault アクセス トークンが環境変数としてエクスポートされます: `VAULT_TOKEN`。 -
[トークンの取り消し (自己)](https://www.vaultproject.io/api/auth/token#revoke-a-token-self) Vault API を呼び出してアクセス トークンを取り消すステップを追加します。
# このワークフローはGitHubによって認定されていないアクションを使用します。
# それらはサードパーティによって提供され、
# 別個の利用規約、プライバシーポリシー、
# ドキュメントを参照してください。
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
# このワークフローはGitHubによって認定されていないアクションを使用します。
# それらはサードパーティによって提供され、
# 別個の利用規約、プライバシーポリシー、
# ドキュメントを参照してください。
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