
CCoEとしてマルチアカウント環境 GuardDuty 検知運用を AWS DevOps Agent で効率化しようとした話
とあるCCoEチームで、 AWS DevOps Agent の活用推進 を進めています。 まずは CCoE が関わる既存の枠組みに組み込む実績を作りたいと思い、 最初のテーマに GuardDuty を選びました。
GuardDuty の検知後は、担当者が検知メッセージの原文を読み取り、 必要に応じてコンソールを開いて Finding の内容を確認し、 誤検知かどうかを判断するという初期調査が毎回発生します。 手順や判断の分岐には定型的な部分もありつつ、初動担当者の暗黙知に頼る部分も多く、 DevOps Agent に任せる余地が大きいと判断しました。
本記事では、 GuardDuty の検知を起点に DevOps Agent が自動で調査を実行し、 結果を Slack に通知する仕組み の構築について書きます。 既存の運用フローへの組み込み方と、使ってみての所感もあわせて紹介します。
目次は以下のとおりです。
- 前提: DevOps Agent とは
- DevOps Agent をセットアップする
- 自動起動の仕組み (Lambda + EventBridge)
- 調査をチューニングする (AGENTS.md / Agent Skill)
- 運用フローに組み込む
- おわりに
前提: DevOps Agent とは
AWS DevOps Agent は、AWSが提供するマネージドなAIオペレーションエージェントです。 CloudWatch アラームやオブザーバビリティツールからのアラートを起点に、 自律的にインシデントの初期調査と根本原因分析を実行します。 マルチアカウント環境にも対応しており、複数アカウントを横断した分析が可能です。
エージェントの動作は読み取り専用に制限されています。 DevOps Agent が提供するのは調査結果や緩和策の候補であり、最終的な判断と対応は人が行う設計です。
CCoEとしての DevOps Agent 活用方針
DevOps Agent をどう位置づけるかの方針について、以下のように定めました。
- 判断と対応は人が行い、DevOps Agentは参考情報を提供する役割に徹します。
- DevOps Agentが出力するのは調査結果や緩和策の候補であり、最終的な判断と実際の対応はCCoE / オペレーターが担います。
- Agentと人の責任範囲を明確に分けることで、安全に活用していく前提を整えます。
- DevOps Agentを組み込んだ運用プロセスを定義し、チームで回せる仕組みを作ります。
- アラート検知から初期調査、対応判断、事後記録までの流れの中で、DevOps Agentがどこでどのように使われるのかを明確にします。
- 属人化を避けるため、プロセス化・言語化・ドキュメント化を進め、チーム全体で同じ使い方ができる状態を目指します。
- CCoE運用に最適化された振る舞いになるよう、継続的にチューニングします。
- DevOps AgentはAgent Skills、MCP、外部データソース連携など、エージェントを育てるための仕組みを備えています。
- これらを活用し、CCoEチームの運用コンテキスト(マルチアカウント構成、監視対象、利用中の監視ツール等)に合った調査ができるよう、継続的に調整していきます。
- アラート対応だけでなく、アラートを減らすための取り組みにも活用します。
- DevOps Agentは過去のインシデントパターンを踏まえた予防的な改善提案を生成できます。
- この機能を活用し、インシデント対応に加えて、アラートそのものを減らすための運用改善インプットとしても取り込んでいきます。
- 運用の暗黙知を形式知にする手段としても活用します。
- エージェントに調査させるには、調査手順や判断基準を AGENTS.md や Agent Skill として書き出す必要があります。
- 担当者の頭の中にあったナレッジを言語化するプロセスそのものを、活用の目的のひとつに位置づけます。
DevOps Agent をセットアップする
DevOps Agent エージェントスペースは、GuardDuty および Security Hub CSPM を 集中管理しているアカウントに構築しました。 Slack 連携を設定し、調査結果が専用チャンネルにスレッド形式で投稿されるようにしています。
セットアップ自体はマネジメントコンソールから数ステップで完了するため、 本記事では手順の詳細を省略します。
ここまでの簡易な構成図は以下のとおりです。

セキュリティ集約アカウントにエージェントスペースを構築し、調査結果を Slack へ通知する
自動起動の仕組み (Lambda + EventBridge)
GuardDuty の検知から DevOps Agent の調査開始までを自動化するパイプラインを構築しました。

