このドキュメントでは、ID 連携を使用して OpenID Connect(OIDC)をサポートする ID プロバイダから Google Cloud リソースにアクセスする方法について説明します。
従来、Google Cloud の外部で実行されているアプリケーションは、サービス アカウント キーを使用して Google Cloud リソースにアクセスしていました。ID 連携を使用すると、外部 ID でサービス アカウントになり代わることができます。これにより、ワークロードは短期間だけ有効なアクセス トークンを使用して Google Cloud リソースに直接アクセスでき、サービス アカウント キーに関連するメンテナンスとセキュリティの負担が軽減されます。
始める前に
Workload Identity プール管理者ロール(
roles/iam.workloadIdentityPoolAdmin
)があることを確認します。また、IAM オーナー(
roles/owner
)と編集者(roles/editor
)の基本ロールには ID 連携を構成する権限も含まれています。本番環境で基本ロールを付与することはできませんが、開発環境またはテスト環境ではこれらのロールを付与できます。ID プロバイダからのフェデレーションを許可するには、組織の組織ポリシーを更新します。
サービス アカウントにアクセス権を付与して、ワークロードに必要な Google Cloud APIs を呼び出します。
Workload Identity プールの作成
Workload Identity プールは、外部 ID のコレクション用のコンテナです。Workload Identity プールは相互に分離されていますが、1 つのプールは任意の数のサービス アカウントになり代わることができます。一般に、開発、ステージング、本番環境など、環境ごとに新しいプールを作成することをおすすめします。
新しい Workload Identity プールを作成するには、ID を指定する必要があります。オプションの説明と表示名を指定することもできます。
gcloud
gcloud beta iam workload-identity-pools create
コマンドを実行して Workload Identity プールを作成します。
gcloud beta iam workload-identity-pools create pool-id \ --location="global" \ --description="description" \ --display-name="display-name"
レスポンスは次のようになります。
Created WorkloadIdentityPool [pool-id].
REST
projects.locations.workloadIdentityPools.create
メソッドにより、Workload Identity プールが作成されます。
HTTP メソッドと URL:
POST https://iam.googleapis.com/v1beta/projects/project-id/locations/global/workloadIdentityPools?workloadIdentityPoolId=pool-id
JSON 本文のリクエスト:
{ "description": "description", "display-name": "display-name" }
リクエストを送信するには、次のいずれかのオプションを展開します。
このメソッドは、次のような長時間実行 Operation
を返します。
{ "name": "projects/project-number/locations/global/workloadIdentityPools/pool-id/operations/operation-id" }
OIDC ID プロバイダの追加
Workload Identity プールの OIDC ID プロバイダを構成するには、少なくとも次の情報を指定します。
プロバイダの ID。
このドキュメントの前のセクションの Workload Identity プール ID。
プロバイダの発行者 URI。通常は、
https://example.com
の形式を使用します。URI の確認については、OIDC 統合に関するプロバイダのドキュメントをご覧ください。外部トークンのクレームを Google トークンの属性にマッピングする属性マッピングのリスト。
assertion
を使用して外部認証情報を参照します。Google 属性の場合はgoogle
、カスタム属性の場合はattribute
を使用します。Google 属性には
google.subject
とgoogle.groups
の 2 つがあります。これらの属性は IAM ロール バインディングで参照できます。google.subject
も Cloud Logging のログエントリに表示されます。google.subject
のマッピングを指定する必要があります。通常は、assertion.sub
にマッピングすることをおすすめします。これにより、IAM ロール バインディングで使用する固定 ID が提供されます。マッピングは次のようになります。google.subject=assertion.sub
より複雑なアサーションの場合は、Common Expression Language を使用できます。たとえば、Workload Identity プールに複数の ID プロバイダが含まれている場合は、それらの ID を明確化するために接頭辞を追加できます。
google.subject="provider-a::" + assertion.sub
google.subject
フィールドは 127 文字以下で指定してください。カスタム属性を指定することもできます。たとえば、以下では
assertion.foo
をattribute.bar
にマッピングします。attribute.bar=assertion.foo
参照できるクレームの完全なリストについては、アクセス トークンに関するプロバイダのドキュメントをご覧ください。
式で使用されているクレームの特定の部分を参照するには、CEL の
extract()
関数を使用します。この関数は、指定したテンプレートに基づいてクレームから値を抽出します。extract()
の詳細については、リソース名からの値の抽出をご覧ください。認証情報にクレームが含まれているかどうかを確認するには、
has()
関数を使用します。外部認証情報の
aud
フィールドに設定できる値を指定する許可されたオーディエンスのリスト。最大 10 個のオーディエンス(それぞれ最大 256 文字)を構成できます。aud
のデフォルト値については、プロバイダのドキュメントをご覧ください。または、ID プロバイダで
aud
のカスタム値を構成できる場合は、許可オーディエンス パラメータを空白のままにし、aud
の値を Workload Identity プロバイダの完全なリソース名に設定できます。HTTP 接頭辞は省略可能です。例://iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/providers/provider-id https://iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/providers/provider-id
どちらの場合も、許可された値を含まないトークン交換リクエストは拒否されます。
次の複数のオプション パラメータを指定することもできます。
表示名と説明。
プリンシパルが提示する必要がある属性を指定する属性条件。この条件は、外部認証情報に対するクレーム、または Google 認証情報の属性に適用できます。条件を満たしていないリクエストは拒否されます。
属性条件は、ブール値を返す CEL 式の形式になります。たとえば以下では、特定のグループのメンバーではない ID からのリクエストは拒否されます。
group in assertion.groups
ID プロバイダが一般に公開されている場合は、属性条件を使用することを強くおすすめします。属性条件の一般的なユースケースの詳細については、Workload Identity 連携の概要をご覧ください。
次の例は、ID プロバイダを追加する方法を示しています。
gcloud
gcloud beta iam workload-identity-pools providers create-oidc
コマンドを実行して ID プロバイダを追加します。
gcloud beta iam workload-identity-pools providers create-oidc provider-id \ --workload-identity-pool="pool-id" \ --issuer-uri="issuer-uri" \ --location="global" \ --attribute-mapping="google.subject=assertion.sub"
レスポンスは次のようになります。
Created WorkloadIdentityPoolProvider [provider-id].
REST
projects.locations.workloadIdentityPools.providers.create
メソッドにより、OIDC ID プロバイダが追加されます。
HTTP メソッドと URL:
POST https://iam.googleapis.com/v1beta/projects/project-id/locations/global/workloadIdentityPools/pool-id/providers?workloadIdentityPoolProviderId=provider-id
JSON 本文のリクエスト:
{ "issuerUrl": "issuer-uri" }
リクエストを送信するには、次のいずれかのオプションを展開します。
このメソッドは、次のような長時間実行 Operation
を返します。
{ "name": "projects/project-number/locations/global/workloadIdentityPools/pool-id/providers/provider-id/operations/operation-id" }
サービス アカウントの権限借用を許可する
外部 ID は、ほとんどの Google Cloud リソースに直接アクセスできません。代わりに、Workload Identity ユーザーロール(roles/iam.workloadIdentityUser
)をサービス アカウントに付与することで、サービス アカウントの権限を借用できます。
特定の ID にこのロール バインディングを追加するには、google.subject
にマッピングされた値を使用します。
gcloud iam service-accounts add-iam-policy-binding service-account-email \ --role roles/iam.workloadIdentityUser \ --member "principal://iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/subject/subject"
グループのすべてのメンバーにこのバインディングを追加するには:
gcloud iam service-accounts add-iam-policy-binding service-account-email \ --role roles/iam.workloadIdentityUser \ --member "principalSet://iam.googleapis.com/project/project-number/workloadIdentityPools/pool-id/groups/group-name"
カスタム属性に基づいてアクセス権を付与することもできます。例:
gcloud iam service-accounts add-iam-policy-binding service-account-email \ --role="roles/iam.workloadIdentityUser" \ --member="principalSet://iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/attribute.custom-attribute-name/custom-attribute-value"
アクセス権を取り消すには、add-iam-policy-binding
を remove-iam-policy-binding
に置き換えます。
REST API またはクライアント ライブラリを使用して、バインディングの追加または削除を行うこともできます。詳細については、リソースへのアクセス権の付与、変更、取り消しをご覧ください。
外部トークンを Google トークンと交換する
外部 ID でサービス アカウントになり代わることができる状態であれば、その認証情報を Google 認証情報と交換できます。
認証情報を交換するには、次のようにします。
ID プロバイダから OIDC ID トークンを取得します(詳しい手順については、ID プロバイダのドキュメントをご覧ください)。
OIDC ID トークンをセキュリティ トークン サービスの
token()
メソッドに渡して、連携アクセス トークンを取得します。REST
token
メソッドにより、サードパーティ トークンが Google トークンに交換されます。後述のリクエストのデータを使用する前に、次のように置き換えます。
project-number
: Google Cloud プロジェクト番号。pool-id
: このチュートリアルで前に作成した Workload Identity プールの ID。provider-id
: このチュートリアルで前に構成した ID プロバイダの ID。
HTTP メソッドと URL:
POST https://sts.googleapis.com/v1beta/token
JSON 本文のリクエスト:
{ "audience": "//iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/providers/provider-id", "grantType": "urn:ietf:params:oauth:grant-type:token-exchange", "requestedTokenType": "urn:ietf:params:oauth:token-type:access_token", "scope": "https://www.googleapis.com/auth/cloud-platform", "subjectTokenType": "urn:ietf:params:oauth:token-type:jwt", "subjectToken": "oidc-id-token" }
リクエストを送信するには、次のいずれかのオプションを展開します。
このメソッドは連携トークンを返します。
generateAccessToken()
を呼び出して、サービス アカウントのアクセス トークンと連携トークンを交換します。連携トークンは一部の Google Cloud APIs でサポートされています。すべての Google Cloud APIs はサービス アカウントのアクセス トークンをサポートしています。REST
Service Account Credentials API の
serviceAccounts.generateAccessToken
メソッドによって、サービス アカウントの OAuth 2.0 アクセス トークンが生成されます。後述のリクエストのデータを使用する前に、次のように置き換えます。
project-id
: Google Cloud プロジェクト ID。sa-id
: サービス アカウントの ID。これは、サービス アカウントのメールアドレス(sa-name@project-id.iam.gserviceaccount.com
の形式)、またはサービス アカウントの一意の数値 ID のいずれかです。token
: 連携アクセス トークン。
HTTP メソッドと URL:
POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/sa-name@project-id.iam.gserviceaccount.com:generateAccessToken
JSON 本文のリクエスト:
{ "scope": [ "https://www.googleapis.com/auth/cloud-platform" ] }
リクエストを送信するには、次のいずれかのオプションを展開します。
generateAccessToken
リクエストが成功した場合、レスポンスの本文には OAuth 2.0 アクセス トークンと有効期限が含まれます。expireTime
に達するまで、サービス アカウントの代わりにaccessToken
をリクエストの認証に使用できます。{ "accessToken": "eyJ0eXAi...NiJ9", "expireTime": "2020-04-07T15:01:23.045123456Z" }
サービス アカウントのアクセス トークンを取得したら、リクエストの Authorization
ヘッダーにトークンを含めることで、Google Cloud APIs の呼び出しに使用できます。
Authorization: Bearer service-account-access-token
リクエストはサービス アカウントとして承認されます。