GCP Service Account を AWS から STS 認証で利用する設定例
[履歴] [最終更新] (2021/10/31 16:17:34)
最近の投稿
注目の記事

概要

GCP API を GCP の外から利用するためには、一般に Service Account を利用します。その際に Service Account の鍵ファイルを利用すると、鍵ファイルの流出によるリスクが発生します。Workload identity federation という機能を用いることで、鍵を用いない認証の仕組みを実現できます。

参考資料: Keyless API authentication—Better cloud security through workload identity federation, no service account keys necessary

処理の流れ

  1. GCP 外の Workload が、自らの環境の Identity Provider に対して認証を行います。
  2. Identity Provider から得た情報をもとに、GCP Security Token Service (STS) に対して認証を行います。
  3. STS から取得した Token を用いて GCP Service Account を利用します。

Uploaded Image

上記の処理の流れを実現するために、以下の設定が必要となります。

  • Workload Identity Pool に Identity Provider を事前に登録しておきます。
  • Service Account を Workload Identity Pool の Identity が利用できるように権限を設定しておきます。
  • Service Account に必要な IAM Role を付与しておきます。

Uploaded Image

参考資料: Workload identity federation

Workload Identity Pool

Cloud Console または以下のコマンドで作成します。

gcloud iam workload-identity-pools create my-aws-pool --location='global'

Uploaded Image

参考資料: Create the workload identity pool and provider

Identity Provider

Cloud Console または以下のコマンドで作成します。

gcloud iam workload-identity-pools providers create-aws my-aws-provider \
--location=global \
--workload-identity-pool=my-aws-pool \
--account-id=123412341234 \
--attribute-mapping='google.subject=assertion.arn,attribute.aws_role=assertion.arn.contains("assumed-role") ? assertion.arn.extract("{account_arn}assumed-role/") + "assumed-role/" + assertion.arn.extract("assumed-role/{role_name}/") : assertion.arn'

OpenID Connect (OIDC) をサポートする任意の Identity Provider を利用できます。特に AWS の場合は必要な設定値が用意されているため、簡単に利用を始められます。

Uploaded Image

AWS アカウント ID を指定します。

Uploaded Image

AWS を Identity Provider として利用する際の、標準的な Attribute Mapping が自動で設定されます。

Uploaded Image

参考資料: Workload identity providers

Service Account

Workload Identity Pool に登録された Identity Provider によって提供される GCP 外部の Identity は、GCP STS によって federated access token を得ます。GCP 外部の Identity は GCP の principal としては以下のように表現されます。

principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/SUBJECT_NAME

Service Account の Permission において、上記 principal が roles/iam.workloadIdentityUser ロールを持つように grant しておきます。

iam.serviceAccounts.get
iam.serviceAccounts.getAccessToken
iam.serviceAccounts.getOpenIdToken
iam.serviceAccounts.list

iam.serviceAccounts.getAccessToken permission を持つため、federated access token を用いることで short-lived OAuth 2.0 access token を取得できるようになります。この access token を用いることで Service Account を利用します。

GCP 外部の Identity に roles/iam.workloadIdentityUser を付与する対象となる Service Account を選択します。

Uploaded Image

STS によって federated access token を取得するための情報が記載された JSON ファイルがダウンロードできます。認証情報ではないため、例えば Secret Manager 等で守る必要のある情報ではありません。

$ cat clientLibraryConfig-my-aws-provider.json
{
  "type": "external_account",
  "audience": "//iam.googleapis.com/projects/912480652101/locations/global/workloadIdentityPools/my-aws-pool-20211030/providers/my-aws-provider",
  "subject_token_type": "urn:ietf:params:aws:token-type:aws4_request",
  "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/mysa-457@myproject-20210411.iam.gserviceaccount.com:generateAccessToken",
  "token_url": "https://sts.googleapis.com/v1/token",
  "credential_source": {
    "environment_id": "aws1",
    "region_url": "http://169.254.169.254/latest/meta-data/placement/availability-zone",
    "url": "http://169.254.169.254/latest/meta-data/iam/security-credentials",
    "regional_cred_verification_url": "https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15"
  }
}

Uploaded Image

選択した Service Account に対して、リソースレベルの IAM 権限の設定がなされていることも確認できます。

Uploaded Image

参考資料: Service account impersonation

Security Token Service (STS) によるトークン発行

Access Token を取得するまでの流れ

Service Account を GCP 外部 Identity が利用するためには、以下のステップが必要となります。

  1. 外部 Identity Provider から認証情報を取得。
  2. 「1」で取得した認証情報を GCP STS でトークンと交換。
  3. 「2」で取得したトークンを用いて short-lived な Access Token を取得。
  4. 「3」で取得した Access Token を用いて Service Account を利用。

参考資料: Obtaining short-lived credentials with identity federation

Python3 の例

google-auth を利用します。

python3 -m pip install -U google-auth

IAM role が割り当てられた AWS EC2 インスタンスで以下のコマンドを実行します。

export GOOGLE_APPLICATION_CREDENTIALS=`pwd`/clientLibraryConfig-my-aws-provider.json

python3 -m IPython

from google.cloud import storage
import google.auth

scopes=['https://www.googleapis.com/auth/cloud-platform']
credentials, project = google.auth.default(scopes=scopes)

client = storage.Client(project=project, credentials=credentials)

for bucket in client.list_buckets():
    print(bucket.name)

参考資料:

Cloud SDK の例

CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE 環境変数を利用することで対応できます。gsutil および bq コマンドは対応していません。

export CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=`pwd`/clientLibraryConfig-my-aws-provider.json
gcloud compute instances list

参考資料:

IAM Role の制限

Attribute Mapping で Key として設定されている attribute.aws_role または google.subject を用いて、特定の Identity のみが Service Account を利用できるように制限できます。例えば aws_rolemy-role-20211027 に限定するためには、以下のように設定します。

Uploaded Image

Identity Provider 側の設定によって制限することも可能です。

Uploaded Image

関連資料:

Organization Policy

Workload Identity Federation を用いる場合、Service Account の鍵は不要となります。組織のポリシーによって制限することが可能です。

また、Identity Provider を AWS に制限することや、AWS のアカウント ID を制限することも可能です。

VPC Service Controls

インターネットへのアクセスが制限されている環境においては sts.googleapis.com によるトークン発行が失敗します。

Security Token Service (STS) は、こちらのページに記載の VPC-SC および Private Google Access でサポートされています。これを利用することでインターネット接続ができない環境であっても STS を利用できます。

AWS PrivateLink

同様に AWS STS へのアクセスをインターネットを経由せずに実現するためには、AWS PrivateLink を利用します: Using AWS STS interface VPC endpoints

関連ページ
    概要 こちらのページでは GCP Service Account を AWS から STS で利用する設定例を記載しました。本ページでは、逆に GCP から AWS IAM Role を利用するための設定例を記載します。 GCP Service Account の作成 Service Account を作成して Unique ID を確認します。