はじめに
みなさんこんにちは、そしてこんばんは!サービスプラットフォーム事業部の大嵩です。
今回は、最近 GA された AWS Security Agent と AWS DevOps Agent を使ってみます! Apache のデフォルト config に潜むディレクトリリスティングを検知・修正し、その後に大量発生した HTTP403 の原因を AWS DevOps Agent で調査していきます。
気になるAgentの性能を見てみましょう!!
AWS Security Agent と AWS DevOps Agentについて
では、最初にそれぞれのAgentについて紹介します。
AWS Security Agent
AWSセキュリティエージェントは、すべての環境における開発ライフサイクル全体でアプリケーションを積極的に保護するフロンティアエージェントです。これは、お客様の要件に合わせてカスタマイズされた自動セキュリティレビューを実施し、セキュリティチームが中央で定義した基準がレビュー時に自動的に検証されます。このエージェントは、あなたのアプリケーションに合わせたオンデマンドのペネトレーションテストを実施し、確認済みのセキュリティリスクを発見して報告します。このアプローチは、開発の速度に合わせてアプリケーション全体にセキュリティの専門知識を拡張し、包括的なセキュリティカバレッジを提供します。設計から展開までセキュリティを統合することで、脆弱性を早期かつ大規模に防ぐのに役立ちます。
https://aws.amazon.com/jp/security-agent/
とのことですが、AIエージェントが設定した要件に沿ってペネトレーションテストやレビューを行い、危険を教えてくれるというものですね!
AWSリソースに対して行ってくれるので、かなり便利なものです。
なお、ペネトレーションテストは高度な検証を行うため、相応の費用(エンタープライズ向けの価格帯)に設定されています。事前のコスト試算やバジェット設定を推奨します。
https://aws.amazon.com/jp/security-agent/pricing/
AWS DevOps Agent
AWS DevOps エージェントは、インシデントの解決とプロアクティブな防止、アプリケーションの信頼性とパフォーマンスの最適化、AWS、マルチクラウド、オンプレミス環境にわたるオンデマンド SRE タスクの処理など、いつでも利用可能な運用チームメンバーです。DevOps エージェントは、経験豊富な DevOps エンジニアが行うように、アプリケーションとその関係を学習し、オブザーバビリティツール、ランブック、コードリポジトリ、CI/CD パイプラインを操作し、すべての環境にわたるテレメトリ、コード、デプロイメントデータを相互に関連付けることで、インシデントを調査し、運用の改善点を特定します。質問をしたり、状況に応じた回答を即座に得たり、保存してチームと共有できるカスタムチャートやレポートを作成したりできます。
https://aws.amazon.com/jp/devops-agent/
こちらも簡単に言えば、私のようなインフラ運用を行うエンジニアの仕事を、AIエージェントが自律的に行ってくれるようなものになります!
料金は大量に動かさなければコスト的には跳ねないように感じます。
https://aws.amazon.com/jp/devops-agent/pricing/
この後に動きをご覧いただきますが、業務に導入すれば、かなり楽になるなと感じました!
本記事のゴール
脆弱性をAWS Security Agentで発見後に修正し、AWS DevOps Agentでブロックしたアクセスの原因を調査します!
シチュエーション
わかりやすく、Options IndexesをONにした状態としてディレクトリリスティングを可能としておきます。
Amazon EC2上に構築したApache上で、index.htmlのみならず、/image の階層も閲覧できる状態です。
confを修正後にHTTP403を大量発生させます。
構成

EC2をセットアップする
今回は、検証用途なのでパブリックサブネットにEC2を置きまして、直接アクセスするようにします!
同時に、Amazon CloudWatch Agentを使用し、CloudWatch Logsにアクセスログの転送も行います。
以下のような形のindex.html と、/image にはダミーファイルを設置してます。
また、httpd.conf 周りをAmazon S3バケットに転送し、さらにzip化しておきます
(なぜzipかは後ほどわかります)