GuardDuty 検知から DevOps Agent の調査開始までの構成
全体の流れは以下のとおりです。
- 各メンバーアカウントの GuardDuty 検知が Security Hub に集約される
- Security Hub が EventBridge にイベントを発行する
- EventBridge ルールが新規の GuardDuty Finding をフィルタし、Lambda を起動する
- Lambda が DevOps Agent の SDK を使って調査タスクを作成する
- DevOps Agent が調査を実行し、結果を Slack に通知する
EventBridge ルール
Security Hub から流れてくるイベントのうち、 GuardDuty 由来の新規 Finding だけを拾うイベントパターンを設定しました。
{
"detail": {
"findings": {
"ProductName": ["GuardDuty"],
"RecordState": ["ACTIVE"],
"Severity": {
"Label": ["LOW", "MEDIUM", "HIGH", "CRITICAL"]
},
"Workflow": {
"Status": ["NEW"]
}
}
},
"detail-type": ["Security Hub Findings - Imported"],
"source": ["aws.securityhub"]
}
※ この環境では、通知した Finding を自動で NOTIFIED (通知済み)にする仕組みを別途展開しています。 既存 Finding 更新による重複起動を防ぐためです。
Lambda 関数
Lambda 関数では boto3 の devops-agent クライアントを使い、 create_backlog_task API で調査タスクを作成します。
import json
import os
import boto3
AGENT_SPACE_ID = os.environ["AGENT_SPACE_ID"]
REGION = os.environ.get("DEVOPS_AGENT_REGION", "ap-northeast-1")
SEVERITY_MAP = {
"CRITICAL": "CRITICAL",
"HIGH": "HIGH",
"MEDIUM": "MEDIUM",
"LOW": "LOW",
"INFORMATIONAL": "MINIMAL",
}
client = boto3.client("devops-agent", region_name=REGION)
def lambda_handler(event, context):
finding = event["detail"]["findings"][0]
account_id = finding.get("AwsAccountId", "")
account_name = finding.get("AwsAccountName", "Unknown")
severity = finding.get("Severity", {}).get("Label", "")
title = finding.get("Title", "Security Finding")
priority = SEVERITY_MAP.get(severity, "MEDIUM")
task = client.create_backlog_task(
agentSpaceId=AGENT_SPACE_ID,
taskType="INVESTIGATION",
priority=priority,
title=f"{account_name} ({account_id}) : {title}",
description=f'{finding.get("Description", "")}\n\nFinding ID: {finding.get("Id", "")}\nSource: {finding.get("SourceUrl", "")}',
)["task"]
task_id = task["taskId"]
execution_id = task["executionId"]
print(f"Created backlog task {task_id} (execution {execution_id})")
return {
"statusCode": 200,
"body": json.dumps({
"taskId": task_id,
"executionId": execution_id,
}),
}
いくつかポイントを補足します。
create_backlog_task に taskType="INVESTIGATION" を指定すると、 調査タスクとして DevOps Agent に投入されます。 API を呼ぶと DevOps Agent が調査を開始します。
title はそのまま Slack 通知のタイトルになります。 どのアカウントの検知かが一目で分かるよう、 アカウント名 (アカウントID) : Finding のタイトル としました。
description には Description や Finding ID を埋め込んでいます。 Finding の詳細は、後述の AGENTS.md と Agent Skill で 「GuardDuty の Finding ID を受け取ったらこう調べる」と指示し、 DevOps Agent 自身に取得させる形にしました。
Lambda の実行ロールには aidevops:CreateBacklogTask の権限を追加付与しています。
調査をチューニングする (AGENTS.md / Agent Skill)
調査の振る舞いは エージェント指示(AGENTS.md) や エージェントスキル(SKILL.md) でカスタマイズできます。 AGENTS.md にはエージェント全体の調査ルールを書きます。 SKILL.md は特定のドメインに特化した調査手順を定義する機能です。
今回は GuardDuty の調査に特化した Agent Skill を作成し、 AGENTS.md からそのスキルを参照する構成にしました。
AGENTS.md
AGENTS.md には調査ルールを1行だけ書いています。 素の状態では 後述の guardduty-finding-triage スキルが発動しないことがあったためです。
# 調査ルール
- GuardDuty に関する調査は guardduty-finding-triage スキルを使う
SKILL.md(guardduty-finding-triage)
スキルの中身は以下のとおりです。
---
name: guardduty-finding-triage
description: GuardDuty 検知(Finding)を調査し、一次対応の判断材料を提供する
---
# 目的
このスキルは、トリアージ担当と関係する利用部門メンバーが、
GuardDuty 検知のハンドリング判断と一次対応の判断を速やかに下せる状態を作ることを目的とする。
読み手は一定の知識はあるが AWS や IT に深くは詳しくない前提で、
専門用語には補足をつけて出力する。
あなた(DevOps Agent)の役割は判断材料の提供であり、最終判断と対応は人が行う。
# 前提・スコープ
- 調査対象は、受け取った Finding の内容と Security アカウント内で取得できる情報に限る
- メンバーアカウント内のリソースには直接アクセスできない/しない
- 調査できなかった項目は「補足情報」に簡潔に列挙する
# 調査手順
1. Finding 詳細の取得
Security Hub CSPM から Finding の全体情報を取得する。
通知で受け取った Id を使い、use_aws ツールを以下のインプットで実行する。
```json
{
"service_name": "securityhub",
"operation_name": "get_findings",
"aws_account_id": "{SecurityアカウントID}",
"aws_region": "ap-northeast-1",
"parameters": {
"Filters": {
"AwsAccountId": [
{ "Comparison": "EQUALS", "Value": "{対象アカウントID}" }
],
"ProductName": [
{ "Comparison": "EQUALS", "Value": "GuardDuty" }
],
"ProductFields": [
{
"Comparison": "EQUALS",
"Key": "aws/securityhub/FindingId",
"Value": "arn:aws:securityhub:ap-northeast-1::product/aws/guardduty/{Finding ARN}"
}
]
}
}
}
```
2. Finding Type の解釈
Finding Type の意味と一般的な攻撃シナリオを整理し、
今回のケースで実際に何が起きていると推定されるかを言語化する。
3. 判定とレポート作成
下記の出力フォーマットに沿ってレポートを作成する。
# 出力フォーマット
## サマリ(4行以内)
- 誤検知 / 想定内動作の可能性が高いか否かの見立て
- 何が検知されたか
- 影響を受けるリソース(アカウント / リージョン / リソース名)
- 一次対応の推奨アクション(判断区分から1つ)
## 検知内容の解説
- Finding Type の意味と一般的な攻撃シナリオ
- 今回のケースで実際に何が起きていると推定されるか
## 誤検知 / 想定内動作の可能性
- 既知の運用作業(バッチ、スキャンツール、踏み台経由のアクセス等)と一致しないか
## 一次対応の推奨アクション(判断区分を明示)
- [即時対応必要] : 封じ込め推奨。具体的なアクションを提示
- [要エスカレーション] : CCoE/セキュリティ担当への引き継ぎ事項を整理
- [経過観察] : 監視継続で良い理由と、再発時のトリガー条件
- [誤検知の可能性高] : 根拠と、抑制ルール化の要否
## 補足情報
- 未調査項目と、追加で確認すべき情報
# 制約
- 推測と事実を明確に区別する(「〜の可能性がある」「〜が確認できた」を使い分ける)
- 専門用語には補足説明をつける
# 既知の想定内動作パターン
以下のパターンに合致する検知は、想定内動作の可能性が高い。判断の参考にする。
## 管理者ロールによる Stealth:IAMUser/PasswordPolicyChange
CCoEチームが使用する管理者ロールによる操作。
初期アカウントセットアップ作業によるものであり、原則静観。
## Control Tower による Stealth:IAMUser/CloudTrailLoggingDisabled
Control Tower の正常な動作であり、静観。
意識した点は以下のとおりです。
- 調査手順の初期ステップは具体的に指示
- Security Hub の
get_findingsを、JSON パラメータまで書いて指定しました - 指示しないと毎回違う手段で情報を取りにいき、API 実行に失敗することがあったためです
- Security Hub の
- 出力フォーマットをある程度固定化
- 情報を受け取った側の認知負荷を下げるためです
- 冒頭にサマリを置いて、初動の判断を少しでも早められるようにしました
- ※ Slack 投稿は長文だと途中で省略されるため、その対策も兼ねています
- 「既知の想定内動作パターン」を記録
- 過去に誤検知と判断したパターンをスキル内に残しています
- 新しい誤検知が出るたびに追記していけば、判断精度が上がっていきます
- ※ 条件が明確なものは GuardDuty の抑制ルール で機械的に除外するのが本筋です
- ※ 機械的に切れない定性的な判断をこちらに書く、という棲み分けにしています
出力例
実際には、次のような形で Slack に投稿されます。

