S3バケットポリシーが変更/削除されたらメール通知したい
はじめに
みなさんこんにちは、クラウド事業本部コンサルティング部の浅野です。
特定S3バケットのバケットポリシーの変更や削除を明示的に禁止した方が良い時がありますよね。アカウント内に多数のユーザーやロールが作成されているときはOrganizationsのSCP等を使って「PutBucketPolicy」等に「Deny」設定を行えば良いのですが、Organizations管理下にないアカウントに対してはIAMポリシー等で個別に制御しなくてはなりませんし、完璧には制御しにくいです。そのような時に打てる対処法の一つが「変更/削除」の検知だと思います。
今回は明示的にバケットポリシー操作の禁止まではしないが、変更や削除された時にメールにてすぐに検知・アラートを行う構成を組んでみました。
構成
EventBridge -> SNS -> Emailサブスクリプション という非常にシンプルな内容です。
東京リージョンに全てのリソースを構築しています。
やってみた
CloudTrailの確認
まず行いたいイベントタイプがCloudTrailにて記録されているか確認しましょう。「CloudTrail」のダッシュボードでイベントタイプを「PutBucketPolicy」、「DeleteBucketPolicy」でフィルタリングしてみます。
無事に確認できました。上記2つのイベントは「データイベント」ではなく「管理イベント」ですので管理イベントのCloudTrail証跡が有効の場合は記録可能です。別途データイベントの証跡を設定する必要はありません。
SNSトピックの作成とサブスクリプション登録
まずはイベントの受け口となるSNSトピックを作成します。
「SNS」コンソール>「トピックの作成」を選択し、以下の条件でSNSトピックを作成します。
- タイプ: スタンダード
- 名前: edit-s3-bucket-policy-notification-topic
- 暗号化: (デフォルト)alias/aws/sns (AWS管理キー)
作成できました。続いてサブスクリプションの登録を行います。
Eメール宛に通知設定を行います。サブスクリプションフィルターポリシーとRedriveポリシーはデフォルト設定で良いです。
- プロトコル: Eメール
- エンドポイント: 任意のメールアドレス
サブスクリプションを登録し終わったら、設定したメールアドレス宛に以下の「Subscription Confirmation」メールが届いています。
メールリンク内の「Confirm subscription」をクリックしてSNSからの通知を承認してあげましょう。これをしないとメール通知が届きませんので注意です。
以下の画面が表示されればOKです。
SNSの「サブスクリプション」画面上でステータスが「確認済み」となっていればOKです。
EventBridge ルールの作成
続いてCloudTrailのAPIイベントをキャッチするEventBridge ルールを作成します。「EventBridge」のサイドバーから「ルール」を選択し、イベントバスは今回デフォルトを使用しますので「default」を選択し、「ルールを作成」を選択します。
ルールを以下のように設定します。
- 名前: edit-s3-bucket-policy-rule
- 説明: 適宜
- イベントバス: default
- 選択したイベントバスでルールを有効にする: チェックが入っていることを確認
- ルールタイプ: イベントパターンを持つルール
次へを選択し、「イベントパターン」を以下のように設定
{
"source": ["aws.s3"],
"detail-type": ["AWS API Call via CloudTrail"],
"detail": {
"eventSource": ["s3.amazonaws.com"],
"eventName": ["PutBucketPolicy", "DeleteBucketPolicy"],
"requestParameters": {
"bucketName": ["sample-bucket"] // 任意のバケット名
}
}
}
続いてイベントを検知後のアクション先ターゲットを選択します。
- ターゲットタイプ: AWSのサービス
- ターゲット: SNSトピック
- ターゲットの場所: このアカウントのターゲット
- トピック: edit-s3-bucket-policy-notification-topic (先ほど作成したトピック)
- 実行ロールを使用(推奨): 許可
- 実行ロール: 新規作成
最後に設定を最終確認して作成します。
S3バケットポリシー編集 & 通知確認
EventBridgeに設定した該当のバケットのバケットポリシーを編集します。
編集内容はなんでもいいので、下記画像の用に設定しました。
1分も経たないうちにメールにて以下のようにjson形式の本文が通知されました。
{
"version": "0",
"id": "*******",
"detail-type": "AWS API Call via CloudTrail",
"source": "aws.s3",
"account": "*******",
"time": "2025-10-16T01:37:36Z",
"region": "ap-northeast-1",
"resources": [],
"detail": {
"eventVersion": "1.11",
"userIdentity": {
"type": "AssumedRole",
"principalId": "*******:*******",
"arn": "arn:aws:sts::*******:assumed-role/*******/*******",
"accountId": "*******",
"accessKeyId": "*******",
"sessionContext": {
"sessionIssuer": {
"type": "Role",
"principalId": "*******",
"arn": "arn:aws:iam::*******:role/*******",
"accountId": "*******",
"userName": "*******"
},
"attributes": {
"creationDate": "2025-10-16T00:57:17Z",
"mfaAuthenticated": "true"
}
}
},
"eventTime": "2025-10-16T01:37:36Z",
"eventSource": "s3.amazonaws.com",
"eventName": "PutBucketPolicy",
"awsRegion": "ap-northeast-1",
"sourceIPAddress": "104.28.196.2",
"userAgent": "[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36]",
"requestParameters": {
"bucketPolicy": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSpecificUserReadAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::*******:user/*******"
},
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": ["arn:aws:s3:::*******", "arn:aws:s3:::*******/*"]
}
]
},
"bucketName": "*******",
"Host": "*******.s3.ap-northeast-1.amazonaws.com",
"policy": ""
},
"responseElements": null,
"additionalEventData": {
"SignatureVersion": "SigV4",
"CipherSuite": "TLS_AES_128_GCM_SHA256",
"bytesTransferredIn": 356,
"AuthenticationMethod": "AuthHeader",
"x-amz-id-2": "*******",
"bytesTransferredOut": 0
},
"requestID": "*******",
"eventID": "*******",
"readOnly": false,
"resources": [
{
"accountId": "*******",
"type": "AWS::S3::Bucket",
"ARN": "arn:aws:s3:::*******"
}
],
"eventType": "AwsApiCall",
"managementEvent": true,
"recipientAccountId": "*******",
"eventCategory": "Management",
"tlsDetails": {
"tlsVersion": "TLSv1.3",
"cipherSuite": "TLS_AES_128_GCM_SHA256",
"clientProvidedHostHeader": "*******.s3.ap-northeast-1.amazonaws.com"
}
}
}
いつ(time)、どのリソース(eventSource)で、何が(eventName)、誰によって(detail.userIdentity)、どのように(requestParameters.bucketPolicy)変更されたのかが詳しく記載されています。
バケットポリシーの変更内容まで記載してくれるのでわかりやすいですね。
S3バケットポリシー削除 & 通知確認
今度は上記で変更したバケットポリシーを削除してみます。
該当バケットの「アクセス許可」タブからバケットポリシーの「削除」を選択し、入力フィールドに「削除」と入力し削除を行います。
すぐさま「AWS Notification Message」2通目のメールとしてバケットポリシ−が削除された通知が確認できました。
{
"version": "0",
"id": "*******",
"detail-type": "AWS API Call via CloudTrail",
"source": "aws.s3",
"account": "*******",
"time": "2025-10-16T01:39:30Z",
"region": "ap-northeast-1",
"resources": [],
"detail": {
"eventVersion": "1.11",
"userIdentity": {
"type": "AssumedRole",
"principalId": "*******:*******",
"arn": "arn:aws:sts::*******:assumed-role/*******/*******",
"accountId": "*******",
"accessKeyId": "*******",
"sessionContext": {
"sessionIssuer": {
"type": "Role",
"principalId": "*******",
"arn": "arn:aws:iam::*******:role/*******",
"accountId": "*******",
"userName": "*******"
},
"attributes": {
"creationDate": "2025-10-16T00:57:17Z",
"mfaAuthenticated": "true"
}
}
},
"eventTime": "2025-10-16T01:39:30Z",
"eventSource": "s3.amazonaws.com",
"eventName": "DeleteBucketPolicy",
"awsRegion": "ap-northeast-1",
"sourceIPAddress": "104.28.196.2",
"userAgent": "[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36]",
"requestParameters": {
"bucketName": "*******",
"Host": "*******.s3.ap-northeast-1.amazonaws.com",
"policy": ""
},
"responseElements": null,
"additionalEventData": {
"SignatureVersion": "SigV4",
"CipherSuite": "TLS_AES_128_GCM_SHA256",
"bytesTransferredIn": 0,
"AuthenticationMethod": "AuthHeader",
"x-amz-id-2": "*******",
"bytesTransferredOut": 0
},
"requestID": "*******",
"eventID": "*******",
"readOnly": false,
"resources": [
{
"accountId": "*******",
"type": "AWS::S3::Bucket",
"ARN": "arn:aws:s3:::*******"
}
],
"eventType": "AwsApiCall",
"managementEvent": true,
"recipientAccountId": "*******",
"eventCategory": "Management",
"tlsDetails": {
"tlsVersion": "TLSv1.3",
"cipherSuite": "TLS_AES_128_GCM_SHA256",
"clientProvidedHostHeader": "*******.s3.ap-northeast-1.amazonaws.com"
}
}
}
最後に
よくあるシチュエーションなのでハンズオン形式で手順を残せるように今回のブログを記載しました。
この記事がどなたかの役に立てば幸いです。今回は以上です。