補足:EC2 に必要な IAM 権限
今回の構成では、EC2 のインスタンスロールに以下の権限が必要です。不足していると AccessDenied で詰まります。
- 対象 Amazon S3 バケットへの
s3:PutObject/s3:GetObject/s3:ListBucket(conf の zip をアップロードするため) CloudWatchAgentServerPolicy(アクセスログを Amazon CloudWatch Logs へ送るため)
AWS Security Agent を構築する
エージェントスペースを作成
まずは、エージェントスペースなるものを作成します。
イメージはVPC作るのと同じ感じと理解しました!
土台作りですね!
名前と、タグを設定する感じです

カスタム要件を作成する
今回、ディレクトリリスティングを検知するにあたってカスタム要件が必要なので作成します!
AIがわかりやすい文章はAIに作らせるということで、Claudeさんにお願いしました!

## Security requirement name(最大80文字) Webサーバのディレクトリリスティング無効化 ## Description(最大500文字) WebサーバでディレクトリリスティングOptions +Indexes / autoindexが有効だと、index未配置のディレクトリでファイル一覧が露出し、バックアップ・設定・ソース等の情報漏えいにつながる。CWE-548 / OWASP A05。本要件はリスティングが無効であることを担保する。 ## Applicability(最大10,000文字) This control applies to ALL workloads that serve content over HTTP/HTTPS using Apache HTTP Server, Nginx, or similar web servers, including reverse proxies and static content hosts. Mark as NOT_APPLICABLE if: 対象がWebサーバ機能を持たない(バッチ/内部APIのみでディレクトリ列挙の概念がない)場合、またはオブジェクトストレージ等でWebサーバ設定が存在しない場合。 ## Compliance criteria(最大10,000文字) A design is compliant if it demonstrates: Apacheで全ディレクトリに対しOptionsからIndexesが除去されているOptions -Indexes、もしくはデフォルトでIndexesを含まない設定である。Nginxではautoindex offである。公開ディレクトリにはindex文書が配置されている、または列挙が明示的に無効化されている。 A design is clearly non-compliant if it: Options +Indexes / Options Indexes が有効、IndexOptions が設定され列挙が前提になっている、mod_autoindex が有効でindex未配置ディレクトリが公開される、Nginxで autoindex on、のいずれかに該当する。 ## Remediation guidance(任意・最大10,000文字) 1. Apache: 該当する Directory / vhost / .htaccess の Options から Indexes を除去し、Options -Indexes を明示。 2. 必要なら mod_autoindex を無効化(a2dismod autoindex 等)。 3. apachectl configtest で構文確認後、systemctl reload httpd(または apache2)でリロード。 4. Nginx: location ブロックで autoindex off。 5. 修正後、対象ディレクトリへのGETが 403/404 を返すことを確認。
Manage security requirements – AWS Security Agent
作成されたら、カスタム要件として表示されます!

注意!
ここで一つ注意がありまして、先にマネージド要件は全て無効化しておいてください!
こちらを無効にしないと、すべての要件が適用されてしまい、不要なチェックが実行されます。。
(私はテスト当時1つ無効化し忘れてしまいました)

コードレビューを構成する
AWS Security Agent には、ペネトレーションテスト、設計レビュー、コードレビューがあるのですが、
今回はconfのレビューということでコードレビューを行います!
S3バケットには今回confを格納しているものを一旦選択しておきます。これは、他のレビューでも共有されるもののようです。
コードレビュー設定も、要件と脆弱性検出結果どちらも出してもらいましょう。


AWS IAM Identity Centerユーザーの追加
コンソールからAWS Security Agentのウェブアプリを起動できるので、そこからログインしレビューを開始するために
AWS IAM Identity Center のユーザーを追加し、登録します!

コードレビューを作成
まずは、ウェブアプリを起動し、ログインします!
ログインしたら下記画面になりますので、コードレビューを作成します

ここで、今回レビューのターゲットとしてS3を選択します。
ただし、この場合は zip ファイルを選択する必要があります。あらかじめ /etc/httpd を zip 化してアップロードしておき、そのオブジェクトを S3 URI で指定します。


