JMDC TECH BLOG

JMDCのエンジニアブログです

AWS ConfigとSlack連携で実現!S3バケットポリシーの不正・意図しない変更を即座に検知する仕組み

こんにちは。株式会社JMDC データウェアハウス開発部の古橋です。
今年、JMDCではアドベントカレンダーに参加しています。
qiita.com 本記事は、JMDC Advent Calendar 2025 18日目の記事です。


目次

1. はじめに

本記事でご紹介するのは、AWSサービスを利用して以下を実現する仕組みです。

1. AWS Configを利用し、S3バケットポリシーの変更をリアルタイムで監視する
2. 意図しない変更(具体的には、特定のアクセス許可設定が削除されるような変更)を検知し、Slackへ自動通知する

S3に重要なデータを保持する場合、バケットポリシーはセキュリティの要になります。

筆者が担当するシステムでは、S3を経由して複数のシステムとデータを連携しています。そのため、バケットポリシーが不正に書き換えられることは、データ連携の信頼性を揺るがす一大事です。
実際、過去には担当者の誤操作によりバケットポリシーを意図せず上書きしてしまうインシデントが発生しました。
この経験から、S3バケットポリシーのリアルタイム監視と検知の仕組みを構築する必要性を痛感しました。

本記事では、その具体的な仕組みと実装方法をご紹介いたします。

2. システム概要と構成要素

メインで利用するAWSサービスは以下の2つです。

  • AWS Config:S3バケットポリシーの変更を検知するトリガー
  • Amazon EventBridge:Configからのイベントを受け取り、Slackへメッセージを送信

構成図

3. 構築手順

構築手順の説明は以下の前提で行います。

  • S3バケットポリシーに、AWSアカウントID「012345678910」の許可設定が入っている状態を正とする
  • この許可設定が削除されるような更新が加わった時、Slackに通知する
  • AWSリソースはCloudFormationで構築する

🚨注意🚨
本章に登場するソースコードはサンプルコードです。使用前に必ず見直してください。
本章に登場するアカウントID「012345678910」はダミー値です。使用前に実在するアカウントIDに置換してください。

3.1. S3バケットの準備

監視対象のS3バケットとして、以下のポリシーを持つバケットを作成します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::012345678910:root"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::config-rule-target-bucket/*",
            "Condition": {
                "StringEquals": {
                    "aws:PrincipalArn": "arn:aws:iam::012345678910:role/s3-xaccess-test-role"
                }
            }
        }
    ]
}
3.2. AWS Configの設定

AWS Configで設定できるルールは2タイプあります。

  • マネージドルール:AWS側で事前に定義されたルール
  • カスタムルール:LambdaまたはGuardを利用してユーザー独自で定義するルール

今回はマネージドルールの「S3_BUCKET_POLICY_GRANTEE_CHECK」を利用します。
CloudFormationのテンプレートは以下の通り。

Resources:
  ConfigRuleForPublishBucketPolicy: 
    Type: AWS::Config::ConfigRule
    Properties: 
      ConfigRuleName: "jmdc-test-s3-bucket-policy-grantee-check"
      Description: "Policy checks for public buckets"
      EvaluationModes: 
        - Mode: "DETECTIVE"     # 対象が更新されたタイミングで評価するモード
      InputParameters: |
          {"awsPrincipals": "arn:aws:iam::012345678910:root"}
      Scope: 
        ComplianceResourceTypes: 
          - "AWS::S3::Bucket"
      Source: 
        Owner: AWS     # マネージドルールを使う場合は"AWS"固定
        SourceIdentifier: "S3_BUCKET_POLICY_GRANTEE_CHECK"

⚠️マネージドルールでは、監視対象を特定のバケットに絞る設定をサポートしてないようです。
監視対象を指定したい場合はカスタムルールを作る必要があります。

3.3. EventBridgeの設定

