概要
GCPのWorkload Identity連携はサービスアカウントで秘密鍵を作らずともGCPリソースへのアクセス権を他の環境(オンプレ、別パブリッククラウド)に付与することができます。
これにより
といった連携が鍵なしで実現できます。
ただ実装だけだとイメージしづらいので今回は図示してみました。
Workload Identity Federation
Workload Identity連携における登場人物は以下です。
左のWorkloadsがGCPリソースにアクセスしたいアプリケーションに当たります。
準備
Workload Identity Poolの作成とサービスアカウントの作成
まずはWorkload Identity Poolとサービスアカウントを用意します。
サービスアカウントにはアクセスしたいGCPリソースに対する最低限の権限を付与します。
Identity ProviderとWorkload Identity Poolの連携
Workload Identity Poolが外部IdPを信頼するように設定します。
gcloudコマンドだと
IdPによってやや変わりますが以下のように設定します。
$ gcloud iam workload-identity-pools providers create-oidc PROVIDER_ID \ --location="global" \ --workload-identity-pool="POOL_ID" \ --issuer-uri="ISSUER" \ --allowed-audiences="AUDIENCE" \ --attribute-mapping="MAPPINGS" \ --attribute-condition="CONDITIONS"
Workload Identity 連携の構成 | IAM Documentation | Google Cloud に各IdPとの連携方法が載っています。
attribute-mapping
やattribute-condition
を使ってIdP側のユーザグループに対するアクセス制御のための情報を渡します。
attribute-mapping
は以下をマッピングできます。
属性 | 設定するロールバインディング | ユースケース |
---|---|---|
google.subject | principal:// | 一意のユーザにアクセス権を付与したい |
google.groups | principalSet:// | グループのすべてのメンバーにアクセス権を付与したい |
attribute.XXX | principalSet:// | 特定の属性を持つすべての ID にアクセス権を付与したい |
例えばGitHub Actionsであれば以下のようにattribute.repository
を渡すことで、
--attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository"
認証を特定のリポジトリに制限することができます。
※次のWorkload Identity Poolとサービスアカウントのロールバインディングでも設定が必要です
Workload Identity Poolとサービスアカウントの連携
最後にWorkload Identity Poolがサービスアカウントの権限を借用する(impersonate=成りすます)ための設定を行います。
以下はGitHub Actionsの例です。先程attribute-mapping
でマッピングした情報(attribute.repository
)を使うことで、リソースにアクセスできるメンバー(リポジトリ)を制限しています。
$ gcloud iam service-accounts add-iam-policy-binding "my-service-account@${PROJECT_ID}.iam.gserviceaccount.com" \ --project="${PROJECT_ID}" \ --role="roles/iam.workloadIdentityUser" \ --member="principalSet://iam.googleapis.com/${WORKLOAD_IDENTITY_POOL_ID}/attribute.repository/my-org/my-repo"
リソースアクセスまでの流れ
設定が完了したら以下のフローでGCPリソースにアクセスすることができます。
- Workload(アプリケーション)がIdPに認証
- IdPがクレデンシャルを発行
- WorkloadがクレデンシャルをGCPのSTSに渡す
- STSはクレデンシャルの正当性をWorkload Identity Poolに登録した情報を使ってチェック
- 問題なければ進める
- サービスアカウントに成りすますことができる一時トークンを発行
- 一時トークンを使ってサービスアカウントになりすます
- GCPリソースにアクセス
その他
assertion.XXXには何が使えるか
OIDCトークン(JWT)に内包されている各claimsが使えます。
例えばGitHub Actionsだと以下です。
{ "jti": "example-id", "sub": "repo:octo-org/octo-repo:environment:prod", "environment": "prod", "aud": "https://github.com/octo-org", "ref": "refs/heads/main", "sha": "example-sha", "repository": "octo-org/octo-repo", "repository_owner": "octo-org", "run_id": "example-run-id", "run_number": "10", "run_attempt": "2", "actor": "octocat", "workflow": "example-workflow", "head_ref": "", "base_ref": "", "event_name": "workflow_dispatch", "ref_type": "branch", "job_workflow_ref": "octo-org/octo-automation/.github/workflows/oidc.yml@refs/heads/main", "iss": "https://token.actions.githubusercontent.com", "nbf": 1632492967, "exp": 1632493867, "iat": 1632493567 }
公式動画
公式にとても分かりすい動画が上がっているのでオススメです。
まとめ
Workload Identity連携はIdPによって若干設定が異なります。
今回図示することで連携に必要な手順の根本を理解できたので、異なるIdPにおいてもスムーズに設定できるようになりました。