Organizations 環境で組織タイプのIAM Access Analyzerの検出結果のみをEventBridgeで通知してみた
はじめに
クラスメソッドメンバーズのAWSアカウントをご利用の場合、セキュリティ強化とメンバーズサービスの提供を目的として、複数のAWSサービスが自動的に有効化され、関連リソースが作成されます。
その一環として、cm-access-analyzer
という名前のAWS IAM Access Analyzerが自動的に全リージョンで作成されます。このIAM Access Analyzerの信頼ゾーンはアカウント単位で設定されています。
以下の記事で解説されているように、マルチアカウント構成では、通常、管理アカウントのみに組織タイプのIAM Access Analyzerを作成し、メンバーアカウントにはIAM Access Analyzerを作成しないケースが多く見られます。
そのため、以前、メンバーアカウントのIAM Access Analyzerを削除するように、全メンバーアカウントにおける全リージョンのcm-access-analyzer
を一括削除する方法をご紹介しました。
今回は、各メンバーアカウントにcm-access-analyzer
を残したまま、管理アカウントに存在する組織タイプのcm-access-analyzer
のみの検出結果をフィルタリングして通知する方法をご紹介します。
構成は以下の通りです。EventBridgeルール以外のリソースはすでに作成済みとします。
前提条件
- 各メンバーアカウントのIAM Access Analyzerの検出結果が管理アカウントの東京リージョンのSecurity Hubに集約している状態であること
- Security Hubは集約リージョンを設定し、全アカウントで有効化している
- 全アカウントの全リージョンで、IAM Access Analyzer名
cm-access-analyzer
が作成済み- 管理アカウントのIAM Access Analyzerのみが組織タイプであること
- メール通知用のAmazon SNSトピックは作成済み
EventBridgeルールを作成する
IAM Access Analyzerの検出結果の通知は、IAMロール用とその他の検出結果用の2つのルールを作成します。
IAMロールはグローバルリソースであるため、1つのリージョンに絞って通知する必要があります。
IAMロール検出結果用ルール
イベントパターンは以下の通りです。
IAMロールの検出結果は、prefix
で東京リージョンの管理アカウントのIAM Access Analyzerに絞っています。111111111111
は、管理アカウントのAWSアカウントIDです。
{
"detail-type": ["Security Hub Findings - Imported"],
"source": ["aws.securityhub"],
"detail": {
"findings": {
"ProductName": ["IAM Access Analyzer"],
"Id": [{
"prefix": "arn:aws:access-analyzer:ap-northeast-1:111111111111:analyzer/cm-access-analyzer"
}],
"RecordState": ["ACTIVE"],
"Region": ["ap-northeast-1"],
"Severity": {
"Label": ["LOW", "MEDIUM", "HIGH", "CRITICAL"]
},
"Resources": {
"Type": ["AwsIamRole"]
}
}
}
}
なお、イベントパターンを使用して検出結果が作成されるメンバーアカウントをフィルタリングし、メンバーアカウントごとに管理アカウントにEventBridgeルールを作成することで、通知先を個別に設定することも可能です。
今回は、入力トランスフォーマーを利用します。入力パスと入力テンプレートは以下の通り設定します。
{
"CreatedAt": "$.detail.findings[0].CreatedAt",
"Description": "$.detail.findings[0].Description",
"Id": "$.detail.findings[0].Id",
"ProductName": "$.detail.findings[0].ProductName",
"Recommendation": "$.detail.findings[0].Remediation.Recommendation",
"ResourceOwnerAccount": "$.detail.findings[0].ProductFields.ResourceOwnerAccount",
"SourceUrl": "$.detail.findings[0].SourceUrl",
"Title": "$.detail.findings[0].Title"
}
"[ ProductName ] <ProductName>"
"[ Title ] <Title>"
"[ Description ] <Description>"
"[ Recommendation ] <Recommendation>"
"[ SourceUrl ] <SourceUrl>"
"[ CreatedAt ] <CreatedAt>"
"[ ResourceOwnerAccount] <ResourceOwnerAccount>"
"[ Id] <Id>"
IAMロール以外のリソース検出結果用ルール
イベントパターンは以下の通りです。
検出結果の通知は全リージョンに存在する組織タイプのIAM Access Analyzer(cm-access-analyzer
)の検出結果が対象のため、wildcard
で全リージョンにしています。
{
"detail-type": ["Security Hub Findings - Imported"],
"source": ["aws.securityhub"],
"detail": {
"findings": {
"ProductName": ["IAM Access Analyzer"],
"RecordState": ["ACTIVE"],
"Id": [{
"wildcard": "arn:aws:access-analyzer:*:111111111111:analyzer/cm-access-analyzer*"
}],
"Severity": {
"Label": ["LOW", "MEDIUM", "HIGH", "CRITICAL"]
},
"Resources": {
"Type": [{
"anything-but": "AwsIamRole"
}]
}
}
}
}
こちらも同様に入力トランスフォーマーを利用します。入力パスと入力テンプレートは、IAMロール用と同じです。
{
"CreatedAt": "$.detail.findings[0].CreatedAt",
"Description": "$.detail.findings[0].Description",
"Id": "$.detail.findings[0].Id",
"ProductName": "$.detail.findings[0].ProductName",
"Recommendation": "$.detail.findings[0].Remediation.Recommendation",
"ResourceOwnerAccount": "$.detail.findings[0].ProductFields.ResourceOwnerAccount",
"SourceUrl": "$.detail.findings[0].SourceUrl",
"Title": "$.detail.findings[0].Title"
}
"[ ProductName ] <ProductName>"
"[ Title ] <Title>"
"[ Description ] <Description>"
"[ Recommendation ] <Recommendation>"
"[ SourceUrl ] <SourceUrl>"
"[ CreatedAt ] <CreatedAt>"
"[ ResourceOwnerAccount] <ResourceOwnerAccount>"
"[ Id] <Id>"
IAMロールを作成してみる
AWSアカウントの関係性は以下の通りです。
- 組織外アカウント:000000000000
- 管理アカウント:111111111111
- メンバーアカウント:222222222222
メンバーアカウント(222222222222
)内で、組織外のアカウント(例:000000000000
)からAssumeRoleできるIAMロールを作成します。
AWS CloudShellを開き、以下のコマンドを実行します。
組織外のアカウントは、実際に存在するアカウントにする必要があります。
$ aws iam create-role --role-name TestAccessAnalyzerRole \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::000000000000:root"
},
"Action": "sts:AssumeRole"
}
]
}'
IAMロールを作成すると、メール通知が届きました。管理アカウントのアナライザーが検出結果を作成していることを確認できます。
一方、メンバーアカウントのアナライザーの検出結果は、狙い通りメール通知されませんでした。
"[ ProductName ] IAM Access Analyzer"
"[ Title ] AwsIamRole/arn:aws:iam::222222222222:role/TestAccessAnalyzerRole/ allows cross-account access"
"[ Description ] AWS::IAM::Role/arn:aws:iam::222222222222:role/TestAccessAnalyzerRole/ allows cross-account access from AWS 000000000000"
"[ Recommendation ] {Text:If the access isn't intended, it indicates a potential security risk. Use the console for the resource to modify or remove the policy that grants the unintended access. You can use the Rescan button on the Finding details page in the Access Analyzer console to confirm whether the change removed the access. If the access is removed, the status changes to Resolved.}"
"[ SourceUrl ] https://console.aws.amazon.com/access-analyzer/home?region=ap-northeast-1#/findings?resource=arn%3Aaws%3Aiam%3A%3A222222222222%3Arole%2FTestAccessAnalyzerRole"
"[ CreatedAt ] 2025-01-06T01:27:26.265Z"
"[ ResourceOwnerAccount] 222222222222"
"[ Id] arn:aws:access-analyzer:ap-northeast-1:111111111111:analyzer/cm-access-analyzer/arn:aws:iam::222222222222:role/TestAccessAnalyzerRole"
以下は、Security Hub経由でEventBridgeに送信されるIAM Access Analyzerの検出結果の例です。
{
"version": "0",
"id": "3bd0c5a6-f966-d408-789f-e9a0ec9622ef",
"detail-type": "Security Hub Findings - Imported",
"source": "aws.securityhub",
"account": "111111111111",
"time": "2025-01-06T00:36:51Z",
"region": "ap-northeast-1",
"resources": [
"arn:aws:securityhub:ap-northeast-1::product/aws/access-analyzer/arn:aws:access-analyzer:ap-northeast-1:111111111111:analyzer/cm-access-analyzer/arn:aws:s3:::analyzer-tests-222222222222-member-account"
],
"detail": {
"findings": [
{
"AwsAccountId": "222222222222",
"CompanyName": "AWS",
"CreatedAt": "2025-01-06T01:27:33.905Z",
"Description": "AWS::IAM::Role/arn:aws:iam::222222222222:role/TestAccessAnalyzerRole/ allows cross-account access from AWS 000000000000",
"FindingProviderFields": {
"Types": [
"Software and Configuration Checks/AWS Security Best Practices/External Access Granted"
],
"Severity": {
"Normalized": 1,
"Label": "LOW",
"Product": 1
}
},
"GeneratorId": "aws/access-analyzer",
"Id": "arn:aws:access-analyzer:ap-northeast-3:222222222222:analyzer/cm-access-analyzer/arn:aws:iam::222222222222:role/TestAccessAnalyzerRole",
"ProcessedAt": "2025-01-14T00:10:23.361Z",
"ProductArn": "arn:aws:securityhub:ap-northeast-3::product/aws/access-analyzer",
"ProductFields": {
"ResourceOwnerAccount": "222222222222",
"aws/securityhub/FindingId": "arn:aws:securityhub:ap-northeast-3::product/aws/access-analyzer/arn:aws:access-analyzer:ap-northeast-3:222222222222:analyzer/cm-access-analyzer/arn:aws:iam::222222222222:role/TestAccessAnalyzerRole",
"aws/securityhub/ProductName": "IAM Access Analyzer",
"aws/securityhub/CompanyName": "AWS"
},
"ProductName": "IAM Access Analyzer",
"RecordState": "ACTIVE",
"Region": "ap-northeast-3",
"Remediation": {
"Recommendation": {
"Text": "If the access isn't intended, it indicates a potential security risk. Use the console for the resource to modify or remove the policy that grants the unintended access. You can use the Rescan button on the Finding details page in the Access Analyzer console to confirm whether the change removed the access. If the access is removed, the status changes to Resolved."
}
},
"Resources": [
{
"Details": {
"Other": {
"External Principal Type": "AWS",
"Condition": "none",
"Resource Control Policy Restriction Type": "NOT_APPLICABLE",
"Action Granted": "sts:AssumeRole",
"External Principal": "000000000000"
}
},
"Id": "arn:aws:iam::222222222222:role/TestAccessAnalyzerRole",
"Type": "AwsIamRole"
}
],
"SchemaVersion": "2018-10-08",
"Severity": {
"Label": "LOW",
"Normalized": 1,
"Product": 1
},
"SourceUrl": "https://console.aws.amazon.com/access-analyzer/home?region=ap-northeast-3#/findings?resource=arn%3Aaws%3Aiam%3A%3A222222222222%3Arole%2FTestAccessAnalyzerRole",
"Title": "AwsIamRole/arn:aws:iam::222222222222:role/TestAccessAnalyzerRole/ allows cross-account access",
"Types": [
"Software and Configuration Checks/AWS Security Best Practices/External Access Granted"
],
"UpdatedAt": "2025-01-14T00:10:23.056421296Z",
"Workflow": {
"Status": "NEW"
},
"WorkflowState": "NEW"
}
]
}
}
検出結果を確認した後、IAMロールを削除します。
$ aws iam delete-role --role-name TestAccessAnalyzerRole
S3バケットのバケットポリシーでも検出結果が通知されるかを確認します。
S3バケットを作成し、次にS3バケットポリシーを設定します。
$ aws s3api create-bucket --bucket test-access-analyzer-bucket-xxxxxxxxxx \
--create-bucket-configuration LocationConstraint=ap-northeast-3 \
--region ap-northeast-3
$ aws s3api put-bucket-policy --bucket test-access-analyzer-bucket-xxxxxxxxxx \
--policy '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::000000000000:root"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::test-access-analyzer-bucket-xxxxxxxxxx/*"
}
]
}'
S3バケットを作成すると、IAMロールと同様に管理アカウントのアナライザーが検出結果を作成し、メール通知が届きました。
通知を確認した後、S3バケットを削除します。
$ aws s3api delete-bucket --bucket test-access-analyzer-bucket-xxxxxxxxxx --region ap-northeast-3
参考