ポイント
S3を選択した場合は、自動コード修正が使用できません!
GitHub リポジトリなら AWS Security Agent が自律的にコードを修正してくれます。可能であれば GitHub リポジトリを選ぶと、その恩恵を受けられます!
実際にコードレビューを開始する
それでは、レビューを開始していきましょう!
右上の「コードレビューを開始する」を押すだけで始められます!

始まると、プリフライトというフェーズになり、レビュー用の環境構築が始まります。

コンテナ環境でS3をpullしてるのが伺えます

プリフライトが終わると、分析が始まります!
1つずつタスクが終わりますと、簡単にログが出てきます。
テストしたときにマネージド要件を1つ無効化し忘れてしまいまして、たくさん出てきていますw
その中でも下記がApacheのIndex部分を指すものですね!

すべて終わると、グラフとともに画面が更新されます!
もちろんすべてデフォルト設定であったのでたくさん出てますね。。。
これを先に実行しておけば、危険性をかなり減らせそうです!

もちろん、ディレクトリリスティングについても指摘されています。

指摘を受けて、Apacheのconfを修正する
Agentから指摘を受けましたので、いつものあの行を修正します。
[ec2-user@ip-10-0-0-11 conf]$ diff httpd.conf httpd.conf.bak.20260617045643 149c149 < Options FollowSymLinks --- > Options Indexes FollowSymLinks [ec2-user@ip-10-0-0-11 conf]$
これで、ブラウザからの階層移動はできなくなり、かつHTTP403が出る状態を作れました!

AWS DevOps Agentを構築する
それでは、Apacheの修正ができたところで、今度はAWS DevOps Agentの設定をしていきます。
エージェントスペースを作成
こちらも同様にエージェントスペースを作成します。
少し項目は多いですが、あまり変わりません。
エージェントの応答言語は日本語を選択します!
暗号化の部分で、今回はマネージドキーを選択しましたが、CMKも選択できるようです。

Slack連携を設定する
今回、調査してもらう過程をSlack通知したいと思います!
実はAWS DevOps Agentには、Slack連携機能があり、そちらを使用します。
機能プロバイダーからSlackを選択します。

その後、ワークスペース連携と必要な情報を入力していきます!


連携が終わると、下記のような感じになります。

ここまでは、Slackワークスペースとの連携でしたので、エージェントスペースに対して通知したいチャンネルを登録します!
IDはチャンネルを右クリックし、リンクをコピーで出てくるURLの末尾の英数字です。

これと同時に、チャンネルにAWS DevOps Agentインテグレーションを追加します!

エージェントスペース内のコミュニケーションに追加されたら完了です!

HTTP403を大量発生させる
AWS DevOps Agent の用意ができました。作ったスクリプトを Systems Manager Run Command 経由で実行し、HTTP403 を15回ほど発生させてみます!
以下のように、早速メトリクスが出てきましたね! アクセスログを CloudWatch Logs に送り、メトリクスフィルタでカウントしています。

ハマりポイント:メトリクスフィルタは「末尾基準」で書く
403 の発生回数は、アクセスログを Amazon CloudWatch Logs に送り、メトリクスフィルタでカウントしています。ここで一つハマったのが、フィルタのパターンです。
Apache のアクセスログは ::1 - - [17/Jun/2026:05:14:02 +0000] "GET /image/ HTTP/1.1" 403 239 ... のような形式です。じつは CloudWatch は、この [17/Jun/2026:05:14:02 +0000] を 1 つのフィールドとして扱います(中のスペースで分割されません)。
そのため、日時と時刻を別フィールドとして数える「先頭基準」のパターンだと一致せず、メトリクスがずっと 0 のままになります。
正解は、末尾を基準にした次のパターンです。
[..., status=403, bytes, referer, agent]
ステータスコードを末尾側から数えることで、先頭のフィールド数のブレに左右されず、確実に 403 を拾えます。
最初に、自然言語で調査してみる
AWS DevOps Agentもウェブアプリがありまして、マネジメントコンソールからログインし、自然言語で調査をお願いしてみます。
調査プロセスの開始から、あえて雑にアラームの名前を入れてみます。


