Security HubのFindingステータス遷移を検出タイプごとで検証し、通知設計とトリアージ運用に落とし込んでみた

Security HubのFindingステータス遷移を検出タイプごとで検証し、通知設計とトリアージ運用に落とし込んでみた

Security Hubの新しいOCSFスキーマにおいて、findingの状態遷移を5種類の検出タイプで実地検証し、`status`と`activity_name`がどう変化するのかを明らかにしました。通知ルール設計とトリアージ運用への落とし込み方も整理します。
2026.07.29

はじめに

Security Hubを有効化すると、findingにはstatusactivity_nameという2つのフィールドが存在します。本記事では、この2つのフィールドがそれぞれどういう意味を持ち、いつ・どう変化するのかを実際に確認します。これらを理解して正しい通知ルールやトリアージ運用を設計することが可能になることを目指していきます。

本記事では、Security Hubが生成する5種類のfinding(Exposure Finding/IAM Analysis Finding/Compliance Finding/Vulnerability Finding/GuardDuty)それぞれに対して実際に検出を発生させ、修正・削除・手動操作を行いながらactivity_namestatusがどう変化するかを検証してみました。そのうえで、通知ルール(EventBridge)とトリアージ運用への落とし込み方を整理します。

なお、EventBridgeのフィルタパターンの書き方そのものは新Security Hubのイベント通知を試してみたで製品別に詳しく紹介されています。本記事は「状態遷移のどのタイミングで、どんなイベントが実際に発生するのか」を実地検証で明らかにしたうえで、その裏付けをもとにしたフィルタ設計とトリアージ運用に焦点を当てます。

検証方法について

statusactivity_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_idactivity_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 イベントのアクティビティがマッピングされていない。

statusactivity_idactivity_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(versiondetail-typesourceaccounttimeregion)の中にdetail.findingsという配列があり、その1件(1件のイベントにつき常に1件のfinding)の中にstatusactivity_idactivity_nameが並んで存在しています(Security Hub検出のJSONを表示などで確認できるものと同一)。この例ではactivity_name: "Close"(findingとしてのライフサイクルは終了)でありながら、status: "New"(人間側は未着手のまま)という組み合わせが実際に起きていることも読み取れます。

ここまでがドキュメントで確認できた内容でした。 一方で、status_idactivity_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(調査進捗)+RecordStateACTIVEARCHIVED、finding provider専用) statusstatus_idの1フィールド(両者の値セットを比較する限り、2フィールドの概念が1フィールドに集約されていると考えられる)
Create/Update/Closeの区別 フィールドとして存在しない activity_idactivity_nameとして明示的に存在

旧Security Hubには存在しなかったactivity_idactivity_nameという軸の新設が、本記事全体の起点になります。

検証した5つのfinding種別

Security Hubは検出元によって異なるclass_uid(OCSFのクラス)のfindingを生成します。今回は以下の5種類を検証しました。
class_nameclass_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 DetectionSecurity HubInspectorSecurity HubGuardDuty)を持ちますが、Compliance FindingとIAM Analysis Findingは両方とも"Security Hub"と表示されるため、この2つは製品名だけでは区別できません(後述)。

なお、Security Hubに検出を集約するAWSサービスは他にAmazon MacieNetwork 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回だけ」という点でどの種別も共通していますが、UpdateCloseはどちらもトリガーが種別ごとに異なります。

1. Exposure Finding:寄与するContributing Traitがすべて解消されるとClose

