CI/CDパイプライン(例: GitHub Actions)からGoogle Cloudへ安全にアクセスする手法として、キーレス認証(JSONキーを配置しない手法)のうち、Google Cloudが推奨しているDirect Workload Identity Federationの実装方法をご紹介します。
概要
- Github Actionsでterraformを実行し、GoogleCloudリソースであるプロジェクトを作成する。
- Direct Workload Identity Federationという機能を利用して、サービスアカウントの認証情報を持たせずに、GoogleCloudの認証を可能にする。
- 今回の記事では、Workload Identity IDpoolの作成やIAMの設定方法について紹介する。
背景
- 社内のスキルアップのための検証環境を提供していて、利用者の申請ベースに利用者ごとのプロジェクトを払い出している。
- 社内のGithub環境が変化し、自動化のしくみを実装しやすくなった。
- Direct Workload Identity Federationという機能を利用すれば、サービスアカウントの認証情報をGithub Secrets等で保管せずに認証できるようになった。
- 色々障壁が少なくなってきたので、まずは自動化の検討のために手を動かして実験してみよう!の気持ちで今回やってみました。
全体像
- 構成として、管理者用フォルダと利用者用フォルダがあり、管理者用フォルダの下にはネットワーク管理やその他課金管理用プロジェクトなどがある。利用者用フォルダの下には各利用者専用のプロジェクトがある。
- 管理者用のプロジェクトにWorkload Identity Poolを構築し、そのプリンシパルに対して利用者用フォルダでプロジェクト作成者の権限ロールを付与する。
- 管理用プロジェクトのGCSにtfstateファイルを利用者ごとに保存する
- Github Actionsではterraformコマンドを実行して、プロジェクトの作成を行う。
Direct Workload Identity Federationとは?
Workload Identity プールは、AWSやGithubなどの外部IDをGoogle Cloud内で管理・マッピングできるエンティティである。
Direct Workload Identity Federationは、サービスアカウントを必要とせず、外部ID(プリンシパル)に対して直接リソースへのアクセス権限(IAMロール)を付与/許可することができる。これによって、そもそもサービスアカウントの管理が不要になるのと、セキュリティリスクの削減につながることが利点となる。
GitHub Actionsを例にとると、裏側では以下のようなフローで認証が行われている。
- OIDCトークンの発行
GitHub Actionsが、自身のジョブ情報(リポジトリIDやブランチ名など)を含んだOIDCトークン(JWT)を発行する。 - STS APIによるトークン交換
Google CloudのSecurity Token Service (STS) API を呼び出し、GitHubのOIDCトークンを提示する。STSはトークンを検証し、有効期間の短い連携アクセストークンに交換し、このアクセストークンを利用してGoogleCloudAPIの呼び出しを行う。
したがって、どこからのGithub OIDCを受け入れるかの設定と、その外部IDが何をできるかのIAM設定を実施する。
参考リンク
具体的な手順
実際の手順を見ていきましょう。
1. IDプロバイダを追加する
1.「IAM」→「Workload Identity連携」→「プロバイダを追加」ボタンを選択する。
2. 「IDプールを作成する」で任意の名前を入力する
3. 「プールにプロバイダを追加する」で各種パラメータを入力する
プロバイダの選択: OpenID Connect(OIDC)
プロバイダ名: 任意の名前
プロバイダID: 任意のID
発行元URL: https://token.actions.githubusercontent.com
オーディエンス: デフォルト
参考リンク:OpenID Connect リファレンス
4. 「プロバイダの属性を構成する」でマッピング情報および条件式を設定する。
今回はなりすましを防ぐためにrepository_idやrepository_owner_idの条件を定めています。
※ここのIDは後述のGithub Actionで確認可能
2. IAMを設定する。
Workload Identity IDプールに「IAMプリンシパル」が表示されていて、下記のような形式で埋めてメモしておく。
principal://iam.googleapis.com/projects/[プロジェクトID]/locations/global/workloadIdentityPools/[IDプールの名前]/subject/[Github OIDCのsub値]
今回は利用者用のフォルダの下にプロジェクトを新規作成していく構成なので、利用者用フォルダの「IAMと管理」→「IAM」→「アクセスを許可」で新しいプリンシパルに上記メモした値と、プロジェクト作成者のロールを選択する。
3. Github Actionsを実行する。
たとえば、下記のようなものがサンプルとして挙げられます。
Debug OIDC claimsのステップでは、OIDCクレームを表示するようなbashスクリプトにしています。
また、google-github-actions/auth@v2というアクションを利用していて、サービスアカウント名を入力しない場合は、Direct Workload Identity Federationを利用することになります。
Authenticate to Google Cloud from GitHub Actions
GitHub Actions からのキーなしの認証の有効化
name: Provision GCP Project
on:
push:
branches:
- main
jobs:
provision:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Debug OIDC claims
shell: bash
run: |
resp="$(curl -s -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=https://github.com/${{ github.repository_owner }}")"
token="$(echo "$resp" | python3 -c 'import sys, json; print(json.load(sys.stdin)["value"])')"
payload="$(echo "$token" | cut -d '.' -f2 | tr '_-' '/+' | base64 -d 2>/dev/null || true)"
echo "$payload" | python3 -m json.tool
echo "---"
# ここでOIDCのクレームの中身を知ることができる
- id: auth
name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
workload_identity_provider: "projects/XXXXXXXX/locations/global/workloadIdentityPools/XXXXXXX/providers/XXXXXXX"
# ここのXXXXXは適切な値を入力する。
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
- name: Terraform Init
run: |
terraform init
- name: Terraform Plan
run: |
terraform plan
- name: Terraform Apply
run: |
terraform apply -auto-approve
まとめ
- CICDパイプライン(github actions)からGoogle cloudのリソースのデプロイを可能にした。
- サービスアカウントを利用しないDirect Workload Identity Federationという仕組みによってよりセキュアな外部接続を可能にした。
- これを実現するために、Workload Identity Poolの構築方法と、IAM設定の仕方をご紹介した。