ある程度確認できたら、どのように分析するかも聞いてくれます。
今回は、リクエストの特徴も確認してもらいます!

調査タイムラインも出力されますので、そこでAgentがどのような流れで調査を進めてくれたのかがわかります!

このように、調査の中でタスクを出して、自律的に並列実行もしてくれます!
私のような人間一人だと難しい仕事を難なくこなしてくれますね。。。

最後にはまとめと、根本原因まで出してくれます!
根本原因は Markdown でダウンロードもできます。チーム内での共有や、次のインシデントへの対策にも使えそうです。運用をよく意識された、魅力的な Agent ですね!



CloudWatch アラームから自律的に動作させてみる
先ほどはアラームを発生させ、その後に自然言語で Agent を動かしましたが、ここからは本題の自律的に調査してもらいましょう!
Agent Space Webhook、Amazon EventBridge とAWS Lambdaを用意します!
Agent Space Webhook の設定
今回アラームからトリガーさせてAgentに情報を渡すうえで、残念ながらLambdaを使わなければなりません。
というのも、まだアラームのアクションとしては登録できないので、WebhookでAgentにPOSTしないといけません。
また、POSTするうえで、HMAC (Hash-based Message Authentication Code)で署名する必要があるため、Lambdaが必要になります。
(SFnからWebhookやEventBridge Connection を検討しましたが、HMACだとLambdaになります。。)
ということで、Webhookを設定していきましょう。
エージェントスペースの機能タブ最下部にあります、追加ボタンから追加します。
もう追加してしまっていますが、最初にWebhook URLとSecret Keyが発行されますので、CSVでダウンロードするのをおすすめします!
その後、下記スキーマ要件が出てきますので、データソース側で出力を満たしておくようにします。
{
eventType: 'incident';
incidentId: string;
action: 'created' | 'updated' | 'closed' | 'resolved';
priority: "CRITICAL" | "HIGH" | "MEDIUM" | "LOW" | "MINIMAL";
title: string;
description?: string;
timestamp?: string;
service?: string;
// The original event generated by service is attached here.
data?: object;
}
TypeScriptを使った実装例も出てきますので、参考にしてコーディングできます!
親切すぎてありがたいです。。。

Webhookが用意できたら、URLとSecret KeyをAWS Secrets Managerに格納しておきましょう!

Lambdaを用意する
Webhook設定ができたところで、次はLambdaを用意します。
実装例とは反して、PythonでClaudeさんといっしょにコーディングしました!
EventBridge 経由で動かしますので、handlerを見ていただくとわかるように、受け取れるものは引数から代入して
渡ってきていないものは、ロジックとハードコードして補完します。
(timestampやtitle、priorityなど)
Lambdaコード
"""
CloudWatch アラーム(EventBridge経由)を起点に、
DevOps Agent の Generic Webhook(HMAC認証)へ investigation トリガーを送る Lambda。
- Secrets Manager に {"webhook_url": "...", "hmac_secret": "..."} を保存しておき参照する。
- HMAC 署名は "<timestamp>:<payload>" を hmac_secret で SHA-256 → base64。
ヘッダ x-amzn-event-signature / x-amzn-event-timestamp を付与(DevOps Agent Generic Webhook v1)。
"""
import os
import json
import hmac
import hashlib
import base64
import urllib.request
from datetime import datetime, timezone
import boto3
SECRET_ID = os.environ["SECRET_ID"]
_sm = boto3.client("secretsmanager")
_cache = {}
def _load_secret():
if not _cache:
v = json.loads(_sm.get_secret_value(SecretId=SECRET_ID)["SecretString"])
_cache.update(v)
return _cache
def handler(event, context):
sec = _load_secret()
url = sec["webhook_url"]
hmac_secret = sec["hmac_secret"]
# EventBridge "CloudWatch Alarm State Change" イベントから情報抽出
detail = event.get("detail", {}) or {}
alarm_name = detail.get("alarmName", "unknown-alarm")
state = (detail.get("state") or {})
reason = state.get("reason", "")
region = event.get("region", "")
account = event.get("account", "")
payload_obj = {
"eventType": "incident",
"incidentId": f"{alarm_name}-{state.get('timestamp', '')}",
"action": "created",
"priority": "HIGH",
"title": f"CloudWatch ALARM: {alarm_name}",
"description": reason or f"{alarm_name} transitioned to ALARM",
"timestamp": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.000Z"),
"service": "otake-test-apache",
"data": {"metadata": {"region": region, "account": account}, "alarm": detail},
}
payload = json.dumps(payload_obj)
ts = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.000Z")
signature = base64.b64encode(
hmac.new(hmac_secret.encode(), f"{ts}:{payload}".encode(), hashlib.sha256).digest()
).decode()
req = urllib.request.Request(
url,
data=payload.encode(),
method="POST",
headers={
"Content-Type": "application/json",
"x-amzn-event-timestamp": ts,
"x-amzn-event-signature": signature,
},
)
with urllib.request.urlopen(req, timeout=20) as resp:
body = resp.read().decode()
print(f"webhook status={resp.status} body={body}")
return {"status": resp.status, "body": body}
EventBridge を用意する
Lambdaまでできたら、EventBridgeルールを用意します。
イベントパターンは下記です。
{
"source": ["aws.cloudwatch"],
"detail-type": ["CloudWatch Alarm State Change"],
"detail": {
"alarmName": ["otake-test-apache-403-spike"],
"state": {
"value": ["ALARM"]
}
}
}