「Configルールが非準拠になったイベントを受け取ってSlackに通知する」というEventルールを作成します。
CloudFormationのテンプレートは以下の通り。(SlackAPIの接続設定については省略)

  NonCompliantNotificationRule:
    Type: AWS::Events::Rule
    Properties:
      EventBusName: default
      EventPattern:
        source:     # イベントの発信元を指定
          - aws.config
        detail-type:     # イベントの具体的な種類を指定
         - Config Rules Compliance Change
        detail:     # イベントデータ本体に対してフィルタリングを適用する
          messageType:
            - ComplianceChangeNotification
          configRuleName:
            - jmdc-test-s3-bucket-policy-grantee-check
          newEvaluationResult:
            complianceType:
              - NON_COMPLIANT     # 非準拠に変わる場合に限定(非準拠から準拠に変わる場合はスルー)
      Name: test-notify-config-non-compliant-rule
      State: ENABLED
      Targets:
        - Id: test-notify-config-non-compliant-target
          Arn: !GetAtt NotifyDestination.Arn
          RoleArn: !GetAtt ApiExecutionRole.Arn
          InputTransformer:
            InputPathsMap:
              account: $.account
              detail-type: $.detail-type
              detail-configRuleName: $.detail.configRuleName
              id: $.id
              region: $.region
              resources: $.resources[0]
              source: $.source
              time: $.time
            InputTemplate: !Sub |-
              {
                  "channel": "${NotifiedSlackChannelId}",     # 送信先のSlackチャンネルID
                  "text": "Bucket policy non-compliance notification \n RuleName: <detail-configRuleName>"     # Slackに届くメッセージ内容
              }

4. 動作検証

それでは、実際に検知されるか試してみましょう。

まずは構築直後の状態です。
(3.2.)で作成したConfigルールをマネジメントコンソールで確認すると、(3.1.)で作成したS3バケットは「準拠」になっています。

4.1. S3バケットポリシーの意図的な変更

非準拠になるようにバケットポリシーを書き換えます。
※実際に存在するアカウントIDでないとエラーになるため、アカウントID部分はマスキングしています。

4.2. 通知の確認

数分待つと、、、

宛先に指定したSlackチャンネルにメッセージが届きました!

マネジメントコンソールを確認してみると、評価結果が「非準拠」に変わってますね。

5. おわりに

この記事では、S3バケットポリシーの意図しない変更をリアルタイムで検知する仕組みをご紹介しました。

筆者はAWS Configに触れるのが初めてだったので、試行錯誤しながらの構築になりました。
振り返ってみるとブラッシュアップするポイントがたくさんあると感じます。

  • マネージドルールだと監視対象を細かく指定できない ⇒カスタムルールで試してみたい
  • Slack通知の内容があまりにも簡素 ⇒バケット名や変更時刻、変更前後の差分などを盛り込みたい
  • 他のAWSリソースにも応用できそう

最後までお読みいただき、ありがとうございました。
この仕組みが、同様の課題を抱える方々の一助となれば幸いです。

6. 参考情報

本記事の作成および実装にあたり、以下のドキュメントや記事を参考にしました。

  • マネージドルール一覧

List of AWS Config Managed Rules - AWS Config

  • ConfigルールのCloudFormationテンプレート

AWS::Config::ConfigRule - AWS CloudFormation


明日19日目は、姜さんによる「個人情報連携システムにおけるセキュリティ設計」です。お楽しみに!

JMDCでは、ヘルスケア領域の課題解決に一緒に取り組んでいただける方を積極採用中です!
フロントエンド /バックエンド/ データベースエンジニア等、様々なポジションで募集をしています。
詳細は下記の募集一覧からご確認ください。 hrmos.co

まずはカジュアルにJMDCメンバーと話してみたい/経験が活かせそうなポジションの話を聞いてみたい等ございましたら、下記よりエントリーいただけますと幸いです。
hrmos.co

★最新記事のお知らせはぜひ X(Twitter)、またはBlueskyをご覧ください!
twitter.com bsky.app