Create:IAMユーザーの単一ホップでのデータアクセス経路の存在・MFA無効(IAM.5)・弱いパスワードポリシー(IAM.7)という3つのContributing Trait、および管理者権限ポリシーを保持しているというContextual Trait1件、計4件のsignalを持つExposure findingとして初回の検出時にactivity_nameCreateでイベントが発生しました。実際の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が更新されたことが確認できます。severitylikelihoodはいずれも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ロール(アカウント222233334444dummy-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: 43total_potential_attacks_count: 62のまま変化していませんでしたが、...b4dcae37...のCreate時点ではそれぞれ4563に増加していました。

差分の内訳を見ると、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.statusFailのまま6日間・16回Updateが発行され続けており、間隔は約12時間おきとほぼ規則的でした。また、AWS Configが設定変更を検知した場合は、この定期チェックとは別に数分というイベント駆動の速さで即座にUpdateが発行されることも確認しました。EC2.19の設定修正ケース(compliance.statusFailPassに変化)では、以下のように変更から約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
セキュリティグループ自体を削除 FailUnknownCONFIG_RETURNS_NOT_APPLICABLE Close
セキュリティグループのルールを修正 FailPass Update(Closeしない)

Compliance Findingはコントロール+リソースの1対1の継続追跡です。合格しても「追跡対象がなくなる」わけではなくUpdateのまま存続し、リソース自体が削除されて評価不能になって初めてCloseします。これはASFF(v1)時代のコントロールfindingの挙動と同じ設計思想です。AWS公式ドキュメントにも、合格時は新規findingを生成せず既存findingを更新するだけであること、RecordStateARCHIVEDになるのはコントロール無効化・リソース削除・長期間未更新(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とも変化なし

ここから以下のような特徴が見られました。

  1. finding(...7afd2ca7)はCreate時点のHighからUpdate時点でMediumに変化していましたが、残り2件は不変でした。CVSSスコアの見直し等によって変化したと推測できます
  2. 複数の異なる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: 3activity_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_nameCreateを経由せず、いきなり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時点でもstatusNewのままでした。

確認済み2:手動でのstatus変更はactivity_name: Updateにはなるが、Closeには絶対にならない

BatchUpdateFindingsV2statusをいずれかの値に変更した場合、activity_nameUpdateになりイベントが発生します。またUpdateにはなりますが、Closeには絶対にならないstatus: Archivedを指定した場合も同様)。手動変更にはmetadata.loggerslog_name: "BATCH_UPDATE_FINDINGS")というマーカーが付き、自動的な再評価との判別に使えます。

確認済み3:手動設定したstatusは、根本原因が再発しても自動的にリセットされない(ASFFとの決定的な違い)

Compliance Financeが一度Passになった後、statusを手動でResolvedに変更し、その後意図的に設定を戻してcompliance.statusFailseverityCritical)へ再発させたところ、statusResolvedのまま変化しませんでした。ASFF(v1)には「Compliance.StatusPASSEDFAILED等に変化するとWorkflow.Statusが自動的にNEWにリセットされる」という明文化された挙動がありましたが、v2ではこの自動リセットは発生しません

一度Resolvedにトリアージしたfindingが実際にCriticalで再発しても、statusResolvedのまま何も知らせてくれません。ResolvedSuppressedにしたfindingも、中身の変化を定期的に見直す運用が必須です。

実データから見えた発生傾向と、通知設計上のポイント

Updateが大半を占める

サンプル調査ではactivity_nameの分布はUpdateが81%を占めました。内容が一切変化していなくてもUpdateは発行されるため、severitystatusだけの通知条件では、この大量の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等に変更する。この間は再通知しない

  • 是正した場合statusResolvedに手動変更する。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_namestatusについて以下が分かりました。

  • activity_nameはCreate(初回のみ)→Update(再評価のたび、内容不変でも発生)→Closeという共通パターンで遷移するが、Closeのトリガーはfinding種別によって異なるCreateを経由せずCloseから始まる例外も存在する
  • statusは運用担当が手動で操作する軸で、activity_nameとは独立している。Close時に自動変化せず、手動変更もfindingに影響を与えず、根本原因が再発しても自動リセットされない(ASFFとの決定的な違い)

これらを踏まえ、通知ルールは「重要度+statusactivity_name+(場合によって)class_name」の組み合わせで設計し、トリアージ運用ではCloseのトリガーがfinding種別ごとに異なることと、statusが自動リセットされないことを前提にした定期棚卸しを組み合わせることで、状態と運用実態の乖離を防げます。

Security Hubを運用に組み込む際の参考にしていただけると幸いです。

参考リンク

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事