CloudTrail Lakeのエンリッチメントでコンプライアンス監視をやってみた

CloudTrail Lakeのエンリッチメントでコンプライアンス監視をやってみた

Clock Icon2025.06.24

AWS環境でコンプライアンス監視やセキュリティ分析をしようと思った時に、特定のタグが付与されたリソースへのアクセスを監視したい場合や、IAMの条件コンテキストを含めた詳細な分析を行いたいケースがあるかと思います。

1ヶ月ほど前ですが、CloudTrail Lakeでイベントエンリッチメントとイベントサイズの拡張をサポートするアップデートがありました。
https://aws.amazon.com/jp/about-aws/whats-new/2025/05/cloudtrail-lake-event-enrichment-expanded-event-size/

従来のCloudTrailログでは、イベント発生時点での基本的な情報(誰が、いつ、何を実行したか)は記録されますが、リソースのタグ情報やIAMの詳細なコンテキスト情報は含まれていませんでした。
この機能により、CloudTrail Lakeのイベントデータストアに保管される時、ログエントリに対してリソースタグやIAMグローバル条件コンテキストを付与することができます。

早速試してみました。

この記事では、以下の流れで実際に検証した結果を共有します:

  1. イベントエンリッチメント機能の概要と効果
  2. 機能有効化前のイベントの確認
  3. リソースタグ情報とプリンシパルタグ情報付加
  4. プリンシパルタグ情報付加の実践
  5. IAMグローバル条件キー付加の実践
  6. コンプライアンス監視の分析活用

実際のAWS環境で検証し、具体的なユースケースとともに解説していきます。

イベントエンリッチメント機能の概要と効果

機能の目的と効果

この機能は、標準のCloudTrailイベントに以下の情報を自動的に付加します。

付加情報 詳細 活用例
リソースタグ イベント対象リソースのタグ情報 部署別、プロジェクト別のアクセス監視など
IAMグローバル条件キー リクエスト時のIAM条件情報 IP制限、MFA要求の遵守状況確認など

サポートされるリソースタグ

この機能でサポートしているリソースタグは AWS Resource Groups Tagging API に依存しています。

https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-context-events.html#resource-tags-supported-services

また、マネジメントコンソールの設定画面から、リソースタグの設定にはIAMグローバル条件キーの一つであるプリンシパルタグも含まれるものかと想像できますが、後述の検証結果で補足します。

IAMグローバル条件キーの種類

以下のIAMグローバル条件キーがサポートされています。

キー 値の例
aws:FederatedProvider 「IdP」
aws:TokenIssueTime 「123456789」
aws:MultiFactorAuthAge 「99」
aws:MultiFactorAuthPresent 「true」
aws:SourceIdentity UserName」
aws:PrincipalAccount 「111122223333」
aws:PrincipalArn 「arn:aws:iam::555555555555:role/myRole」
aws:PrincipalIsAWSService 「false」
aws:PrincipalOrgID 「o-rganization」
aws:PrincipalOrgPaths ["o-rganization/path-of-org"]
aws:PrincipalServiceName 「cloudtrail.amazonaws.com」
aws:PrincipalServiceNamesList ["cloudtrail.amazonaws.com"s3.amazonaws.com"]
aws:PrincipalType 「AssumedRole」
aws:userid 「userid」
aws:username 「ユーザー名」
aws:RequestedRegion us-east-2"
aws:SecureTransport 「true」
aws:ViaAWSService 「false」
aws:CurrentTime 「2025-04-30 15:30:00」
aws:EpochTime 「1746049800」
aws:SourceAccount 「111111111111」
aws:SourceOrgID 「o-rganization」

エンリッチメントできるグローバル条件キーが対象とするサービスは限定されています。
対象のサービスをこちらで確認できます。
また、条件キーごとに、リクエストコンテキストに含まれるかどうかの条件があるので、それらの情報はこちらで該当するものを確認できます。

機能有効化前のイベントの確認

機能有効化する前のイベント情報を確認しておきます。
今回の検証では、S3オブジェクトへの GetObject と、CloudTrailの GetTrailStatus のログの情報を確認します。

S3オブジェクトへの GetObject 時のログ

S3バケットのタグを確認します。
後ほどこちらがリソースタグとしてログにエンリッチメントされる想定です。

aws s3api get-bucket-tagging --bucket sample09220840
{
    "TagSet": [
        {
            "Key": "department",
            "Value": "hr"
        }
    ]
}

ユーザーのタグを確認します。
こちらはプリンシパルタグとしてエンリッチメントされる想定です。

aws iam list-user-tags --user-name alice
{
    "Tags": [
        {
            "Key": "team",
            "Value": "operation"
        }
    ]
}

ユーザーにアタッチしているポリシーも確認します。

aws iam get-user-policy --user-name alice --policy-name hogehoge827f720a
{
    "UserName": "alice",
    "PolicyName": "hogehoge827f720a",
    "PolicyDocument": {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "s3:GetObject"
                ],
                "Resource": "arn:aws:s3:::sample09220840/a/${aws:PrincipalTag/team}/*"
            }
        ]
    }
}

