サービスアカウントの OIDC ID トークンの発行になる。
Cloud Run サービス、Cloud Run Functions 利用時に IAM 認証を突破するために必要になる。
gcloud コマンドで発行
gcloud auth print-identity-token
を使う。
例.
gcloud auth login
# 自身の Google アカウントの ID トークンを発行
gcloud auth print-identity-token audiences="<オーディエンス>"
# サービスアカウントになりすましての ID トークンを発行
gcloud auth print-identity-token --impersonate-service-account="<サービスアカウント>" audiences="<オーディエンス>"
なお、gcloud auth print-identity-token
を利用して、サービスアカウントになりすましてサービスアカウントの ID トークンを発行する場合は、なりすまし先サービスアカウントに対する roles/iam.ServiceAccountOpenIdTokenCreator
ロールをなりすまし元の Google アカウントに付与しておく必要あり。
roles/iam.ServiceAccountTokenCreator
ロールは不要。
なお、ロールに含まれるパーミッション的には、
roles/iam.ServiceAccountTokenCreator
⊇ roles/iam.ServiceAccountOpenIdTokenCreator
の関係である。
REST API で発行
projects.serviceAccounts.generateIdToken API を使う。
エンドポイント
POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/<認証情報を要求するサービスアカウント>:generateIdToken
リクエストヘッダ
Authorization: Bearer
には 「ID トークンを発行したいサービスアカウントに対するroles/iam.ServiceAccountOpenIdTokenCreator
ロールが付与されているプリンシパル」の OAuth2.0 アクセストークンをセット。
ADC に含まれる source_credencials の情報を使う方法もあるみたいだが、Google 公式のドキュメントを明後日も伺いしれなかった。
・・・とはいえ、Authorization: Bearer
にアクセストークンをセットする方法も、とあるサンプル実行からわかっただけで、API 仕様として書かれているドキュメントはない(はず)。
リクエストボディ
{
"delegates": [
<必要あれば>
],
"audience": <オーディエンス>,
"includeEmail": true
}
delegates[]:
デリゲーションチェーンにおけるサービスアカウントのシーケンス。
各サービスアカウントは、チェーンの次のサービスアカウントの roles/iam.serviceAccountTokenCreator
ロールを付与されている必要あり。
チェーン内の最後のサービスアカウントは、リクエストのnameフィールドで指定されたサービスアカウントのroles/iam.serviceAccountOpenIdTokenCreatorロールを付与されなければならない。
デリゲートは、以下の形式でなければならない: projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}
ワイルドカード文字の-
は必須。
audience:
必須。トークンの利用者。このトークンがアクセスを許可する API やアカウントなど。
includeEmail:
トークンにサービスアカウントのEメールを含めるか。
true に設定すると、トークンに email
と email_verified
クレームが含まれる
実行例.
curl で叩くと以下のような形
curl -X POST \
-H "Authorization: Bearer <サービスアカウントに対する >" \
-H "Content-Type: application/json; charset=utf-8" \
-d <リクエストボディ> \
"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/<サービスアカウント>:generateIdToken"
各言語の認証ライブラリで発行
Go だと idtoken。
ADC を使っていい感じに ID トークンを発行してくれる。
ローカルで使う場合は、gcloud auth application-default login
で ADC をセットした状態で利用する。
gcloud auth application-default login --impersonate-service-account="<サービスアカウント>"
で ADC が Google アカウントからサービスアカウントになりすます形になっている場合は、idtoken では以下のような処理になる模様。
- Google アカウントの source_credentials から サービスアカウントのアクセストークンを発行
- 対象のサービスアカウントに対する
roles/iam.ServiceAccountTokenCreator
ロールが Google アカウントに付与されている必要あり
- 対象のサービスアカウントに対する
- サービスアカウントのアクセストークンからサービスアカウントの ID トークンを発行
- 対象のサービスアカウントに対する
roles/iam.ServiceAccountOpenIdTokenCreator
ロールが サービスアカウント自身に付与されている必要あり
- 対象のサービスアカウントに対する
ちなみに、他の言語の ID トークン発行処理だと Google アカウントの source_credentials から直接サービスアカウントの ID トークンを発行(対象のサービスアカウントに対する roles/iam.ServiceAccountOpenIdTokenCreator
ロールが Google アカウントに付与されている必要あり)という形になっているらしい(Issue。ややこしい・・・
参考