Security HubのFindingステータス遷移を検出タイプごとで検証し、通知設計とトリアージ運用に落とし込んでみた
はじめに
Security Hubを有効化すると、findingにはstatusとactivity_nameという2つのフィールドが存在します。本記事では、この2つのフィールドがそれぞれどういう意味を持ち、いつ・どう変化するのかを実際に確認します。これらを理解して正しい通知ルールやトリアージ運用を設計することが可能になることを目指していきます。
本記事では、Security Hubが生成する5種類のfinding(Exposure Finding/IAM Analysis Finding/Compliance Finding/Vulnerability Finding/GuardDuty)それぞれに対して実際に検出を発生させ、修正・削除・手動操作を行いながらactivity_nameとstatusがどう変化するかを検証してみました。そのうえで、通知ルール(EventBridge)とトリアージ運用への落とし込み方を整理します。
なお、EventBridgeのフィルタパターンの書き方そのものは新Security Hubのイベント通知を試してみたで製品別に詳しく紹介されています。本記事は「状態遷移のどのタイミングで、どんなイベントが実際に発生するのか」を実地検証で明らかにしたうえで、その裏付けをもとにしたフィルタ設計とトリアージ運用に焦点を当てます。
検証方法について
status/activity_nameの変化は、Security HubコンソールやGetFindingsV2APIで確認することもできますが、本記事ではEventBridgeに配信されるFindings Imported V2イベントを対象に検証しています。findingを操作するたびに発生するこのイベントをCloudWatch Logsへ転送し、CloudWatch Logs Insightsでクエリして時系列を追う、という方法です。
これは、本記事のもう一方の目的である「通知ルール(EventBridge)への落とし込み」を意識したものです。実際に通知ルールを設計する際にフィルタ対象となるのはこのFindings Imported V2イベントそのものなので、検証もそのイベント単位で行うことで、確認した結果がそのまま通知ルールの条件設計に転用できます。そのため、以降のJSON例やフィールドの説明も、EventBridgeイベントの構造(detail.findings[0]配下にfindingの内容が入る形)を前提に記載しています。このenvelope構造自体はEventBridge event formatsで確認することができます。
Security Hubの基礎知識
status と activity_name の定義について確認する
検証結果に入る前に、AWSドキュメントとOCSF公式スキーマを確認して分かることを整理します。
status/status_id
OCSF公式スキーマの参照先です。
上記のページからstatus_idが取りうる値と説明について抜き出します。またAWSドキュメントで記載されていた内容も表に追記し整理しました。
| status_id | status | OCSF公式の説明文(日本語訳) | AWS Security Hub固有の補足 |
|---|---|---|---|
| 0 | Unknown | ステータスは不明。 | - |
| 1 | New | findingは新規で、まだレビューされていない。 | - |
| 2 | In Progress | findingはレビュー中である。 | - |
| 3 | Suppressed | findingはレビューされ、無害または誤検知と判断され、現在は抑制されている。 | - |
| 4 | Resolved | findingはレビュー・是正され、現在は解決済みとみなされている。 | - |
| 5 | Archived | findingはアーカイブされた。 | finding providerまたは調査中の顧客が、このfindingはもう関連性がないと判断した状態(Security Hub conceptsより) |
| 6 | Deleted | findingは削除された。例えば、誤って作成された場合などが該当する。 | Security Hubでは顧客は設定不可(BatchUpdateFindingsV2が受け付けるStatusIdの許容値から6のみ除外されていることを本記事の実地検証で確認) |
statusが実際のイベントでどう現れるかは、activity_id/activity_nameとあわせて次項でまとめて示します。
activity_id/activity_name
こちらもOCSF公式スキーマを確認します。AWSドキュメントでは説明に関する主な記載を見つけることはできませんでした。
| activity_id | activity_name | OCSF公式の説明文(日本語訳) |
|---|---|---|
| 0 | Unknown | イベントのアクティビティは不明。 |
| 1 | Create | findingが作成された。 |
| 2 | Update | findingが更新された。 |
| 3 | Close | findingがクローズされた。 |
| 99 | Other | イベントのアクティビティがマッピングされていない。 |
statusとactivity_id/activity_nameは、実際のイベントでは1つのfinding内に併存するフィールドです。以下は、今回の検証で実際に取得したイベントの全体像です(Compliance Finding、EC2セキュリティグループ削除によってCloseした時点。可読性のため、リソース詳細など一部フィールドは省略しています)。
{
"version": "0",
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"detail-type": "Findings Imported V2",
"source": "aws.securityhub",
"account": "111122223333",
"time": "2026-07-28T02:53:00Z",
"region": "ap-northeast-3",
"resources": ["<metadata.uid のハッシュ値>"],
"detail": {
"findings": [
{
"activity_id": 3,
"activity_name": "Close",
"class_name": "Compliance Finding",
"class_uid": 2003,
"severity": "Informational",
"severity_id": 1,
"status": "New",
"status_id": 1,
"type_name": "Compliance Finding: Close",
"type_uid": 200303,
"finding_info": {
"uid": "arn:aws:securityhub:ap-northeast-3:111122223333:subscription/aws-foundational-security-best-practices/v/1.0.0/EC2.19/finding/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"title": "EC2.19 Security groups should not allow unrestricted access to ports with high risk"
},
"metadata": {
"product": { "name": "Security Hub" }
}
}
]
}
}
イベント全体の構造としては、EventBridgeのenvelope(version/detail-type/source/account/time/region)の中にdetail.findingsという配列があり、その1件(1件のイベントにつき常に1件のfinding)の中にstatus/activity_id/activity_nameが並んで存在しています(Security Hub検出のJSONを表示などで確認できるものと同一)。この例ではactivity_name: "Close"(findingとしてのライフサイクルは終了)でありながら、status: "New"(人間側は未着手のまま)という組み合わせが実際に起きていることも読み取れます。
ここまでがドキュメントで確認できた内容でした。 一方で、status_idとactivity_nameとの関連性はどうなっているのか、activity_nameの各値に遷移する時の条件は何なのかは、ドキュメントでは確認できませんでした。そこで5種類のfindingを実際に操作・観察して確かめてみたいと思います。
ASFF(v1)とOCSFでの状態管理の違い
新しいSecurity HubはOCSFをベースにしており、旧Security Hub(ASFF)とは状態管理の考え方そのものが変わっています。
尚Security Hubが準拠しているOCSFのバージョンは1.6です。
Security Hub currently supports findings in OCSF schema version 1.6.
(Security Hub and the Open Cybersecurity Findings Format (OCSF)より)
| 概念 | 旧Security Hub(ASFF) | Security Hub(OCSF) |
|---|---|---|
| ステータスを表すフィールド | Workflow.Status(調査進捗)+RecordState(ACTIVE/ARCHIVED、finding provider専用) |
status/status_idの1フィールド(両者の値セットを比較する限り、2フィールドの概念が1フィールドに集約されていると考えられる) |
| Create/Update/Closeの区別 | フィールドとして存在しない | activity_id/activity_nameとして明示的に存在 |
旧Security Hubには存在しなかったactivity_id/activity_nameという軸の新設が、本記事全体の起点になります。
検証した5つのfinding種別
Security Hubは検出元によって異なるclass_uid(OCSFのクラス)のfindingを生成します。今回は以下の5種類を検証しました。
class_nameやclass_uidについての情報はOCSF公式スキーマ(Findingsカテゴリ)で確認できます。
| finding種別 | class_name | class_uid | 検出元 | 本記事での検証対象 |
|---|---|---|---|---|
| Exposure Finding | Detection Finding | 2004 | Security Hub Exposure Detection(複数Signal/Traitの相関) | IAMユーザーのMFA無効/弱いパスワードポリシー |
| IAM Analysis Finding | IAM Analysis Finding | 2008 | IAM Access Analyzer(Security Hubが自動作成するサービスリンク型・unused access専用) | 未使用のIAMロール権限 |
| Compliance Finding | Compliance Finding | 2003 | Security Hub CSPM(コントロールチェック) | EC2セキュリティグループの高リスクポート開放(EC2.19) |
| Vulnerability Finding | Vulnerability Finding | 2002 | Amazon Inspector | EC2上のOSパッケージ脆弱性(CVE) |
| GuardDuty | Detection Finding | 2004 | Amazon GuardDuty | サンプルfinding(DoS攻撃検知)+ArchiveFindingsAPI |
GuardDutyはExposure Findingと同じclass_uid: 2004(Detection Finding)を使います。 同じOCSFクラスを異なる検出元(Security Hub Exposure DetectionとGuardDuty)が使う場合に、挙動が共通するのかも検証しています。
metadata.product.nameは5種類それぞれで異なる値(Security Hub Exposure Detection/Security Hub/Inspector/Security Hub/GuardDuty)を持ちますが、Compliance FindingとIAM Analysis Findingは両方とも"Security Hub"と表示されるため、この2つは製品名だけでは区別できません(後述)。
なお、Security Hubに検出を集約するAWSサービスは他にAmazon MacieやNetwork Scanningがありますが、今回の検証では対象外としています。
ここから先は、5種類のfindingを実際に操作・観察して確かめた検証結果です。詳細な検証内容に入る前に、まず結論を先にまとめます。
- Create:finding UIDが初めて生成されたときのみ。同一UIDが二度
Createになることはない - Update:再評価のたびに発生する。内容(severity・compliance状態など)が変化していなくても発生する
- Close:findingが「そのfindingとして存在する根拠」を失ったときに発生する
このうち3番目の「存在する根拠を失う」条件が、finding種別によって大きく異なりました。さらに、GuardDutyでは「Createが必ず最初に発生する」から外れる例外ケースも確認しました。それでは検証の詳細について一つずつ紹介します。
※activity_nameに関する本検証では複雑だったCloseの条件が多く書かれていますが、重要な点としてはCreateは同一finding uidで最初の一度だけ発生する、Updateは再評価などで繰り返し発生する、Closeは様々な条件がある、ということを押さえていただけたらと思います。
activity_name の状態遷移を検証
ここから先は、finding種別ごとにCreate・Update・Closeの3段階を実際に確認していきます。先に結論を言うと、Createは「初回検出時に1回だけ」という点でどの種別も共通していますが、UpdateとCloseはどちらもトリガーが種別ごとに異なります。
1. Exposure Finding:寄与するContributing Traitがすべて解消されるとClose
Create:IAMユーザーの単一ホップでのデータアクセス経路の存在・MFA無効(IAM.5)・弱いパスワードポリシー(IAM.7)という3つのContributing Trait、および管理者権限ポリシーを保持しているというContextual Trait1件、計4件のsignalを持つExposure findingとして初回の検出時にactivity_nameがCreateでイベントが発生しました。実際のCreateイベント(一部サンプル化して抜粋。)は以下の通りです。
{
"detail-type": "Findings Imported V2",
"source": "aws.securityhub",
"account": "111122223333",
"time": "2026-07-21T15:51:45Z",
"region": "ap-northeast-3",
"detail": {
"findings": [{
"activity_id": 1,
"activity_name": "Create",
"class_name": "Detection Finding",
"class_uid": 2004,
"finding_info": {
"created_time_dt": "2026-07-21T15:51:15.418Z",
"desc": "The IAM user has weak password policies and has MFA disabled, exposing it to unauthorized access and privilege escalation. Weak password policies reduce password complexity requirements, making credentials easier to compromise. Without MFA protection, a threat actor could compromise the credentials more easily.",
"related_events": [
{
"title": "AWS::IAM::User <IAMユーザー名> <ユーザーUID>",
"traits": [{ "category": "Impact", "name": "The IAM user has a single hop data access path", "type": "Contributing Trait" }],
"type": "ResourceConfiguration"
},
{
"title": "AWS::IAM::User <IAMユーザー名> <ユーザーUID>",
"traits": [{ "category": "Misconfiguration", "name": "The IAM user has an administrative access policy", "type": "Contextual Trait" }],
"type": "ResourceConfiguration"
},
{
"product": { "name": "Security Hub" },
"title": "IAM.5 MFA should be enabled for all IAM users that have a console password",
"traits": [{ "category": "Misconfiguration", "name": "The IAM user does not have MFA enabled", "type": "Contributing Trait" }],
"type": "Finding"
},
{
"product": { "name": "Security Hub" },
"title": "IAM.7 Password policies for IAM users should have strong configurations",
"traits": [{ "category": "Misconfiguration", "name": "The AWS Account of the IAM user has weak password policies", "type": "Contributing Trait" }],
"type": "Finding"
}
],
"related_events_count": 4,
"title": "Potential Unauthorized Access: IAM user has weak password policies and has MFA disabled",
"types": ["Exposure/Potential Privilege Escalation/Valid Cloud Credentials", "Exposure"],
"uid": "arn:aws:securityhub:ap-northeast-3:111122223333:exposure:<ハッシュ値>"
},
"metadata": {
"product": {
"name": "Security Hub Exposure Detection",
"uid": "arn:aws:securityhub:ap-northeast-3::productv2/aws/securityhub-exposure"
}
},
"severity": "High",
"severity_id": 4,
"status": "New",
"status_id": 1,
"type_name": "Detection Finding: Create",
"type_uid": 200401
}]
}
}
related_eventsの4要素が、先ほど述べた「3つのContributing Trait(単一ホップでのデータアクセス経路/IAM.5/IAM.7)+1つのContextual Trait(管理者権限ポリシー)」の実体です。related_events_count: 4もこれと一致しています。
Update:Exposure Findingsの原因となる一つのContributing Trait:IAM.5(MFA無効)を解消するためにMFAを有効化したところ、約24時間後にUpdateが発生しました。Create時点の値と比較した実データは以下の通りです。
| activity_name | finding_info.uid | severity | likelihood | related_events_count | IAM.5(MFA無効)のsignal |
|---|---|---|---|---|---|
| Create | arn:aws:securityhub:...:exposure:xxxxxxxx... | High | High | 4 | 存在する |
| Update | 同一の値 | Low | Low | 3 | 配列から消滅 |
finding_info.uidは変化しておらず、新規findingではなく既存findingが更新されたことが確認できます。severity・likelihoodはいずれも2段階低下し、related_events_countも4→3に減少、IAM.5(MFA無効)に対応するsignalが配列から消滅していました。一部のContributing Traitが残っている限りはUpdateにとどまります。
Close:さらに残っていたContributing Trait(IAM.7)についても、アカウントのパスワードポリシーを強化して解消したところ、activity_name: Closeへの遷移を確認しました。実際のイベントは以下の通りです。
| @timestamp | class_name | finding | activity_name | compliance.status | 備考 |
|---|---|---|---|---|---|
| 2026-07-24T03:32:25.133Z | Compliance Finding | IAM.7(同一アカウントのパスワードポリシー) | Update | Pass | 是正したIAM.7自体のSecurity Hub CSPMイベント |
| 2026-07-24T05:46:23.572Z | Detection Finding | Exposure finding(本節で追跡している同一finding_info.uid) | Close | - | 上のIAM.7合格を受けて再評価されたExposure findingのイベント |
IAM.7の合格を受けて、Exposure Finding側は約2時間14分後にCloseしました。
一方で別のExposure FindingではContributing Traitが未解消のままCloseしたケースもありました。IAMユーザーのfinding(IAM.3「未ローテーションキー」がContributing Trait、IAM.8とAccess Analyzerのunused access traitがContextual Trait、計3件で構成)における実際のイベントは以下の通りです。
| activity_name | related_events(IAM.3/IAM.8/Access Analyzerのtrait) | severity | status | last_seen_time_dt | modified_time_dt | 備考 |
|---|---|---|---|---|---|---|
| Update | 3件 | Low | New | 2026-06-22T13:38:32Z | 2026-06-22T13:38:32Z | 同日1回目のUpdate |
| Update | 3件、上と内容同一 | Low | New | 2026-06-22T16:37:18Z | 2026-06-22T16:37:18Z | 同日2回目のUpdate。内容は1回目と完全に同一 |
| Update | 3件、上と内容同一 | Low | New | 2026-06-22T22:37:33.880Z | 2026-06-22T22:37:33.880Z | 同日3回目・最後のUpdate。内容は1・2回目と完全に同一 |
| Close | 3件、上のUpdateと一字一句同一 | Low | New | 2026-06-22T22:37:33.880Z(更新されず) | 2026-07-06T18:18:51.808Z(更新) | 最後のUpdateから約14日後に発生。last_seen_time_dtは更新されず、modified_time_dtのみ更新 |
last_seen_time_dt:traitの状態を最後に観測・再評価した時刻modified_time_dt:findingのレコードが最後に書き換えられた時刻(理由を問わず、レコードに何か変更が入れば更新される)
3回のUpdateでは上記両フィールドが毎回一致していますが、Closeではmodified_time_dtだけが更新され、last_seen_time_dtは最後のUpdate時点のまま変化していません。このことからCloseはtraitを改めて観測・再評価した結果ではなく、最後のUpdateから約14日間観測が途絶えたこと自体がトリガーになった可能性もありそうだと思いました。
寄与するContributing Traitを解消することでCloseする、ということは実データで確認できました。その他いくつか不明な点が残ってしまいましたがExposure Findingsに限ってはCloseする条件が他にもありそうだということも分かりました。
2. IAM Analysis Finding:内容が変化すると、旧findingをCloseして新findingを別UIDでCreateする(置き換え型)
Create:未使用のIAMロール権限が初めて検知された時点でCreateされます。severityは一律Lowとなるようです。これはSecurity Hub CSPM(ASFF)に集約される外部アクセスアナライザーと同じような感じですね。ちなみにSecurity Hubでは未使用アクセスアナライザーのみが集約され、外部アクセスアナライザーを設定していた場合も集約されない仕様となっているようです。
実際のCreateイベント(一部抜粋。サービス・アクション単位の詳細な内訳は省略)は以下の通りです。
{
"detail-type": "Findings Imported V2",
"source": "aws.securityhub",
"account": "222233334444",
"time": "2026-07-25T11:24:35Z",
"region": "ap-northeast-3",
"detail": {
"findings": [{
"activity_id": 1,
"activity_name": "Create",
"class_name": "IAM Analysis Finding",
"class_uid": 2008,
"finding_info": {
"created_time_dt": "2026-07-25T11:23:59.972Z",
"title": "AWSIAMRole/arn:aws:iam::222233334444:role/dummy-role/ contains unused permissions",
"types": ["Posture Management", "Software and Configuration Checks/AWS Security Best Practices/Unused Permission"],
"uid": "arn:aws:access-analyzer:us-east-1:222233334444:analyzer/_AccessAnalyzerForSecurityHubV2-<ハッシュ値>/unusedaccess/finding/<ハッシュ値>"
},
"metadata": {
"product": { "name": "Security Hub" }
},
"permission_analysis_results": [{
"total_potential_attacks_count": 63,
"unused_privileges_count": 45,
"unused_services_count": 22
}],
"severity": "Low",
"severity_id": 2,
"status": "New",
"status_id": 1,
"type_name": "IAM Analysis Finding: Create",
"type_uid": 200801
}]
}
}
permission_analysis_resultsには、対象ロールのサービス・アクション単位の未使用権限一覧に加えて、ロール全体の集計値(unused_privileges_countなど)が含まれています。またmetadata.product.nameは"Security Hub"で、前述の通りCompliance Findingと同じ値になっており、この2つは製品名だけでは区別できません。
Update:全体の9割以上がUpdateでした。実際に...ebe722...というfindingの発生時刻と内容を確認すると以下の通りでした(後述するCloseの検証でも同一findingを扱います)。
| @timestamp | finding_info.uid(末尾) | activity_name | unused_privileges_count | total_potential_attacks_count | unused_services_count |
|---|---|---|---|---|---|
| 2026-07-19T22:55:51Z | ...ebe722... | Create | 43 | 62 | 22 |
| 2026-07-20T20:57:07Z | ...ebe722... | Update | 43 | 62 | 22 |
| 2026-07-21T19:00:42Z | ...ebe722... | Update | 43 | 62 | 22 |
| 2026-07-22T17:05:05Z | ...ebe722... | Update | 43 | 62 | 22 |
| 2026-07-23T15:09:00Z | ...ebe722... | Update | 43 | 62 | 22 |
| 2026-07-24T13:18:41Z | ...ebe722... | Update | 43 | 62 | 22 |
| 2026-07-25T11:24:41Z | ...ebe722... | Close | 43 | 62 | 22 |
Create以降、5回のUpdateの間隔はいずれも22時間前後で、ほぼ1日1回のペースで発行され続けていました。しかもunused_privileges_count等の集計値はCreateからCloseの直前まで完全に同一で、その他の検出内容も同一です。Access Analyzerの定期的な再走査(約22時間おき)そのものによって発生していると考えられます。
Close:未使用のIAMロール権限(UnusedPermission)について、あるIAMロール(アカウント222233334444のdummy-role)に対する2つの異なるfinding UIDの履歴があったので注目してみました。
| 時刻 | 対象IAMロール | finding_info.uid(末尾) | activity_name | unused_privileges_count | total_potential_attacks_count |
|---|---|---|---|---|---|
| 07-19 | 222233334444:dummy-role | ...ebe722... | Create | 43 | 62 |
| 07-20〜07-24(5回) | 222233334444:dummy-role | ...ebe722... | Update | 43 | 62 |
| 07-25T11:24:35 | 222233334444:dummy-role | ...b4dcae37... | Create | 45 | 63 |
| 07-25T11:24:41(6秒後) | 222233334444:dummy-role | ...ebe722... | Close | 43 | 62 |
| 07-26/07-27 | 222233334444:dummy-role | ...b4dcae37... | Update | 45 | 63 |
| 07-28 | 222233334444:dummy-role | ...b4dcae37... | Close | 45 | 63 |
新しいfinding(...b4dcae37...)がCreateされたわずか6秒後に、古いfinding(...ebe722...)がCloseしています。これは他の種別では見られなかったパターンですが、未使用権限の内容が変化するたびに、同一UIDのまま状態遷移するのではなく、旧UIDをCloseして新UIDに置き換えていることが分かりました。
同じIAMロールに対する同じ検出ですが、finding_info.uidごとで「内容」がどう変化したのかを確認します。上記結果の通り...ebe722...のpermission_analysis_resultsはCreateからCloseの直前までunused_privileges_count: 43/total_potential_attacks_count: 62のまま変化していませんでしたが、...b4dcae37...のCreate時点ではそれぞれ45/63に増加していました。
差分の内訳を見ると、ec2サービスで以下の2アクションが新たに「未使用」に追加されていました。
| 追加されたアクション | 最終使用日時 |
|---|---|
ec2:RunInstances |
2026-04-26T04:42:20.000Z |
ec2:DescribeVolumes |
2026-04-26T04:43:20.000Z |
IAM Access Analyzerの仕組みとして、未使用権限の判定はロール単位ではなくロールが持つ権限のアクション単位で行われ、指定した日数(今回の環境では90日)呼び出されなかったアクションが「未使用」と判定されます。
(Understand how IAM Access Analyzer findings workより)
上記2つのアクションは最終使用が2026-04-26で、07-25の再評価時点でちょうど90日ルックバック期間を超えたと考えられます。つまりロールの権限設定自体が変更されたのではなく、時間経過によって「未使用」と判定されるアクションが新たに増えたことが、この置き換えの引き金になっていました。
3. Compliance Finding:リソースが評価対象でなくなるとClose(合格だけではCloseしない)
Create:意図的に違反を作ったセキュリティグループ(EC2.19)のfindingは、以下のようにCreateされました(実データより抜粋)。
{
"detail-type": "Findings Imported V2",
"source": "aws.securityhub",
"account": "111122223333",
"time": "2026-07-28T03:02:00Z",
"region": "ap-northeast-3",
"detail": {
"findings": [{
"activity_id": 1,
"activity_name": "Create",
"class_name": "Compliance Finding",
"class_uid": 2003,
"compliance": { "control": "EC2.19", "status": "Fail", "status_id": 3 },
"finding_info": {
"created_time_dt": "2026-07-28T03:01:46.658Z",
"title": "EC2.19 Security groups should not allow unrestricted access to ports with high risk",
"uid": "arn:aws:securityhub:ap-northeast-3:111122223333:subscription/aws-foundational-security-best-practices/v/1.0.0/EC2.19/finding/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
},
"metadata": {
"product": { "name": "Security Hub" }
},
"severity": "Critical",
"severity_id": 5,
"status": "New",
"status_id": 1,
"type_name": "Compliance Finding: Create",
"type_uid": 200301
}]
}
}
Update:内容が変化していなくても、定期チェックのたびにUpdateが発行され続けることを確認しました。SSM.7の同一findingを7日間追跡した実データ(一部抜粋)は以下の通りです。
| @timestamp | activity_name | compliance.status |
|---|---|---|
| 2026-07-21T03:20:35Z | Update | Fail |
| 2026-07-21T15:48:33Z | Update | Fail |
| 2026-07-22T03:21:03Z | Update | Fail |
| … | … | … |
| 2026-07-27T04:02:22Z | Update | Fail |
| 2026-07-27T15:22:40Z | Update | Pass |
compliance.statusがFailのまま6日間・16回Updateが発行され続けており、間隔は約12時間おきとほぼ規則的でした。また、AWS Configが設定変更を検知した場合は、この定期チェックとは別に数分というイベント駆動の速さで即座にUpdateが発行されることも確認しました。EC2.19の設定修正ケース(compliance.statusがFail→Passに変化)では、以下のように変更から約4分後に反映されています。
| @timestamp | activity_name | compliance.status | severity |
|---|---|---|---|
| 2026-07-28T03:01:46Z | Create | Fail | Critical |
| 2026-07-28T03:06:03Z | Update | Pass | Informational |
Close:EC2セキュリティグループの高リスクポート開放(EC2.19)で2パターンを検証しました。
| 是正方法 | compliance.statusの変化 |
結果のactivity_name |
|---|---|---|
| セキュリティグループ自体を削除 | Fail→Unknown(CONFIG_RETURNS_NOT_APPLICABLE) |
Close |
| セキュリティグループのルールを修正 | Fail→Pass |
Update(Closeしない) |
Compliance Findingはコントロール+リソースの1対1の継続追跡です。合格しても「追跡対象がなくなる」わけではなくUpdateのまま存続し、リソース自体が削除されて評価不能になって初めてCloseします。これはASFF(v1)時代のコントロールfindingの挙動と同じ設計思想です。AWS公式ドキュメントにも、合格時は新規findingを生成せず既存findingを更新するだけであること、RecordStateがARCHIVEDになるのはコントロール無効化・リソース削除・長期間未更新(3〜5日、ベストエフォート)・ConfigがNOT_APPLICABLEを返した場合など別トリガーによることが明記されています。
(Generating and updating control findingsより)
4. Vulnerability Finding:脆弱性が実際に解消されるとClose(リソースは残したまま)
Create:InspectorがCVEを検知した時点で、以下のようにCreateされました(実データより抜粋)。
{
"activity_id": 1,
"activity_name": "Create",
"severity": "High",
"severity_id": 4,
"status": "New",
"type_name": "Vulnerability Finding: Create",
"vulnerabilities": [{
"cve": { "uid": "ALAS2023-2026-1916" },
"is_fix_available": true,
"fix_coverage": "Complete"
}]
}
severityはCVEのCVSSスコアに基づく評価(High)でした。
Update:別の3件のCVEについて、実際のイベントを追跡したところ以下の通りでした。
| @timestamp | finding_info.uid(末尾) | activity_name | severity |
|---|---|---|---|
| 2026-06-08T15:40:10Z | ...7afd2ca7 | Create | High |
| 2026-06-08T15:40:14Z | ...3eaaac1e | Create | Medium |
| 2026-06-08T15:40:37Z | ...cb46d6c3 | Create | Medium |
| 2026-06-22T18:44:20Z | ...7afd2ca7 | Update | Medium(Create時はHigh) |
| 2026-06-22T18:44:01Z | ...3eaaac1e | Update | Medium |
| 2026-06-22T18:44:04Z | ...cb46d6c3 | Update | Medium |
| 2026-07-25T07:00:52〜54Z | 3件とも | Update | 各findingとも変化なし |
| 2026-07-28T00:05:52〜38Z | 3件とも | Update | 各findingとも変化なし |
| 2026-07-28T19:11:26〜33Z | 3件とも | Update | 各findingとも変化なし |
ここから以下のような特徴が見られました。
- finding(
...7afd2ca7)はCreate時点のHighからUpdate時点でMediumに変化していましたが、残り2件は不変でした。CVSSスコアの見直し等によって変化したと推測できます - 複数の異なるfinding(別UID)が、数秒差でほぼ同時に
Updateが続きました。Inspectorの定期スキャンや各スキャン契機にしたがって再評価が行われていると思われます
下記ブログで紹介されている通り以下のようなタイミングかと思います。
(Amazon Inspector v2の判定条件、スキャン間隔について確認してみたより)
- Linuxのソフトウェアインベントリ収集は30分間隔(
AWS-GatherSoftwareInventoryドキュメント)- Inspectorの脆弱性データベースに新しいCVEが追加されたタイミングでも再スキャンが行われる(Linux)
- EC2のステータスが「実行中」に変わったタイミング(新規作成・停止からの再開含む)でもスキャンが行われる
Close:Amazon Linux 2023上のCVE(ALAS2023-2026-1916、libblkid等)に対し、dnf upgrade --releasever=...でパッケージを修正版に上げたところ、インスタンスを削除しなくても約30分後にactivity_name: Closeを確認しました。
{
"detail-type": "Findings Imported V2",
"source": "aws.securityhub",
"account": "222233334444",
"time": "2026-07-28T05:51:20Z",
"region": "ap-northeast-3",
"detail": {
"findings": [{
"activity_id": 3,
"activity_name": "Close",
"class_name": "Vulnerability Finding",
"class_uid": 2002,
"finding_info": {
"first_seen_time_dt": "2026-07-28T05:20:29.444Z",
"last_seen_time_dt": "2026-07-28T05:48:16.690Z",
"modified_time_dt": "2026-07-28T05:50:48.879Z",
"uid": "arn:aws:inspector2:ap-northeast-3:222233334444:finding/<ハッシュ値>"
},
"severity": "High",
"severity_id": 4,
"status": "New",
"status_id": 1,
"type_name": "Vulnerability Finding: Close",
"type_uid": 200203,
"vulnerabilities": [{
"affected_packages": [{"name": "libblkid", "version": "2.37.4", "fixed_in_version": "0:2.37.4-1.amzn2023.0.5"}],
"fix_coverage": "Complete",
"is_fix_available": true,
"severity": "high"
}]
}]
}
}
これはCompliance Findingとは逆で、**Exposure Findingと同じ挙動(実際に問題が解消されればリソースを残したままCloseする)**です。
5. GuardDuty:脅威の自然解消ではなく、GuardDuty自身の手動アーカイブ操作がトリガー
Create:サンプルfinding(DoS攻撃検知)を生成した時点で、以下のようにCreateされました(実データより抜粋)。
{
"activity_id": 1,
"activity_name": "Create",
"class_name": "Detection Finding",
"class_uid": 2004,
"finding_info": { "title": "The EC2 instance i-99999999 is behaving in a manner that may indicate it is being used to perform a Denial of Service (DoS) attack using the DNS protocol." },
"metadata": { "labels": ["SAMPLE"], "product": { "name": "GuardDuty" } },
"severity": "High",
"status": "New",
"count": 1
}
Update:同じ検出タイプのサンプルを再度生成したところ、新規Createではなく既存findingのUpdateとして扱われました。実際のイベントの推移は以下の通りです。
| @timestamp | activity_id/name | count |
|---|---|---|
| 2026-07-28T08:14:25Z | 1 / Create | 1 |
| 2026-07-28T08:15:36Z | 2 / Update | 2 |
| 2026-07-28T08:17:24Z | 3 / Close | 2 |
countが1→2に増加し、created_time_dtは不変のまま(同一findingとして更新)でした。これはGuardDuty自身が持つ「同じ種類の検出を1つのfindingに集約し続ける」仕組み(finding aggregation)によるものです。
Close:GuardDutyには、Compliance FindingやVulnerability Findingのような「修正済み」の概念が存在しません。状態はarchived(真偽値)のみで管理されます。上表の3行目の通り、サンプルfindingを、GuardDuty自身のArchiveFindingsAPI(管理者アカウント専用の操作)でアーカイブしたところ、activity_id: 3/activity_name: "Close"を確認しました。GuardDutyのCloseは、脅威が自然に解消されたからではなく、GuardDuty自身のネイティブなアーカイブ操作(別システムでの明示的な手動操作)がSecurity Hub側でactivity_name: Closeとして反映された結果です。
さらに重要な例外:GuardDutyの抑制ルール(Suppression rule。条件に一致するfindingを生成直後に自動アーカイブするGuardDutyのネイティブ機能)の対象となるサンプルfindingを生成したところ、次の結果になりました。
| @timestamp | activity_name |
|---|---|
| 2026-07-28T08:20:17Z | Close(この1件のみ) |
このfindingについてSecurity Hubが受信したイベントはこの1件だけで、Createは一切観測されませんでした。 つまり、抑制ルールが生成直後にマッチした場合、Security Hub側ではactivity_nameがCreateを経由せず、いきなりCloseから始まることがあります。「Createは必ず最初に発生する」という今回検証した中では唯一の例外であり、activity_name: ["Create"]だけを条件にした通知・追跡ロジックでは、抑制ルールで即座にアーカイブされたfindingは捕捉されません。
Create/Update/Closeのトリガーのまとめ
これまでの結果をまとめて比較すると、実はCreateもUpdateも一様ではなく、finding種別ごとにトリガーが異なることが分かります。
| finding種別 | Create | Update | Close | 同一UID |
|---|---|---|---|---|
| Exposure Finding | Trait相関の初回成立 | 寄与Traitの状態変化 | 寄与Trait全解消 | する |
| IAM Analysis Finding | 未使用権限・ロールの初回検知 | 定期再評価(約22時間おき) | 内容変化→旧Close+新Create | しない(置き換え) |
| Compliance Finding | チェックの初回実行 | 定期チェック(12〜24時間おき)/Config変更の即時検知 | リソース/ルールが評価対象外に | する |
| Vulnerability Finding | 脆弱性の初回検知 | 未検証 | 脆弱性の解消 | する |
| GuardDuty | 脅威パターンの初回検知 | 同一脅威の再観測(集約) | 手動アーカイブ操作 | する |
Createはどの種別も「初めて検出された条件について、最初の1回だけ発生する」という点で共通しています(GuardDutyの抑制ルールのように、Create自体が観測されない例外はありますが、Createが2回以上発生することはありません)。
Updateは、実際には2つの異なるトリガーに分かれます。
- 周期的な再評価によるもの:Compliance Finding(12〜24時間)、IAM Analysis Finding(約22時間)のように、内容が変わっていなくても一定間隔で発行される
- イベント駆動によるもの:Compliance FindingがAWS Configの設定変更を検知した際の即時反映(数分後)、Exposure Findingが寄与するTraitの状態変化を検知した際の再評価、GuardDutyが同一の脅威パターンを再度観測した際の集約、のように「何かが変化した/再発した」ことをトリガーに発行される
同じ種別(Compliance Finding)でも、周期的な再評価とイベント駆動の即時反映の両方が観測されており、Updateは単一のトリガーではなく複数の経路を持つ、という点は運用上見落としやすいポイントです。
Closeは、Exposure・Compliance・Vulnerabilityの3つが「findingがそのfindingとして存在する根拠を失ったときCloseする」という同じ原則の現れ方の違いとして説明できる一方、GuardDutyは検出元サービス自身の手動操作、IAM Analysis Findingは同一UIDで遷移しない置き換え型と、トリガーの種類そのものが分かれます。IAM Analysis Findingについては、finding_info.uidだけを追いかけていると同じ問題を継続的に追跡できないことが予想されます。
(この解釈は限られたサンプル数に基づくものであり、他のパターンで状態遷移する条件が存在する可能性があります。)
statusの状態遷移を検証
status(人間側の調査進捗)については、検証した5種類すべてで一貫した挙動が確認できました。
確認済み1:activity_name: Closeになってもstatusは自動で変わらない
Exposure Finding・Compliance Finding・IAM Analysis Finding・GuardDutyいずれも、誰も手動でトリアージしていなければClose時点でもstatusはNewのままでした。
確認済み2:手動でのstatus変更はactivity_name: Updateにはなるが、Closeには絶対にならない
BatchUpdateFindingsV2でstatusをいずれかの値に変更した場合、activity_nameはUpdateになりイベントが発生します。またUpdateにはなりますが、Closeには絶対にならない(status: Archivedを指定した場合も同様)。手動変更にはmetadata.loggers(log_name: "BATCH_UPDATE_FINDINGS")というマーカーが付き、自動的な再評価との判別に使えます。
確認済み3:手動設定したstatusは、根本原因が再発しても自動的にリセットされない(ASFFとの決定的な違い)
Compliance Financeが一度Passになった後、statusを手動でResolvedに変更し、その後意図的に設定を戻してcompliance.statusをFail(severityもCritical)へ再発させたところ、statusはResolvedのまま変化しませんでした。ASFF(v1)には「Compliance.StatusがPASSED→FAILED等に変化するとWorkflow.Statusが自動的にNEWにリセットされる」という明文化された挙動がありましたが、v2ではこの自動リセットは発生しません。
一度Resolvedにトリアージしたfindingが実際にCriticalで再発しても、statusはResolvedのまま何も知らせてくれません。Resolved/Suppressedにしたfindingも、中身の変化を定期的に見直す運用が必須です。
実データから見えた発生傾向と、通知設計上のポイント
Updateが大半を占める
サンプル調査ではactivity_nameの分布はUpdateが81%を占めました。内容が一切変化していなくてもUpdateは発行されるため、severity+statusだけの通知条件では、この大量のUpdateイベントを再通知の候補として拾ってしまいます。
product.nameだけではCompliance FindingとIAM Analysis Findingを区別できない
CloudWatch Logs Insightsで検出内容を集計したところ、Compliance Finding(CSPMコントロール、33,916件)とIAM Analysis Finding(未使用アクセス分析、1,358件)が同じロググループに混在しており、**両方ともmetadata.product.nameは"Security Hub"**でした。
{
"source": ["aws.securityhub"],
"detail-type": ["Findings Imported V2"],
"detail": {
"findings": {
"severity": ["High", "Critical"],
"metadata": { "product": { "name": ["Security Hub"] } }
}
}
}
このようなルールは、CSPMのコントロール検出だけでなく、IAM Analysis Findingも意図せず対象に含めてしまいます。区別したい場合にはclass_nameを条件に加える必要があります。今回検証していなかったNetwork Scanningもmetadata.product.nameは"Security Hub"でイベントが発生するため、区別が必要な場合は同様です。
さらに、IAM Analysis Findingはseverityが全件Lowで固定されていることも確認しました。severityベースの通知フィルタ(High/Criticalのみ通知)を組んでいるチームでは、これらのfindingは最初から通知対象外になっている点にも注意が必要です。
通知ルール設計(EventBridge)案
以上を踏まえた通知ルールの設計方針です。
- フィルタ条件は**「重要度」+「
status」+「activity_name」+(場合によって)「class_name」**の組み合わせを基本にする。status単独では大量のUpdateを拾ってしまうため、activity_name: ["Create"]で初回検出のみに絞るのが基本形とする class_nameを条件に加えないと、product.nameだけでは異なる検出種別(CSPMコントロール、未使用アクセス分析、Network Scanning)が混在する(分けて管理したい場合は条件をつける)- 通知させたい重要度「
severity」を定義する(ユーザー操作によって変更できる重要度はvendor_attributes.severityとなるので、どちらで判別したいかで使うフィールドを判断する)
CSPMコントロール検出だけに絞りたい場合の例:
{
"source": ["aws.securityhub"],
"detail-type": ["Findings Imported V2"],
"detail": {
"findings": {
"activity_name": ["Create"],
"severity": ["High", "Critical"],
"class_name": ["Compliance Finding"]
}
}
}
日々のトリアージ運用例
-
新規検出時:
activity_name: Createを起点にSLAを計測し、重要度に応じて通知する -
対応中:
statusを手動でIn Progress等に変更する。この間は再通知しない -
是正した場合:
statusをResolvedに手動変更する。activity_name: Closeはfinding種別ごとにトリガーが異なるため、Closeを検知したらstatus更新の要否を確認する運用を組み込むことを検討してもよいが基本的にはfindingとして存在する根拠を失ったときであるため対応不要であるものとする -
Resolvedにした後の再発時:statusは人間が操作することで設定される独立したフィールドで、Security Hub側は「Resolvedにする際」是正されていることを自動保証していません。設定ミスで実は直っていなかった場合や、是正後の再評価時に新たな脆弱性が検知された場合など、Resolvedにした後にリスクが再発するケースがあります。また根本原因が再発してもstatusは自動でリセットされないため、一度Resolvedにしたfindingはそのまま放置される可能性があります。「Resolved=本来はseverityも下がっているはず」という期待値からのズレを検知する、という発想でEventBridgeルールによる通知や再確認するオペレーションを検討しても良いと考えます。detail.findings[].activity_name = "Update" detail.findings[].status = "RESOLVED" detail.findings[].severity in ["High", "Critical"] -
IAM Analysis Findingの棚卸しをする時:同一ロールに対して
finding_info.uidが入れ替わり続けるため、Security Hubの単体のイベントとして注目するよりもバージニア北部リージョンのIAM Access Analyzerでリソースの状況を確認しにいくのが良いでしょう。単体でのイベントよりもExposureの検出要因の一つとして存在しているぐらいの位置づけでもいいかもしれません
上記の流れをフロー図にすると以下の通りです。
まとめ
5種類のfinding(Exposure/Compliance/Vulnerability/IAM Analysis/GuardDuty)を実際に検証した結果、activity_nameとstatusについて以下が分かりました。
activity_nameはCreate(初回のみ)→Update(再評価のたび、内容不変でも発生)→Closeという共通パターンで遷移するが、Closeのトリガーはfinding種別によって異なる。Createを経由せずCloseから始まる例外も存在するstatusは運用担当が手動で操作する軸で、activity_nameとは独立している。Close時に自動変化せず、手動変更もfindingに影響を与えず、根本原因が再発しても自動リセットされない(ASFFとの決定的な違い)
これらを踏まえ、通知ルールは「重要度+status+activity_name+(場合によって)class_name」の組み合わせで設計し、トリアージ運用ではCloseのトリガーがfinding種別ごとに異なることと、statusが自動リセットされないことを前提にした定期棚卸しを組み合わせることで、状態と運用実態の乖離を防げます。
Security Hubを運用に組み込む際の参考にしていただけると幸いです。
参考リンク
- 新Security Hubのイベント通知を試してみた - EventBridgeフィルタパターンの書き方を製品別に詳しく解説
- https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-ocsf.html
- https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-v2-concepts.html
- https://docs.aws.amazon.com/securityhub/latest/userguide/exposure-findings.html
- https://docs.aws.amazon.com/securityhub/latest/userguide/exposure-findings-supported-traits.html
- https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-findings-manage.html
- https://docs.aws.amazon.com/securityhub/latest/userguide/asff-top-level-attributes.html
- https://docs.aws.amazon.com/securityhub/latest/userguide/controls-findings-create-update.html
- https://docs.aws.amazon.com/securityhub/latest/userguide/unused-access-findings.html
- https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-concepts.html
- https://aws.amazon.com/iam/access-analyzer/features/
- https://docs.aws.amazon.com/securityhub/1.0/APIReference/API_BatchUpdateFindingsV2.html
- https://schema.ocsf.io/1.6.0/classes/detection_finding
- https://dev.classmethod.jp/articles/inspector-v2-scan-requirements/