S3の GetObject を実行して、ログを確認します。

aws s3api get-object --bucket sample09220840 --key a/operation/test.txt test.txt
{
    "AcceptRanges": "bytes",
    "LastModified": "2025-06-22T16:51:22+00:00",
    "ContentLength": 8,
    "ETag": "\"7c575a4af854fa5b3eccad23aeb3397e\"",
    "ChecksumCRC64NVME": "DECwnFh+QS4=",
    "ChecksumType": "FULL_OBJECT",
    "ContentType": "text/plain",
    "ServerSideEncryption": "AES256",
    "Metadata": {}
}

※ログの出力値はサンプルです

{
    "eventVersion": "1.11",
    "userIdentity": {
        "type": "IAMUser",
        "principalId": "AKIAIOSFODNN7EXAMPLE",
        "arn": "arn:aws:iam::123456789012:user/alice",
        "accountId": "123456789012",
        "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
        "userName": "alice"
    },
    "eventTime": "2025-06-16 22:17:59.000",
    "eventSource": "s3.amazonaws.com",
    "eventName": "GetObject",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "203.0.113.1",
    "userAgent": "aws-cli/2.11.0 Python/3.11.6 Linux/5.10.198-179.794.amzn2.x86_64 exec-env/CloudShell exe/x86_64.amzn.2 prompt/off",
    "errorCode": "",
    "errorMessage": "",
    "requestParameters": {
        "bucketName": "sample09220840",
        "key": "a/operation/test.txt"
    },
    "responseElements": "",
    "additionalEventData": {
        "SignatureVersion": "SigV4",
        "CipherSuite": "TLS_AES_128_GCM_SHA256",
        "bytesTransferredIn": 0,
        "bytesTransferredOut": 123456
    },
    "requestID": "F7F8F9F0G1H2I3J4K5L6M7N8",
    "eventID": "b2c3d4e5-f6a7-8901-2345-67890abcdef1",
    "readOnly": true,
    "eventType": "AwsApiCall",
    "managementEvent": false,
    "recipientAccountId": "123456789012",
    "eventCategory": "Data",
    "tlsDetails": {
        "tlsVersion": "TLSv1.2",
        "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256"
    }
}

リソースタグ、プリンシパルタグともにログからは確認できない状態です。

CloudTrailの GetTrailStatus 時のログ

グローバル条件キーの付与を確認するために有効化前のログを確認しておきます。
前述の通り、グローバル条件キーの対象のサービスは限定されているため、対象のサービスで検証します。
いくつかの条件キーを確認するのみであれば、特別前提の設定は必要ないので、ログの出力値のみ確認します。

aws cloudtrail get-trail-status --name my-trail
{
    "IsLogging": true,
    "LatestDeliveryTime": "2025-06-24T09:30:15.201000+09:00",
    "LatestNotificationTime": "2025-06-24T09:30:15.228000+09:00",
    "StartLoggingTime": "2022-04-12T14:46:25.183000+09:00",
    "LatestDigestDeliveryTime": "2025-06-24T09:01:53.210000+09:00",
    "LatestDeliveryAttemptTime": "2025-06-24T00:30:15Z",
    "LatestNotificationAttemptTime": "2025-06-24T00:30:15Z",
    "LatestNotificationAttemptSucceeded": "2025-06-24T00:30:15Z",
    "LatestDeliveryAttemptSucceeded": "2025-06-24T00:30:15Z",
    "TimeLoggingStarted": "2022-04-12T05:46:25Z",
    "TimeLoggingStopped": ""
}

ログを確認します。