そして、ターゲットは作成したLambdaを指定します!

もう一度HTTP403を発生させて、自律的に調査してもらう
それでは、スクリプトをつかってもう一度発生させてみます!
Logsに403のアクセスログが出力されていますね!

少し待っていると、Slackに通知が来ました!
ウェブアプリ画面で見れていた調査状況が、1メッセージずつ送信されています!
運用として、アラートをSlackに通知したりもするのでこれはかなり便利ですね!

最後に調査完了と、Root causesで根本原因も送信してくれています!
先ほどブラウザ上で見たものと同じですね!

また、テストのため HTTP403 を連続で発生させて遊んでみました。すると、短い間隔で発生させた場合は、同じ原因なら前回の調査とリンクして処理してくれたんです!
アラートが頻発した際にSlack通知が爆発するとオオカミ少年的な状況になりがちですが、リンクしてくれるとそんな状況を避けられますね!

ちなみに、それぞれのメッセージにあるView investigationのリンクを踏むと、先程のウェブアプリに飛べます。
後片付け
AWS Security Agent や AWS DevOps Agent は、稼働させたままだと料金がかさみます。検証が終わったら、作成したリソースを忘れず削除しておきましょう。
- AWS Security Agent / AWS DevOps Agent のエージェントスペース
- 検証用の Amazon EC2、Amazon S3 バケット
- Amazon CloudWatch のロググループ・メトリクス・アラーム
- Amazon EventBridge ルール、AWS Lambda、AWS Secrets Manager のシークレット、付与した IAM ロール/ポリシー
特にペネトレーションテストは高額なので、使わないなら早めに止めるのがおすすめです!
運用に落とし込むには
ここまで、AWS Security Agent と AWS DevOps Agent をご紹介しました。どちらも運用負荷を最大限抑えられる素晴らしいソリューションだと思います!
ただ、弊社のようなインテグレーターや日本企業の本番運用に載せると考えると、まだまだ向き合うべき課題もあると感じました。正直なところを書いていきます。
① コストと予実管理
冒頭でも触れましたが、ペネトレーションテストの料金はかなり高めです。AWS DevOps Agent も基本は従量課金で、1インシデントあたりにいくらかかるかが事前に読みにくいのが正直なところ。
本番運用に載せるなら、調査回数の上限・コストのガードレール・月次の予実見込みをどう設計するかがセットで必要になります。SI として顧客に提供する場合は、「実費パススルー」なのか「定額で包む」のか、課金モデルの設計が腕の見せどころになりそうです。
② 検知・調査の品質とチューニング
今回、私がマネージド要件を絞り忘れたせいで指摘が16件も出ましたw
これは裏を返すと、何もチューニングしないとノイズが多くなるということでもあります。
誤検知が続くとエージェントへの信頼は一気に下がります。
得意なのは設定ミス系で、アプリのロジック脆弱性や複雑なインシデントには限界もあります。要件のスコープ設計、Skill によるチューニング、そして「ここから先は人にエスカレーション」という線引き。
この設計こそが、運用に載せる上でいちばん効く部分だと感じました。
③ データ主権と既存運用との連携
推論がどのリージョンで処理されるか(Cross Region Inference)は、金融・公共などデータの越境を嫌う顧客には事前整理が必須です。機密情報や個人情報をエージェントに渡してよいのか、という観点も避けて通れません。
連携面でも課題があります。AWS DevOps Agent の標準コネクタは New Relic や Datadog などが中心です。今回のように CloudWatch アラームを直接トリガーにはできず、Lambda + HMAC のブリッジを自作する必要がありました。日本でよく使う Backlog などと繋ぐにも、ひと手間かかります。
このあたりはアラームアクション対応など、今後のアップデートに期待したいところです!
④ 責任分界「直す」までAIに任せられるか?
ここがいちばん考えさせられた点です。
本番環境でAIが自律的に設定やコードを「修正」してしまうとなると、その変更の責任は誰が持つのか、という問題が必ず出てきます。修正が誤っていたら? SLA は? 稟議は?日本企業ほど、ここは慎重にならざるを得ません。
そう考えると、現実的な落としどころは 「調査・検知・原因特定までは AI に任せ、修正の実行判断は人間が持つ」なのではないかと思います。
面白いのは、今回触った両エージェントが、まさにこの思想に沿っていたことです。AWS Security Agent も、S3 ソースでは自動修正せず指摘までに留まりました。AWS DevOps Agent も、あくまで調査と根本原因・是正案の提示で、実行のトリガーは人が引く形です。「制約」だと捉えていた部分は、実は「AIが直すのではなく、人が直すための材料を最速で揃える」という、責任を保てる設計だったわけです。
インテグレーターの価値はどこへ
ここまで課題を並べましたが、悲観しているわけではありません。むしろ逆です。
「AIが運用を全部やってくれる」のではなく、コストのガードレールを引き、要件をチューニングし、データの扱いを整理し、「どこまでをAIに任せ、どこから人が判断するか」の分界を設計する。
この一連の伴走こそが、これからのインテグレーターの価値になると感じました。
エージェントが優秀になるほど、人の仕事は「手を動かす運用」から「AIを安全に運用に組み込む設計とガバナンス」へと移っていく。今回の検証は、その未来を一足先に体験できた、とても刺激的なものでした!
まとめ
今回は AWS Security Agent と AWS DevOps Agent を組み合わせて、脆弱性の検知・修正から、修正後に出た大量の HTTP403 の調査までを通しでやってみました。
流れはこんな感じです。
- AWS Security Agent のコードレビューで、Apache のディレクトリリスティングを検知
- 指摘を受けて conf を手動で修正し、/image を 403 が返る状態に
- 急増した 403 を Amazon CloudWatch アラームで拾い、Amazon EventBridge と AWS Lambda 経由で AWS DevOps Agent を自律起動
- AWS DevOps Agent が原因を調査し、結果を Slack に通知
触ってみて分かったクセも残しておきます。
- コードレビューで S3 を使うときは、zip にしないと受け付けてもらえません
- S3 だと自動修正は効かないので、コードまで直してほしいなら GitHub を選ぶ必要があります
- マネージド要件を絞らずに走らせると指摘が大量に出るので、先に絞っておくと楽です
- メトリクスフィルタは Apache のログの日時でつまずきやすく、末尾から数えるパターンにして動きました
- アラームから AWS DevOps Agent を自律で動かすには、Lambda で署名して Webhook を叩く必要がありました
一番感じたのは、調査や検知はどんどん AI に任せられる一方で、実際に直すかどうかの最終判断は人が持っておくのが今のところ現実的だな、ということでした。
ここまで読んでいただき、ありがとうございました!
どなたかの参考になりますと幸いです!