はじめに
MSPの一次対応を模擬する演習で、CloudWatch AlarmからOpsItemが自動生成される仕組みを検証していました。動作確認のためCloudTrailのイベント履歴を見たところ、Username列に見慣れないランダムな文字列が並んでいて、一瞬「誰か(何か)がこのアカウントを操作したのでは」と身構えました。
先に結論:Username列だけでなく、生イベントのuserIdentity.typeとinvokedByを見れば、そのAPIリクエストを実際に呼び出したのが何だったのかを特定できます。
環境
- AWS CloudTrail
- Amazon CloudWatch Alarms → AWS Systems Manager OpsCenter(OpsItem自動作成)
- AWS CLI
- リージョン: ap-northeast-1(東京)
症状
イベント履歴に、StartSessionとCreateOpsItemという2つのイベントが近い時刻に並んでいました。StartSessionは自分がSession Managerで接続した覚えがあるので納得できましたが、CreateOpsItemのUsername列は見慣れないランダムな文字列でした。
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=CreateOpsItem \
--max-items 1 \
--query "Events[0].{EventTime:EventTime,Username:Username}"
EventTime: 2026-09-03T08:21:39+09:00
Username: 3d871be2875e38abae9687c6c54b7926
このUsername、IAMユーザー名でもロール名でもない、意味の分からない文字列でした。
切り分け:生イベントを見る
コンソールの一覧やCLIのUsername列だけを見ていても正体は分かりません。生のイベント本体(CloudTrailEvent)に含まれるuserIdentity要素を見ると、詳細情報が入っています。
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=CreateOpsItem \
--max-items 1 \
--query "Events[0].CloudTrailEvent" --output text | python3 -m json.tool
抜粋するとこう入っていました。
{
"userIdentity": {
"type": "AssumedRole",
"arn": "arn:aws:sts::123456789012:assumed-role/AWSServiceRoleForCloudWatchAlarms_ActionSSM/3d871be2875e38abae9687c6c54b7926",
"invokedBy": "ssm.alarms.cloudwatch.amazonaws.com"
},
"eventSource": "ssm.amazonaws.com"
}
同じタイミングで実行したStartSessionの方も確認すると、Usernameはシンプルに自分のIAMユーザー名でした。
Name: StartSession
Username: (自分のIAMユーザー)
原因:userIdentity.typeとinvokedBy
CloudTrailの各イベントにはuserIdentityという要素があり、リクエストを行った主体の種類がtypeフィールドに記録されます。代表的な値は次の通りです(公式ドキュメント)。
| type | 意味 |
|---|---|
IAMUser |
IAMユーザーの認証情報で行われたリクエスト |
AssumedRole |
AWS STSのAssumeRoleで取得した一時的な認証情報で行われたリクエスト |
AWSService |
AWSサービスに属するアカウントが行ったリクエスト |
typeがAssumedRoleのとき、arnはassumed-role/ロール名/ロールセッション名という形式になります。今回の
arn:aws:sts::123456789012:assumed-role/AWSServiceRoleForCloudWatchAlarms_ActionSSM/3d871be2875e38abae9687c6c54b7926
を分解すると、ロール名がAWSServiceRoleForCloudWatchAlarms_ActionSSM、Username欄に出ていた謎の文字列は**ロールセッション名(RoleSessionName)**でした。ランダムに見えたのは、人間ではなく仕組み側が機械的に発行した値だったからです。
さらにinvokedByというフィールドは、公式ドキュメントで「AWSサービスがリクエストを行った場合にのみ現れる、そのサービス名」と定義されています。このフィールドがあれば、少なくともこのAPIリクエスト自体はAWSサービスが行ったと判断できます(ただし、その手前に人間の操作が起点としてあったかどうかまでは、このフィールド単体では分かりません。今回のケースでは「自分がCloudWatch Alarmを事前に設定した」という人間の操作が起点にあり、それをトリガーにCloudWatchが自動でこのAPIを呼んだ、という流れです)。
今回のCreateOpsItemはinvokedBy: ssm.alarms.cloudwatch.amazonaws.comが付いており、これはCloudWatch AlarmがOpsItemを作成するために自動で引き受けるサービスリンクロールでした。AWS公式ドキュメントにも、次の2点が明記されています。
- 「CloudWatchはアラームをOpsItem作成用に設定すると、
AWSServiceRoleForCloudWatchAlarms_ActionSSMという名前のサービスリンクロールをIAM内に新規作成する」(Configure CloudWatch alarms to create OpsItems) - 「
AWSServiceRoleForCloudWatchAlarms_ActionSSMはCloudWatchが信頼して引き受けるロールで、ssm:CreateOpsItemの実行権限を持つ」(Using service-linked roles for CloudWatch)
解決:見分け方のチェックリスト
CloudTrailで「このAPIリクエストを実際に呼び出したのは何か」を調べるときは、次の順で確認すると判断しやすいです(Usernameが見慣れているかどうかは調査を始めるきっかけに過ぎず、判定の決め手にはしない方が安全です。IAMロールやフェデレーションなど、人間の操作でも一時的な認証情報になるケースは他にもあるためです)。
- 生イベントの
userIdentity.typeを確認する(AssumedRoleなら一時的な認証情報を経由している) -
AssumedRoleならarnのロール名と、sessionContext.sessionIssuerを確認する -
invokedByフィールドの有無を確認する。あれば、そのAPIリクエスト自体はAWSサービスが行ったものと判断できる - サービスリンクロールらしき名前(
AWSServiceRoleFor...)であれば、そのロールが何のためのものかAWS公式ドキュメントで確認する
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=<調べたいイベント名> \
--max-items 1 \
--query "Events[0].CloudTrailEvent" --output text | python3 -m json.tool
教訓
-
Username列の見た目だけで判断せず、userIdentity.typeとinvokedByまで見ると、そのAPIリクエストを実際に呼び出したのが何かを特定できる - サービスリンクロールの名前(
AWSServiceRoleFor...)には用途が書かれていることが多く、それだけでも手がかりになる。ただし最終的には公式ドキュメントで役割を確認するのが確実 - CloudTrailのイベント履歴(
lookup-events)で参照できる管理イベントは過去90日間。より長期の保存・分析が必要な場合は、Trailの設定やCloudTrail LakeのEvent Data Storeを検討する
おわりに
見慣れない文字列がUsername欄に並んでいるのを見た瞬間は、正直「乗っ取られたか」と一瞬身構えました😅 実際には自分が設定したCloudWatch Alarmが、正規のサービスリンクロールを使って自動で動いていただけでした。CloudTrailは「誰が」だけでなく「何が」を調べる道具でもあるんだな、と実感した一件です。同じように見慣れないUsernameに遭遇した人の参考になれば嬉しいです🙌
参考
- AWS公式: CloudTrail userIdentity element
https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-user-identity.html - AWS公式: lookup-events — AWS CLI Command Reference
https://docs.aws.amazon.com/cli/latest/reference/cloudtrail/lookup-events.html - AWS公式: Configure CloudWatch alarms to create OpsItems
https://docs.aws.amazon.com/systems-manager/latest/userguide/OpsCenter-create-OpsItems-from-CloudWatch-Alarms.html - AWS公式: Using service-linked roles for CloudWatch(AWSServiceRoleForCloudWatchAlarms_ActionSSMの権限)
https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/using-service-linked-roles.html#service-linked-role-permissions-opsitem