調査開始の通知と調査結果がスレッド形式で投稿される
Slack メッセージには DevOps Agent コンソールへのリンクも付いており、 タイムラインや詳細をそこから確認できます。

コンソールでは調査タイムラインと根本原因の判定を確認できる
運用フローに組み込む
既存の GuardDuty 対応フローに DevOps Agent を組み込みました。
以下キャプチャは管理しているドキュメントの更新部分です。

既存の対応フロー手順書に DevOps Agent の自動調査を追記した
今回は既存フローの「調査」ステップに参考情報を足しただけで、フロー自体は大きく変えていません。 本格的な見直しは重くなりそうなので別タスクとして計画しています。
おわりに
DevOps Agent は GuardDuty の Finding に対して良い感じのサマリを出してくれました。 Finding Type の意味、推定される状況、推奨アクションが構造化されて届くため、 トリアージの初動調査を楽にしてくれていると思います。
ただ、初動調査をある程度経験している人からすると 「 調査してくれるのは助かるが、正直それは知っていた 」という内容も少なくありません。 初動調査の時間短縮だけを価値と見るなら、効果はそこまで大きくないという評価にもなり得ます。
大事なのは、 担当者の頭の中にあった判断基準を文書として残していく ことだと思っています。 Agent Skill を書くには「どういう手順で調べているか」「どのパターンは誤検知か」を 言語化しなければならず、その過程で暗黙知が形式知になります。 誰が当番でも同じ水準の初期調査が回る状態に近づけることが、本来の狙いです。
今後は全メンバーアカウントへのクロスアカウント調査の展開を進めます。 あわせて、利用部門への個別展開とその後のフォローも CCoE として続けていきます。
以上、参考になれば幸いです。