{
    "eventVersion": "1.11",
    "userIdentity": {
        "type": "IAMUser",
        "principalId": "AKIAIOSFODNN7EXAMPLE",
        "arn": "arn:aws:iam::123456789012:user/alice",
        "accountId": "123456789012",
        "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
        "userName": "alice"
    },
    "eventTime": "2025-06-19 15:11:00.000",
    "eventSource": "cloudtrail.amazonaws.com",
    "eventName": "GetTrailStatus",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "203.0.113.1",
    "userAgent": "aws-cli/2.11.0 Python/3.11.6 Linux/5.10.198-179.794.amzn2.x86_64 exec-env/CloudShell exe/x86_64.amzn.2 prompt/off",
    "errorCode": "",
    "errorMessage": "",
    "requestParameters": {
        "name": "my-trail"
    },
    "responseElements": "",
    "additionalEventData": {
        "readOnly": true,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "eventCategory": "Management"
    }
}

リソースタグ情報とプリンシパルタグ情報付加

CloudTrail Lakeの設定でエンリッチメントを行います。
対象とするデータはイベントデータストアのログになります。

イベントのコンテキストで編集を行います。

vscode-paste-1750729618773-xsq6qs4s3o.png

リソースとプリンシパルタグキーを追加 でタグを選択します。
AWS Resource Explorer と連携しているようで、Resource Explorer を有効化しないとリソースタグの候補が自動認識せず、有効化なしでは正しくエンリッチメントできていない動作になっていました。

vscode-paste-1750729890503-mugpn96mam.png

下記のブログなどを参考にしてResource Explorerの有効化を行います。

https://dev.classmethod.jp/articles/aws-resource-explorer-new/

Resource Explorer は環境内のリソースをインデックスする必要があるので、データの反映までに時間がかかるときがあるようです。
すぐに反映できることもあるようですが、最大36時間かかることがあるようなので、注意が必要です。

https://docs.aws.amazon.com/ja_jp/resource-explorer/latest/userguide/troubleshooting_search.html#troubleshooting_search_missing-resources

また、公式ドキュメントからサポートしているリソースを確認すると、以下の文言がありました。

現時点では、ロールやユーザーなどの AWS Identity and Access Management (IAM) リソースにアタッチされたタグを検索に使用することはできません。

参考:
https://docs.aws.amazon.com/ja_jp/resource-explorer/latest/userguide/supported-resource-types.html?icmp=docs_re_console_supported-resource-types

つまり、プリンシパルタグキー(aws:PrincipalTag/tag-key)はサポートされていない?...

試しに Resource Explorer を有効化後、36時間待ってみたのですが、プリンシパルタグは認識してくれませんでした。

気を取り直して、CloudTrail Lakeのエンリッチメント設定を続けます。

リソースタグは自動認識してくれているので、選択します。
プリンシパルタグは自動認識できていないので、試しに aws:PrincipalTag/teamteam を手打ちで入れてみます。

vscode-paste-1750730056059-wkviqqo76m.png

設定を保存します。

エンリッチメント後のS3オブジェクトへの GetObject 時のログ

結果を確認します。

aws s3api get-object --bucket sample09220840 --key a/operation/test.txt test.txt
{
    "AcceptRanges": "bytes",
    "LastModified": "2025-06-22T16:51:22+00:00",
    "ContentLength": 8,
    "ETag": "\"7c575a4af854fa5b3eccad23aeb3397e\"",
    "ChecksumCRC64NVME": "DECwnFh+QS4=",
    "ChecksumType": "FULL_OBJECT",
    "ContentType": "text/plain",
    "ServerSideEncryption": "AES256",
    "Metadata": {}
}
{
    "eventVersion": "1.11",
    "userIdentity": {
        "type": "IAMUser",
        "principalId": "AKIAIOSFODNN7EXAMPLE",
        "arn": "arn:aws:iam::123456789012:user/alice",
        "accountId": "123456789012",
        "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
        "userName": "alice"
    },
    "eventTime": "2025-06-16 22:17:59.000",
    "eventSource": "s3.amazonaws.com",
    "eventName": "GetObject",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "203.0.113.1",
    "userAgent": "aws-cli/2.11.0 Python/3.11.6 Linux/5.10.198-179.794.amzn2.x86_64 exec-env/CloudShell exe/x86_64.amzn.2 prompt/off",
    "errorCode": "",
    "errorMessage": "",
    "requestParameters": {
        "bucketName": "sample09220840",
        "key": "a/operation/test.txt"
    },
    "responseElements": "",
    "additionalEventData": {
        "SignatureVersion": "SigV4",
        "CipherSuite": "TLS_AES_128_GCM_SHA256",
        "bytesTransferredIn": 0,
        "bytesTransferredOut": 123456
    },
    "requestID": "F7F8F9F0G1H2I3J4K5L6M7N8",
    "eventID": "b2c3d4e5-f6a7-8901-2345-67890abcdef1",
    "readOnly": true,
    "eventType": "AwsApiCall",
    "managementEvent": false,
    "recipientAccountId": "123456789012",
    "eventCategory": "Data",
    "tlsDetails": {
        "tlsVersion": "TLSv1.2",
        "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256"
    },
    "eventContext": {
        "requestcontext": null,
        "tagcontext": {
            "principaltags": null,
            "resourcetags": [{
                "arn": "arn:aws:s3:::sample09220840",
                "reportedfrom": "tagging.amazonaws.com",
                "lastreportedat": "2025-06-17 00:02:39.000",
                "tags": {
                    "department": "hr"
                }
            }]
        }
    }
}

