【IAM】クロスクラウド連携でアクセスしてきた相手を特定できるログを確認してみた

【IAM】クロスクラウド連携でアクセスしてきた相手を特定できるログを確認してみた

2026.02.13

タイトル

【IAM】クロスクラウド連携でアクセスしてきた相手を特定できるログを確認してみた

はじめに

データ事業本部の川中子(かわなご)です。

以前の記事で、AWSとGoogle Cloud間のフェデレーションアクセスにおいて、
複数プリンシパルからのアクセスをまとめて許可するような構成を紹介しました。

https://dev.classmethod.jp/articles/aws-google-cloud-federation/

ただ、そのような構成にした場合にログで追跡できるのか気になりました。
どのプリンシパルがアクセスしてきたのか特定できるのでしょうか。

今回はAWSとGoogle Cloudそれぞれの場合において、
フェデレーションアクセスしてきた相手がログから分かるのかを検証します。

結論

AWS、Google Cloudのどちらの場合でも、ログからアクセス元を確認できました。

  • AWS側(CloudTrail)
    • Google CloudからアクセスしてきたサービスアカウントのIDがログに記録される
  • Google Cloud側(Cloud Logging)
    • AWSからアクセスしてきたロールのARNがログに記録される

これにより1つのロールやサービスアカウントに対して、
複数プリンシパルからのフェデレーションアクセスを許可するような形式でも、
どのプリンシパルがアクセスしてきたのかを正確に把握できます。

なお概要については、それぞれ公式のドキュメントでも説明されています。

AWS:
https://docs.aws.amazon.com/IAM/latest/UserGuide/cloudtrail-integration.html

Google Cloud:
https://docs.cloud.google.com/iam/docs/audit-logging/examples-workload-identity

検証構成

今回の検証では、以下の2パターンを検証しました。
なお本記事に記載のアカウントIDやクレデンシャル等の値はマスク・変更しています。

Google CloudからAWSにアクセス

1つのIAMロールに対し、複数サービスアカウントからのアクセスを許可する構成です。

Google Cloud側

  • サービスアカウント1: kawanago-crosscloud-test-1
  • サービスアカウント2: kawanago-crosscloud-test-2

AWS側

  • IAMロール: kawanago-crosscloud-test

AWSからGoogle Cloudにアクセス

1つのサービスアカウントに対し、複数IAMロールからのアクセスを許可する構成です。

AWS側

  • IAMロール1: kawanago-crosscloud-test-aws-1
  • IAMロール2: kawanago-crosscloud-test-aws-2

Google Cloud側

  • Workload Identity Pool: kawanago-crosscloud-test
  • Workload Identity Provider: kawanago-crosscloud-test-aws
  • サービスアカウント: kawanago-cc-test-target

Google CloudからAWSにアクセス

大まかな検証の構成イメージは以下になります。
実際の認証の詳細な流れについては、前回のブログを参照してください。

事前準備

Google Cloud側でサービスアカウントを2つ作成し、一意IDを取得しました。

  • サービスアカウント1の一意ID: 100000000000000000001
  • サービスアカウント2の一意ID: 100000000000000000002

AWS側では以下の信頼ポリシーでIAMロールを作成しました。
accounts.google.com:oaudaccounts.google.com:subを条件に指定します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "accounts.google.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "accounts.google.com:oaud": "kawanago-crosscloud-test",
          "accounts.google.com:sub": [
            "100000000000000000001",
            "100000000000000000002"
          ]
        }
      }
    }
  ]
}

サービスアカウントからAWSにアクセス

サービスアカウント1のIDトークンを取得し、AWSロールを引き受けます。

信頼ポリシーのaudience値にkawanago-crosscloud-testを設定したので、
Google Cloud側のトークン取得時にも同じ値を設定します。

TOKEN=$(gcloud auth print-identity-token \
  --impersonate-service-account="kawanago-crosscloud-test-1@my-gcp-project.iam.gserviceaccount.com" \
  --audiences="kawanago-crosscloud-test" 2>/dev/null)

aws sts assume-role-with-web-identity \
  --role-arn arn:aws:iam::111111111111:role/kawanago-crosscloud-test \
  --role-session-name gcp-sa1-session \
  --web-identity-token "$TOKEN" \
  --duration-seconds 900

レスポンスのSubjectFromWebIdentityTokenを確認します。
サービスアカウント1の一意IDが記録されています。

{
    ...,
    "SubjectFromWebIdentityToken": "100000000000000000001",
    "AssumedRoleUser": {
        "Arn": "arn:aws:sts::111111111111:assumed-role/kawanago-crosscloud-test/gcp-sa1-session"
    },
    "Provider": "accounts.google.com",
    "Audience": "100000000000000000001"
}

サービスアカウント2で同様に実行すると、別の一意IDが記録されました。

