初めに
こちらは セゾンテクノロジー Advent Calendar 2025 シリーズ1の12日目の記事です。
クラウドセキュリティ向上のために GuardDuty と Security Hub を統合し、EventBridge を介して通知する仕組みを構築することになりました。
ちゃんと通知できるかテストしていたところ、何回か小石につまずいたので備忘もかねて残します。
フィルターのテストに焦点を絞り、それ以外については深堀しません。
実装
ざっくりとした要件は以下の通りです。
- CloudFormation で簡単に設定できるようにする
- Security Hub を元ネタにしてイベントを受け取る
- Email か Slack で通知する
特にフィルターと、Emailでの通知の場合は使用する入力トランスフォーマーが期待通り値を拾えるかテストします。
早速、EventBridge で作成したルールのイベントパターンの「編集」からトリガーイベントをテストします。
右上のイベントパターン (フィルター)をサンプルトリガーイベントに合わせて修正して、、、あれ?
{
"detail-type": ["Security Hub Findings - Imported"],
"source": ["aws.securityhub"],
"detail": {
"findings": {
"ProductName": ["GuardDuty"],
"RecordState": ["ACTIVE"],
"Workflow": {
"Status": ["NEW"]
},
"Severity": {
"Label": ["HIGH", "CRITICAL"]
}
}
}
}
{
"version": "0",
"id": "8e5622f9-d81c-4d81-612a-9319e7ee2506",
"detail-type": "Security Hub Findings - Imported",
"source": "aws.securityhub",
"account": "123456789012",
"time": "2019-04-11T21:52:17Z",
"region": "us-west-2",
"resources": ["arn:aws:securityhub:us-west-2::product/aws/macie/arn:aws:macie:us-west-2:123456789012:integtest/trigger/6294d71b927c41cbab915159a8f326a3/alert/f2893b211841"],
"detail": {
"findings": [{
"SchemaVersion": "2018-10-08",
~~~中略~~~
"Severity": {
"Product": 6,
"Normalized": 15
},
~~~中略~~~
"ProductFields": {
~~~中略~~~
"aws/securityhub/SeverityLabel": "LOW",
"aws/securityhub/ProductName": "Macie",
"aws/securityhub/CompanyName": "Amazon"
},
"Resources": [{
"Type": "AwsS3Bucket",
"Id": "arn:aws:s3:::test-bucket-12",
"Partition": "aws",
"Region": "us-west-2"
}],
"RecordState": "ACTIVE",
"WorkflowState": "NEW"
}]
}
}
Severity の中に Label が無いぞ?
代わりに ProductFields の中に aws/securityhub/SeverityLabel というそれっぽいのがあるな、指定し直すか。
Workflow.Status も無いから WorkflowState に直して、、、
なんてことをやると AWS Security Finding Format (ASFF) から外れてしまいます。
現在は非推奨のフィールドもあるようです
ちなみに私は意気揚々とpullrequestを出したところレビューで指摘を受けて初めて知りました。(小声)
テストしたい
では ASFF に沿ったテストはどのようにできるのか?
私は次の手順を踏みました。
- GuardDutyで検出結果のサンプルを生成する
- Security Hub CSPM で検出結果のjsonを取得
- EventBridge のルールの編集に戻り、テストイベントで「独自のイベントを使用」を選択
- デフォルトでは
findings要素がないので追加し、その中に 2-2 でコピーした JSONをペーストし、 Prettifyでそろえる - テストを実行
- デフォルトでは
{
"id": "12345678-90ab-cdef-ghij-klmnopqrstuv",
"account": "123456789012",
"time": "2019-04-11T21:52:17Z",
"region": "ap-northeast-1",
"resources": [],
"source": "<required>",
"detail-type": "<required>",
"detail": {
"findings": [{
# ここにペースト
}]
}
}
検出結果のサンプルを参考に、フィルターと入力トランスフォーマーのテストができました!
終わりに
テンプレートはほとんど Copilot に出力してもらいましたが、サンプルと異なっていた時はまたまたハルシネーションか~とか思ってました。(だとしてもテンプレートはそのまま使用できなかったので修正しましたが)
この備忘が誰かの役に立てれば幸いです。