eventContext というプロパティが新たに追加されています。
リソースタグ(resourcetags)は出力されていることが確認できました!
プリンシパルタグ(pricipaltags)は... やはり出力されていないように思います。。現時点では、これが正しい動作なのか分かりませんでした。

IAMグローバル条件キー付加の実践

続いて、IAMグローバル条件キーのエンリッチメントをやってみます。
同じくCloudTrail Lake設定の IAMグローバル条件キーを追加 で付加したいものを選択します。
こちらは、サポートされているものが任意で選択できる仕様になっています。

vscode-paste-1750731677336-oryqscnnk6l.png

情報が付加されていることを確認します。

aws cloudtrail get-trail-status --name my-trail
{
    "IsLogging": true,
    "LatestDeliveryTime": "2025-06-24T11:10:41.159000+09:00",
    "LatestNotificationTime": "2025-06-24T11:10:41.194000+09:00",
    "StartLoggingTime": "2022-04-12T14:46:25.183000+09:00",
    "LatestDigestDeliveryTime": "2025-06-24T11:01:48.492000+09:00",
    "LatestDeliveryAttemptTime": "2025-06-24T02:10:41Z",
    "LatestNotificationAttemptTime": "2025-06-24T02:10:41Z",
    "LatestNotificationAttemptSucceeded": "2025-06-24T02:10:41Z",
    "LatestDeliveryAttemptSucceeded": "2025-06-24T02:10:41Z",
    "TimeLoggingStarted": "2022-04-12T05:46:25Z",
    "TimeLoggingStopped": ""
}
{
    "eventVersion": "1.11",
    "userIdentity": {
        "type": "IAMUser",
        "principalId": "AKIAIOSFODNN7EXAMPLE",
        "arn": "arn:aws:iam::123456789012:user/alice",
        "accountId": "123456789012",
        "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
        "userName": "alice"
    },
    "eventTime": "2025-06-19 15:11:00.000",
    "eventSource": "cloudtrail.amazonaws.com",
    "eventName": "GetTrailStatus",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "203.0.113.1",
    "userAgent": "aws-cli/2.11.0 Python/3.11.6 Linux/5.10.198-179.794.amzn2.x86_64 exec-env/CloudShell exe/x86_64.amzn.2 prompt/off",
    "errorCode": "",
    "errorMessage": "",
    "requestParameters": {
        "name": "my-trail"
    },
    "responseElements": "",
    "additionalEventData": {
        "readOnly": true,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "eventCategory": "Management"
    },
    "eventContext": {
        "requestcontext": {
            "aws:ViaAWSService": false,
            "aws:RequestedRegion": "ap-northeast-1",
            "aws:username": "alice",
            "aws:SecureTransport": true
        },
        "tagcontext": null
    }
}

コンプライアンス監視の分析活用

リソースタグを使った分析でのユースケースを実践してみました。

特定のリソースタグを持ったS3バケットへのイベントの発生回数と実行者(プリンシパル)を調べてみます。

CloudTrail Lakeのクエリを使って分析が可能です。

vscode-paste-1750740587688-f7y22vmd0an.jpeg

SELECT
    count(*) as count,
    userIdentity.arn
FROM 
    4b5213c1-45c5-4127-a443-b2526145e513
WHERE
    eventName='GetObject'
    and
    element_at(eventContext.tagcontext.resourcetags[1].tags, 'department')='hr'
GROUP BY
    userIdentity.arn

1ユーザーのみの分析データになってしまいましたが、グラフ化してタグを使ったコンプライアンス監視が可能になりました。

vscode-paste-1750740638692-y6pk5sfys5.png

まとめ

CloudTrail Lake機能によるCloudTrail証跡ログのエンリッチメントをやってみました。
プリンシパルタグでの分析ができない原因が分からなかったのが残念ですが、証跡ログにコンテキスト情報を付加することで特にコンプライアンス監視の要件において、活躍しそうな機能だと感じました。
本記事がどなたかの一助になれば幸いです。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.