CloudTrailでログを確認

CloudTrailでAssumeRoleWithWebIdentityイベントを検索してみると、
ユーザー名列にアクセス元のサービスアカウントのIDが表示されていました。

1770940793408

参照されたリソースの方では、アシュームされたロールが確認できます。

1770941537445

これで問題なくCloudTrailから、アクセス元の情報を確認できました。
1つのIAMロールに許可をまとめても追跡はできそうです。

AWSからGoogle Cloudにアクセス

大まかな検証の構成イメージは以下になります。
こちらも認証の詳細な流れについては、前回のブログを参照してください。

事前準備

まずはAWS側でIAMロールを2つ作成しています。
今回の検証用に特別に必要な権限はありません。

  • IAMロール1: kawanago-crosscloud-test-aws-1
  • IAMロール2: kawanago-crosscloud-test-aws-2

次にGoogle Cloud側でWorkload Identity関連の資材を作成して、
サービスアカウントとIAMロールの紐づけを行なっています。

  • Workload Identity Pool / Provider
    • 検証用AWSアカウントからのアクセスを許可
  • サービスアカウント: kawanago-cc-test-target
  • サービスアカウントに各AWSロールからのアクセスを許可
  • 認証情報の構成ファイルをダウンロード

認証情報の構成ファイルは、検証のためにAWSのCloudShellにアップロードしました。

AWSロールからGoogle Cloudにアクセス

AWS CloudShell上で以下のpyファイルを実行し、アクセスを確認します。

import json
import os
import boto3
from google.auth import aws
from google.auth.transport.requests import Request

sts = boto3.client('sts')
creds = sts.assume_role(
    RoleArn='arn:aws:iam::111111111111:role/kawanago-crosscloud-test-aws-1',
    RoleSessionName='aws-role1-test'
)['Credentials']

os.environ['AWS_ACCESS_KEY_ID'] = creds['AccessKeyId']
os.environ['AWS_SECRET_ACCESS_KEY'] = creds['SecretAccessKey']
os.environ['AWS_SESSION_TOKEN'] = creds['SessionToken']

with open('credential-config.json') as f:
    config = json.load(f)

credentials = aws.Credentials.from_info(config)
scoped_credentials = credentials.with_scopes(
    ['https://www.googleapis.com/auth/cloud-platform']
)

scoped_credentials.refresh(Request())
print(f"Access token: {scoped_credentials.token[:20]}...")

上記のスクリプトにより、正常にアクセストークンを取得できました。
kawanago-crosscloud-test-aws-2でも同様の方法で確認できました。

Cloud Loggingでログを確認

Cloud Loggingの画面でトークン交換のログを検索すると、
こちらも問題なくログが出力されていることが確認できました。

protoPayload.methodName="google.identity.sts.v1.SecurityTokenService.ExchangeToken"

1769749870128

イベントの詳細を開いてみると、authenticationInfo.principalSubject内に、
アクセス元ロールのARNやセッション名が記載されていることが確認できます。

{
  "protoPayload": {
    "@type": "type.googleapis.com/google.cloud.audit.AuditLog",
    "status": {},
    "authenticationInfo": {
      "principalSubject": "arn:aws:sts::111111111111:assumed-role/kawanago-crosscloud-test-aws-1/aws-role1-test"
    },
    ...
  },
  ...
}

こちらも問題なくCloud Loggingから、アクセス元の情報を確認できました。
1つのサービスアカウントに許可をまとめても追跡できそうです。

なおCloud Loggingで上記のログを確認するには、
IAMの監査ログ設定でデータアクセス監査ログを有効にしておく必要があります。

https://docs.cloud.google.com/iam/docs/audit-logging/audit-logging-sts

さいごに

AWSとGoogle Cloudの間でWorkload Identity連携を使った場合でも、
アクセス元を特定できるログが出力されることが分かりました。

  • Google CloudからAWSにアクセスする場合

    • CloudTrailのuserIdentity.userNameにサービスアカウントの一意IDが記録される
    • 同じIAMロールを複数のサービスアカウントで共有しても、それぞれを区別してログが残る
  • AWSからGoogle Cloudにアクセスする場合

    • Cloud LoggingのprotoPayload.authenticationInfo.principalSubjectにIAMロールのARNが記録される
    • 同じサービスアカウントを複数のAWSロールで共有しても、それぞれを区別してログが残る

どちらの方向においても、アクセス元のプリンシパルを特定することができました。

外部クラウドからのアクセスを許可するリソースが全て同じ場合に限りますが、
最小限のリソースで、複数プリンシパルからのアクセスを許可できることが分かりました。

少しでも参考になれば幸いです。
最後まで記事を閲覧いただきありがとうございました。

この記事をシェアする

FacebookHatena blogX

関連記事