AWS Security AgentでAIによる統合セキュリティレビューを体験しよう
この章では、AWS Security Agentを使った次世代型の統合セキュリティレビューをハンズオン形式で学習します。これにより、AIによる設計レビュー・コードレビュー・ペネトレーションテストが1つのサービスで統合実行できるようになります。
| 💡 ポイント |
|---|
| AWS Security Agentは 2025年12月にプレビュー発表、2026年3月にペネトレーションテスト機能がGA となった、リリース直後のサービスです。設計レビュー・コードレビューは現在もプレビュー相当で提供されており、画面UI・メニュー名・挙動が今後も変更される可能性があります。本セクションは変更を確認次第アップデートしていきますが、追いつかないタイミングもあるため、手順の画面と実際のコンソール表示が異なる場合は、AWS Security Agent User Guide を優先して参照してください。 |
1. AWS Security Agentとは
AWS Security Agent(AWSセキュリティエージェント)は、re:Invent 2025でプレビュー発表され、2026年3月31日にオンデマンドペネトレーションテスト機能が一般提供(GA)されたAIエージェント型のセキュリティサービスです。これまで別々のツールで扱っていた「設計レビュー」「コードレビュー(SAST)」「動的セキュリティテスト(DAST / ペネトレーションテスト)」を1つのサービスに統合し、AIエージェントが自動で実行してくれます。
従来のDevSecOpsでは、以下のように複数のツールを個別に導入・運用する必要がありました。
| 従来のアプローチ | 導入していたツール例 |
|---|---|
| 設計レビュー | 人間のアーキテクト・セキュリティチームによる手動レビュー |
| コードの静的解析(SAST) | Bandit / Semgrep / SonarQube など |
| 動的テスト(DAST) | OWASP ZAP / Burp Suite など |
| ペネトレーションテスト | 外部ベンダへの依頼(数十万〜数百万円) |
AWS Security Agentでは、これらすべてをAIエージェントが肩代わりしてくれます。特にペネトレーションテストは従来「年に1〜2回、外部ベンダに依頼して数百万円」が相場でしたが、Security Agentならオンデマンドで何度でも実行できるのが革命的なポイントです。
1.1 AWS Security Agentの3つの機能
AWS公式ドキュメントのAWS Security Agent capabilitiesでは、以下の3つの機能が提供されています。
1. 設計レビュー
設計ドキュメント(アーキテクチャ図・API仕様書・ER図など)をアップロードすると、AIエージェントがコードが書かれる前にセキュリティ上の問題を指摘してくれます。組織レベルで定義したセキュリティ要件(承認済みライブラリ・ログ基準・データアクセスポリシー)への準拠性も自動でチェックされます。
「シフトレフト」の究極系で、実装前の設計段階で問題を潰せるのが特徴です。
2. コードレビュー
GitHubリポジトリと連携し、プルリクエストが作られるとAIエージェントが自動でコードをレビューします。検出対象は以下の3パターンから選択できます(公式ドキュメント参照)。
| オプション | 検出対象 |
|---|---|
| Security requirement validation | 組織のカスタムセキュリティ要件への準拠性のみチェック(デフォルト) |
| Security vulnerability findings | 一般的な脆弱性(SQLi・入力バリデーション不足など)のみ検出 |
| Security requirements and vulnerability findings | 両方を分析 |
プルリクエストに直接コメントを書き込んでくれるため、開発者は普段のGitHubワークフローの中でレビュー結果を受け取れます。なお、コードレビューはPrivateリポジトリのみが対象です。
3. ペネトレーションテスト
稼働中のWebアプリケーションやAPIに対して、AIエージェントが多段階攻撃シナリオを自動生成・実行し、実際に悪用可能な脆弱性を発見・検証します。AWS News Blogによると、13種類のリスクカテゴリ(OWASP Top 10を含む)に対するテストを実行できます。
| 📝 OWASP Top 10とは |
|---|
| OWASP Top 10(オワスプ・トップテン)は、Webアプリケーションで起こりやすいセキュリティリスクを重要度の高い順に10件まとめた業界標準のリストです。OWASP(Open Worldwide Application Security Project)という非営利団体が、世界中の脆弱性データを集計して数年ごとに更新しており、最新版はOWASP Top 10:2021で公開されています。 2021年版で挙げられている10カテゴリは以下のとおりです。 ・アクセス制御の不備(Broken Access Control) ・暗号化の失敗(Cryptographic Failures) ・インジェクション(Injection、SQLインジェクション等を含む) ・安全でない設計(Insecure Design) ・セキュリティ設定ミス(Security Misconfiguration) ・脆弱で古いコンポーネント(Vulnerable and Outdated Components) ・識別と認証の失敗(Identification and Authentication Failures) ・ソフトウェアとデータの整合性の不具合(Software and Data Integrity Failures) ・セキュリティログとモニタリングの失敗(Security Logging and Monitoring Failures) ・サーバサイドリクエストフォージェリ(SSRF) 本セクションで意図的に仕込んだSQLインジェクションは「Injection」、認証バイパス・偽造可能なトークンは「Identification and Authentication Failures」、IDOR・認可チェックの欠落は「Broken Access Control」に該当し、いずれもOWASP Top 10の上位カテゴリにあたる脆弱性です。 |
静的解析では見つけられない「動的な脆弱性」や「複数の脆弱性を連鎖させた攻撃経路」を発見できるのが特徴です。さらに、発見した脆弱性を自動修正するプルリクエストまで作成してくれます。
2. 事前準備
2.1 前提となる講座
この章では、以下の知識を前提としています。自信がない場合は先に関連講座を実施してみましょう。
| 講座名 | 必要な知識 |
|---|---|
| Git入門 | リポジトリ作成、コミット、Pushなど、Gitの基本操作 |
2.2 必要なツール
この章では、以下のツールを使用します。まだインストールしていない場合は、リンク先の手順に沿って準備をお願いします。
| ツール名 | 関連箇所 | 理由 |
|---|---|---|
| Visual Studio Code | Visual Studio Codeのインストール | サンプルの設計書やコードを確認・編集するエディタとして使用する |
| Git | Git/GitHubのセットアップ | 脆弱性を含むサンプルコードをPrivateリポジトリにPushするために使用する |
2.3 必要なアカウント
この章では、以下のアカウントを使用します。まだ用意していない場合は、リンク先の手順に沿って準備をお願いします。
| アカウント名 | 関連箇所 | 理由 |
|---|---|---|
| AWSアカウント | AWSアカウントの作成 | AWS Security Agentを有効化してセキュリティレビューを実行する環境として使用する(Security Agentを有効化する権限が必要) |
| GitHubアカウント | Git/GitHubのセットアップ | サンプルコードのレビュー対象リポジトリのホスティング先として使用する(Privateリポジトリを使える状態であること) |
2.4 サンプルファイルのダウンロード
フェーズ1〜2で使う設計ドキュメントとソースコードを zip でまとめています。以下のボタンからダウンロードし、任意の作業ディレクトリに展開しておいてください。
zip を展開すると、以下のファイル構成になります。
tasks-api-source/
├── design-doc.md ← フェーズ1(設計レビュー)でアップロードする設計書
└── app/
├── __init__.py
└── main.py ← フェーズ2(コードレビュー)でPrivateリポジトリにpushするFastAPIコード
| 📝 含まれる脆弱性について |
|---|
| zip 内のファイルには、SQLインジェクション・認証バイパス・IDOR・平文パスワード保存・自前実装のトークンなど 意図的な脆弱性 が多数含まれます。学習目的で作成しているため、内容そのものは問題ありませんが、フェーズ2 で push する GitHub リポジトリは必ず Private にしてください。Public リポジトリに置くと第三者から攻撃手段の参考にされる、フォーク先で稼働させて攻撃される、などのリスクがあります。 |
| 📝 AWS Security Agentの提供状況 |
|---|
| AWS Security Agentは機能ごとに提供状況が異なります。ペネトレーションテストは2026年3月31日に一般提供(GA)開始しました(GA announcement)が、設計レビュー・コードレビューは引き続きプレビュー相当で提供されています(公式FAQで無料利用クォータが明記)。 利用可能リージョン(6リージョン、東京を含む) - US East(バージニア北部・ us-east-1)- US West(オレゴン・ us-west-2)- Europe(アイルランド・ eu-west-1)- Europe(フランクフルト・ eu-central-1)- Asia Pacific(シドニー・ ap-southeast-2)- Asia Pacific(東京・ ap-northeast-1)機能別の料金・クォータ - ペネトレーションテスト(GA): $50/task-hour(秒単位で計測)。新規顧客は2ヶ月間の無料トライアル(月200 task-hourまで)あり。詳細はAWS Security Agent pricing - 設計レビュー(プレビュー相当・無料): 月200レビュー/アカウントまで - コードレビュー(プレビュー相当・無料): 月1,000レビュー/アカウントまで |
3. セットアップ: AWS Security Agentの初期セットアップ
AWS Security Agent は、最初に 1回だけ必要なアカウントレベルのセットアップ を行い、同時に最初の エージェントスペース(アプリケーション単位のワークスペース)を作成します。AWS公式の Set up AWS Security Agentに準拠した手順で進めます。
3.1 リージョンの確認
AWS Security Agent は提供リージョンが限られているため、まず最初に作業リージョンを正しく選んでおかないと、後でサービス画面が表示されなかったり、別リージョンに重複セットアップしてしまうトラブルにつながります。AWS Security Agent は、東京・バージニア北部・オレゴン・アイルランド・フランクフルト・シドニーの6リージョンで利用可能です。本セクションでは、他のハンズオンと統一するため 東京リージョン(ap-northeast-1) で進めます。マネジメントコンソール右上のリージョンセレクタから アジアパシフィック(東京) ap-northeast-1 を選択してください。
3.2 Security Agentコンソールを開く
エージェントスペースの作成・管理は専用のコンソールから行うため、まずSecurity Agent画面を開きます。検索バーに Security Agent と入力し、AWS Security Agent のサービス画面を開きます。AWS Security Agent のランディングページが表示されたら、右側の 「AWS Security Agent をセットアップ」 をクリックします。

3.3 セットアップ画面の設定
セットアップ画面は1つのフォームに エージェントスペース設定 / ユーザアクセス設定 / サービスアクセス・Encryption・タグ(折りたたみ) が並んだ構成になっています。本セクションで設定するのは前半の2つで、後半のオプションはすべてデフォルトのままで構いません。
まず エージェントスペース設定 を入力します。エージェントスペースはアプリケーション・プロジェクト単位のワークスペースで、連携する GitHub リポジトリ・過去の設計レビュー・ペネトレーションテスト設定・検出結果がひとまとめに管理されます。
| 設定項目 | 値 | 設定の基準 |
|---|---|---|
| エージェントスペース名 | fastapi-sample-app |
対象アプリケーションを識別できる名前(Webアプリケーション側に表示される) |
| 説明 - オプション | FastAPIサンプルアプリケーションのセキュリティレビュー用 |
エージェントスペースの用途が後から分かる記述 |
次に ユーザアクセス設定 で、ウェブアプリケーションへのアクセス方法を選択します。
- 「IAM アイデンティティセンターによるシングルサインオン (SSO)」は IAM Identity Center 統合による SSO で、複数人のチーム運用に向いている
- 「IAM 専用アクセス」は AWS マネジメントコンソール経由でのアクセスのみで、簡易セットアップに向いている
本セクションでは 「IAM 専用アクセス」 を選択します。
| 📝 IAM 専用アクセス → IAM アイデンティティセンター の切り替え |
|---|
| 画面上の黄色い注意ボックスにも記載のとおり、初期セットアップ後に「IAM 専用アクセス」から「IAM アイデンティティセンター」へ切り替えるには、AWS Security Agent のセットアップを一度削除して再作成する必要 があります。本番で複数人運用を想定するなら最初から IAM アイデンティティセンターを選ぶのが安全です(公式ドキュメント)。 |
残りの サービスアクセス・Encryption・タグ は折りたたまれているセクションで、本セクションでは展開せずデフォルトのままで構いません。サービスアクセスは未設定のまま進めると、AWS Security Agent が必要な権限を持つ IAM ロールを自動作成してくれます。
設定が終わったら、画面右下の 「AWS Security Agent をセットアップ」 をクリックします。

3.4 セットアップの完了
クリックすると AWS Security Agent がエージェントスペースと Web Application、必要な IAM リソースを作成し、エージェントスペース一覧画面に遷移します。
画面上部に緑色の通知 「アプリケーションが正常に有効化されました。ようこそ!」 が表示され、一覧に fastapi-sample-app が並んでいれば、初期セットアップは完了です。

4. フェーズ1: 設計レビューを体験
事前準備でダウンロード・展開した zip 内の design-doc.md を Security Agent にアップロードし、AIが設計段階の問題を指摘してくれる流れを、Create a design reviewの手順に沿って体験します。
Security Agent では、AIが設計レビューを行う際に 「セキュリティ要件」 に対する準拠性を評価します。セットアップ直後の状態では、AWS が提供するベストプラクティス由来の AWS マネージドのセキュリティ要件が10個有効化されている ため、組織独自の要件を定義しなくても、それらに対するレビューがすぐに実行できます。
4.1 Web Applicationを起動
セットアップ完了直後はエージェントスペース一覧画面が表示されているので、ここから今回の対象である fastapi-sample-app をクリックして詳細画面を開きます。詳細画面には「ペネトレーションテスト」「設計レビュー」「コードレビュー」の3つのカードが並んでおり、フェーズ1で使うのは「設計レビュー」カードです。
「設計レビュー」カードの 「ウェブアプリケーションで開始」 をクリックします。

別タブで Security Agent 専用の Web Application が開きます。ホーム画面の「デザインレビュー」カードにある 「デザインレビューを作成」 をクリックします。

| 💡 ポイント |
|---|
| Web Application は、マネジメントコンソールとは別の UI で、実際の設計レビュー・ペネトレーションテスト実行を行う画面です。IAM-only access で初期セットアップした場合、Administrator ユーザとしてアクセスできます(画面右上に表示)。 |
4.2 デザインレビューの作成
Web Applicationが開いたら、レビュー対象の設計書をアップロードしてAIに渡します。今回の対象は事前準備でダウンロードした design-doc.md で、Tasks APIの設計に意図的な脆弱性(認証バイパス・平文パスワード保存など)を埋め込んであります。AIがこの設計書のどこを問題と判断するかを確認していきます。
「デザインレビューを作成」画面で以下を入力します。
| 設定項目 | 値 | 設定の基準 |
|---|---|---|
| デザインレビュー名 | Tasks API Design |
アプリケーション名+「Design」で、後から識別しやすい名前にする |
| 確認するファイル | 事前準備でダウンロードしたzip内の design-doc.md |
フェーズ1のレビュー対象。ドラッグアンドドロップまたは「ファイルを選択」で指定 |
design-doc.md がアップロード済みになっていることを確認し、画面右下の 「デザインレビューを開始する」 をクリックします。

| 💡 ポイント |
|---|
| 公式ドキュメントによると、デザインレビューでは以下のファイル形式・サイズ制限があります。 対応形式: DOC, DOCX, JPEG, MD, PDF, PNG, TXT ファイル数: 1レビューあたり最大5ファイル サイズ制限: 1ファイル2MB以下、合計6MB以下 Googleドキュメントの独自形式( .gdoc)はそのままアップロードできませんが、ダウンロード時に他形式へ変換することでデザインレビューの対象にできます。Googleドキュメント画面のファイル → ダウンロードから、用途に応じて以下を選んでください。Microsoft Word(.docx): テキスト主体の設計書(API仕様書・データモデル定義書など)に最適。見出し・表・箇条書きなどの書式もほぼ保持される PDFドキュメント(.pdf): アーキテクチャ図などレイアウトが重要な場合に最適 書式なしテキスト(.txt): 文章主体で書式が不要な場合 変換後、画像埋め込みが多いとサイズ超過する場合があります。2MBを超えるときは、図を別のPNGとして分けてアップロードするか、画像を圧縮してから再書き出ししてください。また、Googleドライブの共有URLを直接参照する機能はないため、必ずローカルにダウンロードしてからアップロードします。機密情報(APIキー・個人情報など)が含まれていないかもアップロード前に確認してください。 |
レビューが開始されると、画面上部に「デザインレビュー Tasks API Design が開始されました」の通知が表示され、デザインレビュー一覧でステータスが 「進行中」 になります。

4.3 レビュー結果の確認
レビューを開始した時点で、AIエージェントが設計書をAWSマネージドのセキュリティ要件と照らし合わせて分析を始めます。完了を待ち、設計書のどの部分がどの要件に違反していると判定されたかを見ていきます。
数分後にレビューが完了すると、ステータスが 「完了しました」 に変わり、コントロール件数(10個)が表示されます。一覧から Tasks API Design をクリックして詳細を開きます。

詳細画面では、検出結果の概要 として以下の4ステータスでカウントが表示されます。
| ステータス | 意味 |
|---|---|
| 非準拠 | 設計がセキュリティ要件に違反、または適切に対応していない |
| データ不足 | 設計書の情報が不十分で判定できない |
| 準拠 | 設計が要件を満たしている |
| 該当なし | この設計には適用されない要件 |
意図的に脆弱な設計書を渡しているため、10個すべて「非準拠」 として検出される結果になります。下部の「検出結果のレビュー」では、評価された AWS マネージドのセキュリティ要件と、それぞれの非準拠状況が一覧表示されます。

検出されたセキュリティ要件のうち、Tasks API の設計上の問題と直接対応するものは以下です。
| セキュリティ要件 | 検出された設計上の問題 |
|---|---|
| Authentication Best Practices | ログインに自前のbase64トークンを採用しているため、トークン偽造が容易 |
| Authorization Best Practices | /api/v1/users/{id} /api/v1/admin/users に認証/認可がない(誰でも全ユーザ情報を取得可能) |
| Secret Protection Best Practices | パスワードを平文でDBに保存している |
| Information Protection Best Practices | レスポンスにパスワードをそのまま含めている |
| Audit Logging Best Practices | 構造化ログではなく print で標準出力へ出している |
| Log Protection Best Practices | ログにメールアドレス(PII)を出力している |
| Trusted Cryptography Best Practices | 認証ライブラリを使わずbase64エンコードを「トークン」と呼んでいる |
| Privileged Access Best Practices | 管理者APIに権限制御がない |
| Secure by Default Best Practices | 認証・暗号化・PII保護のデフォルトがすべてオフ相当 |
| Tenant Isolation Best Practices | ユーザ間のデータ境界が設計上担保されていない |
各要件をクリックすると、詳細パネルが開き コンプライアンスステータス・コメント(非準拠と判定した根拠)・修正ガイダンス が表示されます。

レビュー結果一覧に複数の Findings(検出事項) がリストアップされ、各 Finding の詳細パネルで非準拠の根拠と修正ガイダンスが確認できれば、設計レビューの体験は完了です。
| 💡 ポイント |
|---|
| ここでは AWS マネージドの汎用的なセキュリティベストプラクティスに対するレビューを体験しました。組織固有のセキュリティポリシー(使用してよい認証ライブラリの限定、ログ出力ルールなど)を要件として追加すると、独自ルールに対する準拠チェックも行えるようになります。詳細は本セクション末尾の「参考: 組織セキュリティ要件(Security requirements)の追加」に記載があります。 |
5. フェーズ2: コードレビューを体験
フェーズ1では、設計段階でセキュリティ要件への違反を見つける設計レビューを体験しました。ただし、設計書だけでは「どんなコードを書くか」までは見えません。たとえばSQL文字列の組み立て方やパスワードハッシュの選び方など、コードを書いてみないと判明しない問題 は、コミットされたコードに対してレビューする必要があります。
フェーズ2では、GitHubリポジトリを Security Agent と連携し、プルリクエストに対してAIが自動でコードレビューを行う流れをEnable code review capability for a GitHub repositoryの手順に沿って体験します。
5.1 Privateリポジトリの準備
コードレビューはPrivateリポジトリのみが対象のため(公式仕様)、まず事前準備でダウンロードしたコードをPrivateリポジトリにpushします。
| 💡 ポイント |
|---|
| 事前準備でダウンロードしたコードには 意図的な脆弱性 が含まれます。Publicリポジトリで作成すると第三者から攻撃手段の参考にされる、フォーク先で稼働させて攻撃される、などのリスクがあります。Visibilityは必ずPrivateを選択 してください。 |
GitHubで新規リポジトリを作成します。
| 設定項目 | 値 |
|---|---|
| Repository name | tasks-api-handson |
| Visibility | Private(必須) |

作成後、ローカルにクローンします。
git clone https://github.com/<あなたのユーザ名>/tasks-api-handson.git
cd tasks-api-handson
事前準備でzipを展開した tasks-api-source/ の中身(design-doc.md と app/)を作業ディレクトリにコピーします。フェーズ2でレビュー対象になるのは app/main.py のコードですが、design-doc.md もフェーズ3のペネトレーションテスト時に ソースコードのコンテキスト として参照されるため、ここで一緒にpushしておきます。
cp -r <zip展開先>/tasks-api-source/* .
リポジトリにpushします。
git add .
git commit -m "Add initial Tasks API"
git push origin main
GitHubの該当リポジトリで design-doc.md、app/main.py、app/__init__.py がmainブランチに表示されていれば、Privateリポジトリの準備は完了です。

| 💡 ポイント |
|---|
| ここで push したコードと 同じ内容のFastAPIアプリケーション が、フェーズ3でCloudFormationテンプレートのUserDataに埋め込まれてEC2上で起動します(リポジトリのコードと稼働環境のコードは1対1対応)。Security Agentはペネトレーションテスト時にこのPrivateリポジトリ側のソースコードを コンテキスト として参照するため、設計→コード→稼働環境を横断した分析が成立します。 |
5.2 GitHub統合の登録(テナントレベル)
コードレビューを動かすには、Security Agent と GitHub を信頼関係で結ぶ必要があります。Security Agent側に「どのGitHub組織・ユーザのリポジトリを見るか」、GitHub側に「Security Agent App にどんな権限を渡すか」を双方向で登録するのがこのフェーズです。テナント(AWSアカウント)レベルの一度きりの設定なので、ここで登録しておけば以降のエージェントスペースから再利用できます。
統合の追加モーダルを開く
GitHub統合の登録は、エージェントスペース詳細画面の「コードレビューを有効にする」を起点に進めるフローになっています。エージェントスペース詳細画面のコードレビューカードにある 「コードレビューを有効にする」 をクリックします。

「統合を追加」 モーダルが開きます。初回は登録済みのGitHub統合がないため、右側の 「新規登録を作成」 を選択し、下の GitHub を選択して 「次へ」 をクリックします。

「GitHub を AWS Security Agent に接続」 画面が開きます。この画面は ステップ1(GitHub App のインストール) / ステップ2(AWS Security Agent の認証) / ステップ3(登録の詳細) の3部構成になっており、上から順に進めます。

ステップ1: GitHub App のインストール
GitHub側に「Security Agent App」を入れることで、Security Agent が GitHub のリポジトリやPRを操作できるようになります。これがないとSecurity Agent側から GitHub にコメントを書き込んだり、PRを生成したりできません。ステップ1 の「GitHub で AWS Security Agent を開く」をクリックすると、GitHub の AWS Security Agent App ページが開きます。右上の 「Install」 をクリックします。

インストール範囲の選択画面になります。本セクションでは自分のアカウント配下の tasks-api-handson リポジトリだけが対象なので、「All repositories」 のままで問題ありません(「Only select repositories」で tasks-api-handson のみ指定してもOK)。「Install」 をクリックします。

ステップ2: AWS Security Agent の認証
ステップ1 はGitHub側のAppインストールだけなので、次はAWS側に「このGitHubユーザとして連携してよい」という認証情報を渡します。これがAWS↔GitHub の双方向トラスト関係を完成させるステップです。AWS Security Agent の画面に戻ります。次に ステップ2 の 「認証する」 をクリックします。

GitHub の認可画面にリダイレクトされます。AWS Security Agent が GitHub アカウントへアクセスする権限を確認し、「Authorize」 をクリックします。

AWS Security Agent の画面に戻ると、ステップ2に 「認証が成功しました」 のチェックマークが表示されます。

ステップ3: 登録の詳細を入力
最後にAWS側でこの統合を識別する名前と、対象とするGitHubアカウントタイプを登録します。これでテナント(AWSアカウント)レベルのGitHub統合の登録自体は完了します。ステップ3 の登録の詳細を入力します。
| 設定項目 | 値 | 設定の基準 |
|---|---|---|
| 登録名 | tasks-api-handson |
複数のGitHub組織を登録する場合の識別名 |
| GitHub アカウントタイプ | ユーザ |
個人アカウントの場合。組織アカウントなら「組織」を選択 |
入力後、右下の 「接続」 をクリックします。

エージェントスペース画面に遷移し、上部に緑のバナー 「GitHub 統合が正常に接続されました」 が表示されれば、テナントレベルのGitHub統合登録は完了です。

5.3 エージェントスペースへのリポジトリ接続とコードレビュー有効化
ここからはエージェントスペースレベルの操作で、実際に監視対象となるリポジトリを fastapi-sample-app エージェントスペースに紐付けます。
統合追加モーダルから既存の登録を選択する
テナントレベルのGitHub統合を登録しただけでは、どのエージェントスペースから・どのリポジトリを 監視するかが決まっていません。同じモーダルからもう一度フローを開始し、今度は登録済みのGitHub統合を再利用してエージェントスペースに紐付けていきます。エージェントスペース詳細画面に戻ったら、コードレビューカードの 「コードレビューを有効にする」 を再度クリックします。

再び 「統合を追加」 モーダルが開きますが、今度は前項で登録したGitHub統合が 「利用可能な登録」 に表示されています。tasks-api-handson を選択して 「次へ」 をクリックします。

監視対象リポジトリを選択する
GitHub統合は組織やユーザ全体への接続なので、その配下に複数のリポジトリがある場合は、どれをこのエージェントスペースで監視するか を明示的に選ぶ必要があります。本セクションの対象は1つだけなので、それだけにチェックを入れます。「GitHub リポジトリを接続」 画面で、登録済み組織配下のリポジトリ一覧が表示されます。本セクションの対象である tasks-api-handson にチェックを入れて 「次へ」 をクリックします。

機能を有効化する
「機能を管理」 画面で、接続したリポジトリに対して有効にする機能を設定します。リポジトリ列のチェックを入れただけでは機能はONになりません。コードレビュー列とペネトレーションテストの修正列のトグルを、それぞれクリックして「有効化済み」に切り替える 必要があります。
| 設定項目 | 値 | 設定の基準 |
|---|---|---|
| リポジトリ列のチェック | ✅ tasks-api-handson |
このエージェントスペースに紐付ける対象 |
| コードレビュー列のトグル | 有効化済み(クリックしてONにする) | PRごとの自動レビューを有効化 |
| ペネトレーションテストの修正列のトグル | 有効化済み(クリックしてONにする) | フェーズ3の修正PR自動生成でも使うため、ここで有効化しておく |
コードレビュー設定で検出対象を選ぶ
コードレビューでは「汎用的な脆弱性パターンを検出する」「組織独自のセキュリティ要件への準拠性をチェックする」「両方」のいずれかを選べます。本セクションではフェーズ2で組織要件をまだ登録していないため、まずは汎用的な脆弱性検出のみを選び、AIが何を指摘してくれるかを体験します。次に 「コードレビュー設定」 で検出対象を選択します。
| オプション | 内容 | 本セクションの選択 |
|---|---|---|
| セキュリティ要件の検証 | 組織のカスタムセキュリティ要件のみチェック | |
| セキュリティ脆弱性検出結果 | 一般的な脆弱性(SQLi等)のみ検出 | ✅ 選択 |
| セキュリティ要件と脆弱性検出結果 | 組織のカスタムセキュリティ要件と一般的なセキュリティ脆弱性の両方について確認 |
右下の 「接続」 をクリックします。

接続完了を確認する
設定が一通り終わっても、本当にエージェントスペースとリポジトリが正しく紐付けられているかを画面で確認しないと、後でPRを作っても「レビューが走らない」という事態に気付くのが遅れます。コードレビュータブの状態を確認することで、ここで連携の成立を確実にしておきます。エージェントスペース画面に戻り、上部に緑のバナー 「統合リソースが追加されました」 が表示されます。さらに 「コードレビュー」タブ を開き、tasks-api-handson が一覧に並んでいればコードレビューの有効化は完了です。

| ⚠️ タブに「リポジトリはまだ接続されていません」と出る場合 |
|---|
| まず 「機能を管理」画面で「コードレビュー」列と「ペネトレーションテストの修正」列のトグルが両方とも「有効化済み」になっているか を確認してください。リポジトリ列のチェックを入れても、これらのトグルがOFFのまま「接続」してしまうと、緑バナー 「統合リソースが追加されました」 は表示されますが、コードレビュータブには反映されません。タブ内の 「コードレビューを有効にする」 ボタンから再度フローを進め、トグルをONにしてから「接続」してください。トグルはONで接続済みなのに表示が変わらない場合は、UIの反映遅延の可能性があるため ブラウザをリロード すれば解消します。 |
5.4 脆弱なコードのPR作成
ここまでの設定でコードレビューは有効になりましたが、レビューを動かす対象がまだありません。コードレビューが動くのはプルリクエストが作られた瞬間なので、わざと脆弱性を含んだPRを作って、AIが何を指摘してくれるかを確認します。
先ほどpushした app/main.py に、新しい脆弱なエンドポイント(タスク検索機能)を追加するPRを作成します。
ローカルでリポジトリを開き、ブランチを作成します。
git switch -c add-task-search
app/main.py の末尾(admin_list_users の関数定義の直後)に、以下のコードを追加します。
@app.get("/api/v1/tasks/search")
def search_tasks(q: str):
conn = get_db()
c = conn.cursor()
c.execute(
f"SELECT id, owner_id, title, body FROM tasks WHERE title LIKE '%{q}%'"
)
rows = c.fetchall()
conn.close()
return [
{"id": r[0], "owner_id": r[1], "title": r[2], "body": r[3]}
for r in rows
]
わざと以下の問題を埋め込んでいます。
- f-stringでクエリパラメータを直接SQL文に埋め込んでおり、SQLインジェクションが成立する
- 認証チェックがなく、全タスク(他ユーザのタスク含む)が誰でも検索可能になる
コードをコミットしてプルリクエストを作成します。
git add app/main.py
git commit -m "Add task search endpoint"
git push origin add-task-search
GitHubのリポジトリ画面を開くと、push直後は上部に 「Compare & pull request」 ボタンが表示されています。このボタンから、ベースブランチ main、比較ブランチ add-task-search の構成でプルリクエストを作成します。タイトルはコミットメッセージと同じ Add task search endpoint のままで構いません。

5.5 AIレビューコメントの確認
PR を作成したら、あとは AWS Security Agent が自動でレビューしてくれるのを待つだけです。普段のGitHubワークフローを離れずにAIレビューを受け取れるのが、コードレビュー機能の使い勝手の良さです。
PR を作成すると、ほぼ即時に aws-security-agent Bot から「AWS Security Agent is reviewing your pull request and will post feedback shortly.」というコメントが付き、レビューが開始されたことが分かります。

数分待つと、Bot が PR の解析を終え、全体の要約コメント と、追加した行に対するインラインコメント が投稿されます。

要約コメントでは、search_tasks エンドポイントに対する指摘が一括で提示されます。今回追加したコードに対しては、認証の欠如、owner_id での所有者スコープ不在による情報漏えい、f-string を使った SQL インジェクション の3点が、修正の方向性(get_current_user の呼び出し、WHERE owner_id = ? でのスコープ、パラメタライズドクエリ化)と合わせて指摘されます。
さらに該当行へのインラインコメントは、以下の3つの観点で構造化されています。
- What is the issue?: 何が問題か(コードのどの部分が脆弱か)
- Why is this important?: なぜ重要か(攻撃者に実際に何ができるか)
- What is the recommendation?: どう直すべきか(修正コード例つき)
PR上に要約コメントとインラインコメントが投稿され、SQLインジェクション・認証欠如・情報漏えいの3点に対して修正コード例つきの指摘が並んでいれば、コードレビューの体験は完了です。
| 💡 ポイント |
|---|
| AIが提案するコード修正例は、そのままコピペで使うのではなく必ずレビュアーが内容を確認してから反映してください。AIが誤った修正を提案する可能性もゼロではないため、最終判断は人間が行う前提で使います。 |
6. フェーズ3: ペネトレーションテストを体験
フェーズ2でPrivateリポジトリにpushしたTasks APIと 同じFastAPIコード をCloudFormationでAWSにデプロイし、その稼働環境に対してAIエージェントによる多段階ペネトレーションテストを実行します。フェーズ2でコードレビュー用に連携したGitHubリポジトリを ソースコードのコンテキスト として参照させることで、Security Agentが 設計→コード→稼働環境を横断したコンテキスト で攻撃シナリオを組み立ててくれるのがポイントです。Quickstart: Run a penetration testの流れに沿って体験します。
| 💡 ポイント |
|---|
| ペネトレーションテスト機能は $50/task-hour の従量課金(秒単位計測)です。新規利用者には 2ヶ月間の無料トライアル が付き、月200 task-hourまで無料で試せます。ただし、トライアル枠を使い切っている/対象外のアカウントで実行した場合、1回のテストで数万円〜十数万円の課金が発生する可能性 があります(公式料金例では小規模APIで約$173、平均的アプリケーションで約$1,200、大規模で約$1,500)。 誤った設定(対象スコープを広く取りすぎる、停止忘れなど)で実行時間が伸びると、想定外の高額請求 につながる恐れがあります。このフェーズの実行は自己責任で行ってください。料金が不安な場合は、実行せずに以降のハンズオン手順を読んで流れを理解するだけに留めるのもOK です。フェーズ1・フェーズ2は無料枠のみで完結しているので、フェーズ3をスキップしても本セクションの核心部分は体験できます。 |
| 💡 ポイント |
|---|
| 本セクションを無料枠外で完走させた場合の概算料金を、セクション制作時の実測値ベースで試算します。Tasks APIは意図的に脆弱性を多く埋め込んであり(SQLi・IDOR・認証バイパス・平文パスワード等)、AIエージェントが13カテゴリ・全28アクションで深掘り検証を行うため、想定よりも task-hour が大きく膨らみます。 実測ベースの目安: - 総 task-hour: 8〜12 task-hour(並列実行のため経過時間より大きくなる) - 単価: $50 / task-hour(秒単位課金) - 完走時の料金: $400〜$600(約60,000〜90,000円)(1ドル150円想定) 公式料金例 の「小規模API 約$173」よりも実測値は高めに着地する傾向があります。これはTasks APIに学習目的で多様な脆弱性を仕込んでおり、AIエージェントが各カテゴリで攻撃検証を完走するためです。 料金特性として知っておくべきこと: - 秒単位で即時課金されます。実行ボタンを押した瞬間から課金が走り、画面の経過時間 ≠ 課金対象時間(並列で複数のエージェントが動くため task-hour の方が大きい) - 途中で停止しても、それまでに消費した task-hour 分は返金されません。1時間経過後に停止しても、その分は支払い対象です - 完走を目指したほうが結果的にコスパが良い です。途中で止めるとPDFレポートも取得できないため、$300払って中途半端に終わるより、$500払って完走させた方が学習価値が高くなります 加えて、フェーズ3で作成するEC2(t3.micro)・ALB・VPCなどの構成リソース費用が 1日あたり数十円〜100円程度 かかります。検証で1〜2日利用する場合は合計で数百円レベルですが、削除し忘れて長期間残すと月額換算で2,000〜3,000円規模になります。最後の「不要リソースの削除」セクションで必ずCloudFormationスタックを削除してください。 判断の目安: - 学習効果を最大化したい・PDFレポートを取得したい → 完走させる。途中中断は「払い損」になる - 料金が不安 → そもそも実行せず、セクションの手順とPDFレポートのサンプル解説を読んで流れを理解するだけに留める - リスクカテゴリを絞りたい → 手順1の「リスクタイプを除外する」で範囲を絞ってから実行(ただし教材で扱うFindingsの一部は出ない可能性あり) 上記はあくまで2026年4月時点の公開料金と為替、および本セクションの制作時実測値に基づく概算です。最新の料金は AWS Security Agent pricing を必ず確認してください。 |
| 💡 ポイント |
|---|
| 無料トライアルは 最初のペネトレーションテストを実行した瞬間 から2ヶ月間開始されます。実行前に以下の3点を確認しておくと安心です。 1. トライアル未開始かの確認: エージェントスペース詳細画面の「ペネトレーションテスト」タブに実行履歴が無ければ、まだトライアルは始まっていません(枠満額)。 2. 利用枠の確認: AWS Billing and Cost Management コンソール → 「Free Tier」ページで、AWS Security Agent の task-hour 使用量を確認できます。 3. 予算アラートの設定: AWS Budgets で「Zero spend budget」を作成しておくと、想定外の課金が発生した瞬間にメール通知が届きます。実行前に仕掛けておくと安全網になります。 |
6.1 Tasks APIをCloudFormationでデプロイ
テンプレートのダウンロード
ペネトレーションテストの対象として、Tasks APIをVPC・ALB・EC2・CloudFrontを含む構成で起動する必要があります。これらを手動で1つずつ作るのは時間がかかるうえ、設定ミスのリスクもあるため、本セクションでは予め用意したCloudFormationテンプレートで一括構築します。以下のボタンからCloudFormationテンプレートをダウンロードしてください。
このテンプレートを適用すると、以下のリソースが作成されます。
| リソース | 名前 | 説明 |
|---|---|---|
| VPC | tasks-api-vpc | 10.100.0.0/16のアドレス範囲を持つ仮想ネットワーク |
| パブリックサブネット×2 | tasks-api-public-subnet-1/2 | ALB・EC2を配置するサブネット(2AZ構成) |
| Internet Gateway | tasks-api-igw | インターネット接続用ゲートウェイ |
| ALB | tasks-api-alb | CloudFrontのオリジンとなるロードバランサ(ポート80) |
| ターゲットグループ | tasks-api-tg | ポート8000(FastAPIのリッスンポート)へ転送 |
| EC2インスタンス | tasks-api-ec2 | Tasks APIを稼働させるEC2(Amazon Linux 2023) |
| セキュリティグループ | tasks-api-alb-sg / tasks-api-app-sg | ALBは80番をインターネット公開、EC2は8000番を ALBからのみ 許可 |
| IAMロール | tasks-api-instance-role | EC2にアタッチされるロール。Session Manager(SSM)経由のアクセスを許可 |
| CloudFront ディストリビューション | (自動生成) | ALBの前段に配置され、HTTPS対応の *.cloudfront.net ドメインを提供する |
| 📝 なぜCloudFrontを挟むのか |
|---|
AWS Security Agent のペネトレーションテスト機能は、対象ドメインの所有権を HTTPS GET で検証します(公式ドキュメント)。一方、ALBの自動DNS(*.elb.amazonaws.com)はAWSが所有するドメインのため、自分のACM証明書を発行できず、HTTPS化が困難です。そこで、CloudFrontディストリビューションをALBの前に配置します。CloudFrontを作ると、 dXXXXXXXXX.cloudfront.net という独自サブドメインと 有効なSSL証明書 が標準で付いてくるため、独自ドメインを購入しなくてもHTTPS要件を満たせる のがポイントです。Security Agentにはこの CloudFront ドメインを登録します。 |
| 📝 Tasks APIのコードはどこにあるか |
|---|
Tasks APIのFastAPIコードは、CloudFormationテンプレート内のEC2インスタンスの UserData に直接埋め込まれています。EC2起動時にUserDataがpipで依存関係をインストールし、コードを /opt/app/main.py として書き出して uvicorn で起動します。これにより、外部のDockerレジストリや公開リポジトリに脆弱なコードを置く必要がなく、CloudFormationテンプレート1つで完結する構成になっています。Privateリポジトリ側のコード(フェーズ2でpush済み)は、Security Agentがペネトレーションテストの コンテキスト として参照する用途で利用されます。 |
CloudFormationスタックの作成
ダウンロードしたテンプレートはローカルにあるだけでは実体が作られません。CloudFormationコンソールからこのテンプレートをアップロードしてスタックを作成することで、Tasks APIのインフラ一式が実際にAWS上にデプロイされます。AWSマネジメントコンソールでCloudFormationのダッシュボードを開き、スタックの作成 > **新しいリソースを使用(標準)**をクリックします。
| 設定項目 | 値 | 設定の基準 |
|---|---|---|
| テンプレートの準備 | 既存のテンプレートを選択 | ダウンロードしたファイルを使用するため |
| テンプレートソース | テンプレートファイルのアップロード | ローカルのテンプレートを直接アップロードするため |
| テンプレートファイル | 先ほどダウンロードしたtasks-api-handson.yml |
ハンズオン環境を構築するテンプレート |
| スタック名 | tasks-api-handson |
スタックを識別するための名前 |


画面下部の「AWS CloudFormation によって IAM リソースがカスタム名で作成される場合があることを承認します。」にチェックを入れ、スタックを作成します。

ステータスがCREATE_COMPLETEになったら、出力タブを開きます。以下の値をコピーしておきます。
CloudFrontDomain(例:dXXXXXXXXX.cloudfront.net): 後ほどSecurity Agentに登録する検証ターゲットTasksApiUrl(例:https://dXXXXXXXXX.cloudfront.net): Tasks APIへのHTTPSアクセス用URL

| ⚠️ CloudFrontドメインにアクセスできない場合 |
|---|
CloudFrontディストリビューションは作成後、全エッジロケーションへの伝搬に5〜15分 かかります。CloudFormationがCREATE_COMPLETEになっても、CloudFrontドメインへのアクセスがすぐに繋がらない場合があります。アクセスエラーが続くときは、5分ほど待ってから再度試してください。 |
Tasks APIの動作確認
CloudFormationがCREATE_COMPLETEになっても、EC2上のFastAPIアプリケーションやCloudFrontの伝搬がまだ完了していない可能性があります。ペネトレーションテストの設定段階でドメイン検証を行うため、その前に「CloudFront → ALB → EC2上のアプリケーション」までの経路が本当に通っているかを自分で確認しておくと、後の手順でつまずきません。以下のコマンドでヘルスチェックエンドポイントを叩きます。CloudFront経由のHTTPSでアクセスします。
curl https://<CloudFrontDomain>/health
以下のように応答が返れば、CloudFront → ALB → EC2上のFastAPIアプリケーションの経路が正常に稼働しています。
{"status":"ok"}
| 💡 ポイント |
|---|
EC2のUserDataがpip installを完了してuvicornが起動し、ALBのヘルスチェックが通るまで 3〜5分程度 かかります。さらにCloudFrontの伝搬で 追加5〜15分 が必要なので、CREATE_COMPLETE 後すぐは502やアクセスエラーが返ることがあります。少し待ってから再度アクセスしてください。もしいつまでも復旧しない場合、まずは Systems Manager → セッションマネージャー からEC2に接続し、 sudo cat /var/log/tasks-api-bootstrap.log でUserDataの実行ログを確認できます。 |
6.2 ペネトレーションテスト機能を有効化
CloudFormationでインフラが揃ったら、AWS Security Agent側でペネトレーションテストの設定を行います。エージェントスペース詳細画面のヘッダーから Enable penetration test をクリックします。3ステップの設定ウィザードが開きます。

ステップ1: ターゲットドメインの設定
テスト対象のドメインと、所有権の検証方法を指定します。ALBの自動DNS名ではなく、CloudFormationが出力したCloudFrontドメインを指定する のがポイントです(HTTPS要件を満たすため)。
| 設定項目 | 値 | 設定の基準 |
|---|---|---|
| Target domain | CloudFormationで出力されたCloudFrontDomain(例: dXXXXXXXXX.cloudfront.net) |
HTTPSで応答できるCloudFrontドメインを使う |
| Verification method | HTTP_ROUTE |
CloudFrontドメインに対してHTTPS GETで検証 |

Next をクリックして次へ進みます。
| 📝 ドメイン検証の必要性 |
|---|
| AWS Security Agentは「自分が所有していないドメインに対して攻撃リクエストを送らない」ための安全装置として、ドメイン所有権の検証を必須にしています(公式ドキュメント)。検証方法は以下の3つから選べます。 One-click verification: Route 53で管理しているドメイン向けの自動検証 DNS_TXT: DNSのTXTレコードに検証トークンを追加する方式(自分のドメインのDNSを編集できる場合) HTTP_ROUTE: 特定のHTTPSパスに検証トークンを含むJSONを応答させる方式(HTTPS対応のWebサーバが必要) 本セクションはCloudFrontドメインを使うため、HTTP_ROUTEで検証します。Security AgentはHTTPS GETで検証パスにアクセスし、レスポンスJSONに検証トークンが含まれていることを確認します。 |
ステップ2: ドメインの検証
Target domainsテーブルで対象ドメインを選択し、Verifyをクリックすると、検証用の固定パス /.well-known/aws/securityagent-domain-verification.json と検証トークン(例: cib4P56CWznyz5vY3WQroA)が表示されます。

このパスへのリクエストに対して、検証トークンを含むJSONを応答させる必要があります。CloudFrontはオリジンであるALBにリクエストを素通りさせる構成のため、ALBのリスナールール に固定レスポンスを設定します。
- EC2コンソールで ロードバランサー を開き、
tasks-api-albの詳細画面を表示 - リスナーとルール タブで
HTTP:80のリスナーを選択 → ルールを管理 → ルールを追加

- 以下の設定で固定レスポンスルールを作成します。レスポンス本文は JSON形式、Content-Typeは
application/jsonが必要な点に注意してください。
| 設定項目 | 値 | 設定の基準 |
|---|---|---|
| ルール名 | aws-security-agent-verification |
ルールの識別名 |
| 条件 | パス(Path)= /.well-known/aws/securityagent-domain-verification.json |
先頭の / を必ず付ける。抜けるとマッチしない |
| アクション | 固定レスポンスを返す(Return fixed response) | 検証用JSONを返す |
| Response body | {"tokens": ["<Security Agentが指定した検証トークン>"]} |
公式仕様で定められたJSON形式 |
| Content type | application/json |
text/plainではなくJSONとして返す |
| HTTPステータスコード | 200 |
検証成功とみなされるコード |
| 優先度 | 1 |
デフォルトルールより先に評価させる |

📝 レスポンス本文はJSONで、Content-Typeも application/json |
|---|
AWS Security Agent の公式ドキュメントでは、検証パスへのレスポンスは以下のJSON形式が要求されています(公式ドキュメント)。{"tokens": ["<insert-token>"]}レスポンス本文がプレーンテキストのトークンだけだったり、Content-Typeが text/plainになっていたりすると、検証は失敗します。 |
ルールを保存したら、ターミナルから直接 CloudFront 経由でアクセスして、想定どおりのJSONが返ることを確認します。
curl -i https://<CloudFrontDomain>/.well-known/aws/securityagent-domain-verification.json
以下のように 200 OK + content-type: application/json + JSONボディが返れば成功です。
HTTP/2 200
content-type: application/json
...
{"tokens": ["cib4P56CWznyz5vY3WQroA"]}
curl で正しい応答が確認できたら、Security Agent の画面に戻り、対象ドメインのラジオボタンを選択した状態で 「検証」 ボタンをクリックします。1〜2分待ってからページをリロードし、ステータスが 「保留中」→「検証済み」 に変わっていれば成功です。検証済みのドメインに対してのみ、ペネトレーションテストが実行できます。

| ⚠️ 検証が「失敗」になった場合 |
|---|
| 「失敗」ステータスは、過去の検証試行が失敗してキャッシュされている可能性があります。以下を順に試してください。 1. curl で200とJSON応答を再確認: ALBルールの設定漏れ、パスの先頭 / 抜け、JSON形式の崩れ、Content-Type の指定漏れがないか2. CloudFrontの伝搬を待つ: ディストリビューション作成直後やキャッシュ無効化直後は、5〜15分の伝搬時間が必要 3. ドメインを削除して再追加: 「Remove Domain」で削除 →「ドメインを追加」で同じCloudFrontドメインを再登録すると、新しい検証トークンが発行されます(古いトークンは無効)。新トークンに合わせてALBルールのレスポンス本文も更新してください |
ステップ3: 追加リソースの設定(オプション)
ペネトレーションテストのカバレッジを広げるための任意設定項目です。本セクションでは最低限で構いません。
| 設定項目 | 値 | 設定の基準 |
|---|---|---|
| Service access | Create default role(デフォルト) | Security Agent用サービスロールを自動作成 |
| VPC(オプション) | 未設定 | Public アクセス可能なCloudFrontドメインなら不要 |
| CloudWatch logs(オプション) | 未設定 | ログ保存したければ指定 |

画面下部の Save をクリックします。AWS Security Agentが設定を検証し、必要なAWSリソースを作成します。

6.3 GitHubリポジトリの連携状態を確認
ペネトレーションテストで発見した脆弱性に対しては、修正PRを自動生成させる ことができます。これには エージェントスペースとGitHub リポジトリの連携が必要ですが、本セクションでは フェーズ2 の「エージェントスペースへのリポジトリ接続とコードレビュー有効化」で「ペネトレーションテストの修正」トグルもあわせて有効化済み のため、ここでの追加操作は不要です。
ペネトレーションテスト機能の設定画面下部の GitHub セクションに、tasks-api-handson リポジトリが「ペネトレーションテストの修正:有効化済み」で表示されていれば、フェーズ3の修正PR自動生成は使える状態です。次のセクションに進んでください。

| ⚠️ 「ペネトレーションテストの修正:無効化済み」と表示されている場合 |
|---|
フェーズ2の「機能を管理」画面で、ペネトレーションテストの修正列のトグルを有効化し忘れている可能性があります。エージェントスペース詳細画面に戻り、tasks-api-handson の 「機能を管理」 から該当トグルを「有効化済み」に切り替えてください。 |
6.4 ペネトレーションテストの実行
ここまでで エージェントスペースとGitHub リポジトリの連携が整ったので、いよいよ稼働中の Tasks API に対するペネトレーションテストを作成・実行します。
Security Agentコンソールのエージェントスペース画面で、ペネトレーションテストカードの 「ウェブアプリケーションで開始」 をクリックして Web Application を起動します。

Web Application のホーム画面に切り替わるので、「ペネトレーションテスト」セクションの 「ペネトレーションテストを作成」 をクリックします。

ここから先は 手順1〜手順4 の4ステップでペネトレーションテストを設定していきます。手順2〜4は「オプション」表記ですが、本セクションでは 手順3(認証リソース)と手順4(学習リソース)まで設定 することで、認証必須エンドポイントの脆弱性検出と、設計→コード→稼働環境を横断したコンテキスト分析の両方を有効化します。手順2のVPCのみスキップします。
手順1: ペネトレーションテストの詳細
最初の手順では、ペネトレーションテストの 基本情報・テスト範囲・実行権限 を設定します。
| 設定項目 | 値 | 設定の基準 |
|---|---|---|
| ペネトレーションテスト名 | tasks-api-handson-pentest |
アプリケーションと用途が識別できる名前。AWS公式は最大100文字以内・記述的な名前を推奨 |
| ターゲット URL | 検証済みドメインから CloudFrontドメイン を選択 | Tasks API の全エンドポイントを対象にするため、ドメインルートを指定 |
| リスクタイプを除外する | 未設定 | Tasks API には学習目的で多様な脆弱性を仕込んでいるため、13カテゴリすべてを網羅的に検知させる |
| 範囲外の URL | 未設定 | 破壊的操作や保護対象パスはないため除外不要 |
| アクセス可能な URL | 未設定 | Tasks API は外部サービス連携なしのため不要 |
| カスタム HTTP ヘッダー | 未設定 | デフォルトの User-Agent: securityagent のままで問題なし |

画面下部にスクロールし、「アクセス許可」 セクションでサービスロールを選択し、「自動コード修正」 セクションでチェックを入れます。
| 設定項目 | 値 | 設定の基準 |
|---|---|---|
| サービスロール | security-testing-XXXXXXXXXXXX(フェーズ3冒頭で Create default role で作成したロール) |
ペネトレーションテスト実行用のIAMロール |
| CloudWatch ロググループ | 未選択(空欄) | 未指定なら /aws/securityagent プレフィックスで自動作成される |
| 自動コード修正を有効にする | チェックを入れる | 連携済みの tasks-api-handson リポジトリに修正PRを自動作成させるため |

設定したら、画面右下の 「次へ」 をクリックします。
手順2: VPC リソース(オプション)
ターゲットドメインがVPC内のプライベート環境にある場合のみ、ペネトレーションテストを実行するVPCを指定します。本セクションでは Tasks API を CloudFront 経由でPublicアクセス可能な構成 にしているため、VPCの設定は不要 です。
VPC欄は空のままで、画面右下の 「次へ」 をクリックします。

| 💡 ポイント |
|---|
| 画面下部に「オプションの手順をすべてスキップ」というボタンもありますが、これを押すと手順3(認証リソース)も飛ばしてしまい、認証必須エンドポイントのテストが行われなくなります。本セクションでは押さずに「次へ」で手順3に進んでください。 |
手順3: 認証リソース(オプション)
Tasks APIには認証必須エンドポイント(/api/v1/tasks など)と認証不要エンドポイント(/api/v1/users/{id}、/api/v1/admin/users など)が混在しています。認証必須エンドポイントまで網羅的にテストするため、テストユーザの認証情報を登録します。
| 設定項目 | 値 | 設定の基準 |
|---|---|---|
| 認証情報の種別 | 認証情報を入力(デフォルト) | ハンズオン用途では直接入力でOK。Secrets Manager 経由は本番運用向け |
| Credential 名 | Credential1(デフォルトのまま) |
1セットしか登録しないため編集不要 |
| ユーザ名 | alice@example.com |
app/main.py の lifespan で初期投入されているテストユーザ |
| パスワード | alice1234 |
同上 |
| 2要素認証 | 未設定 | Tasks API は2FA未実装のため不要 |
| アクセス URL | 手順1で入力した CloudFrontドメイン を選択 | この認証情報で認証するドメインを指定 |
| エージェントスペースログインプロンプト | 下記のプロンプト文を貼り付け | Tasks API はJSON APIのため、AIにログイン手順を明示的に教える必要がある |
エージェントスペースログインプロンプトには、以下の英文をそのまま貼り付けます。
This application is a JSON-based REST API (FastAPI), not a web form.
To authenticate:
1. Send a POST request to /api/v1/auth/login
2. Set the request header: Content-Type: application/json
3. Set the request body (JSON): {"email": "<username>", "password": "<password>"}
4. The response will contain a JWT token in the "token" field of the JSON body
5. For subsequent authenticated requests, include the header: Authorization: Bearer <token>
Use this token to access protected endpoints under /api/v1/tasks.

| 💡 ポイント |
|---|
| AWS Security Agent はLLMベースで認証フローを解釈するため、英語の方が安定して指示を解釈できます。AWS公式のexamples も英語で記載されています。 |
| 💡 ポイント |
|---|
alice@example.com / alice1234 は app/main.py の lifespan 内で初期投入しているテストユーザです。admin@example.com / admin1234 の管理者ユーザも同様に登録されているため、複数ロールでのテストを行いたい場合は 「別の認証情報を追加」 から両方の認証情報を登録できます。 |
| 💡 ポイント |
|---|
| 以前は Login URL / Sign-in payload / Token extraction / Authorization header を個別フィールドで設定していましたが、新UIではこれらすべてが エージェントスペースログインプロンプト という自然言語の指示文に統合されました。AIエージェントがこのプロンプトを読んで認証フローを自律的に実行する仕組みです。Webフォームではない認証フロー(JSON APIなど)の場合は、上記のような明示的な手順を記述しないとログインに失敗するので注意してください。 |
設定したら、画面右下の 「次へ」 をクリックします。
手順4: その他の学習リソース(オプション)
最後の手順では、AIがアプリケーションの構造を理解しやすくするための追加リソースを設定します。フェーズ1〜2で既に tasks-api-handson リポジトリには design-doc.md、ソースコード、API実装が揃っているため、以下を追加できます。
| 追加リソース | 値 |
|---|---|
| ソースコード | フェーズ2で連携済みの tasks-api-handson リポジトリ |
| 設計ドキュメント | リポジトリ内の design-doc.md |
これらを取り込ませることで、Security Agentは「設計書で cursor.execute を使うと宣言されている → 実装でも実際にf-stringの生SQL → 稼働環境でSQLインジェクションが成立する」という横断的な分析が可能になります。

設定したら、画面右下の 「ペネトレーションテストを作成」 をクリックします。
| 💡 ポイント |
|---|
| 同じ画面に 「作成して実行」 ボタンもあります。こちらは設定保存と同時にテストが走り出すショートカットです。本セクションでは設定が正しく保存されたことを画面で確認してから実行に移れるよう、「ペネトレーションテストを作成」(作成のみ)を選択します。 |
ペネトレーションテストの実行開始
「ペネトレーションテストが作成されました」の緑バナーが表示されたら、いよいよ実行に進みます。
| 💡 ポイント |
|---|
| 次のステップで 「実行を開始する」 ボタンを押すと、その瞬間から $50/task-hour の従量課金が秒単位で開始 されます。一度実行を開始すると、途中で停止しても すでに消費した task-hour 分は返金されません。 無料枠外で完走させた場合、本セクションの実測値で $400〜$600(約60,000〜90,000円) の課金が発生します。詳細は本セクション冒頭の「💡 本セクションの実測料金」に記載があります。 重要:2ヶ月の無料トライアルは「初回ペネトレーションテスト実行時点」から起算されます。AWS公式の料金ページにも new AWS Security Agent customers receive a 2-month free trial starting with their first penetration test run と明記されているとおり、今回のボタン押下が アカウントとして初めての実行 であれば、その瞬間から2ヶ月の無料期間カウントダウンが始まります。Security Agent を今後の業務・本番運用で使う予定がある場合、本セクションで初回実行をしてしまうと、本来一番価値のあるタイミングで無料枠を消化済み になる可能性があります。業務で使う予定があるなら、本セクションでは実行を見送り、手順を読むだけに留めて無料枠を温存するという判断も検討してください。ボタンを押す前に、以下を必ず確認してください: 1. 無料トライアル枠の残量 を AWS Billing コンソール → 「Free Tier」で確認したか 2. 予算アラート(AWS Budgets) を仕掛けたか(想定外の課金検知用) 3. 手順1のターゲットURLが、自分が所有するTasks APIのCloudFrontドメインで間違いない か 4. 手順1で「自動コード修正を有効にする」のチェック状態 が意図通りか 5. 無料トライアルの条件(2ヶ月/月200 task-hour)と料金($50/task-hour)は 2026年4月時点 の情報。実行前に AWS Security Agent pricing で 最新の条件・料金を必ず確認 したか 料金が不安な場合は、ここでブラウザを閉じて実行を取りやめても問題ありません。作成した状態で保存されているだけでは課金は発生しません。後日改めて実行することもできます。 |
確認が取れたら、画面右上の 「実行を開始する」 をクリックします。

「ペネトレーションテストが開始されました」の緑バナーが表示され、ステータスが 「進行中」 に切り替われば、ペネトレーションテストの開始は完了です。

| 💡 ポイント |
|---|
| ペネトレーションテストは プリフライト → 静的分析 → ペネトレーションテスト → ファイナライズ の4フェーズで進みます。実際の攻撃リクエストが Tasks API に飛ぶのは3フェーズ目の「ペネトレーションテスト」からで、それまでのフェーズは攻撃側の準備(テスト基盤のプロビジョニング・ソースコード解析)です。プリフライトだけでも5〜15分かかるので、すぐに攻撃が始まらなくても焦らず待ちましょう。 |
6.5 ペネトレーションテスト結果の確認
ペネトレーションテストは最大数時間かかります(対象アプリケーションの規模とリスクカテゴリ数に応じて、本セクションの実測では3〜5時間程度)。実行中はステータスが「進行中」のままなので、完了するまで待ったうえで結果画面に進みます。
実行ステータスを確認する
検出結果の中身に入る前に、まずはテスト全体が正常に最後まで走り切ったかを確認しないと、サマリが信頼できません。途中で失敗していると意図していないFindingsだけが見えるため、対応の優先順位を見誤る原因になります。ペネトレーションテストが完走すると、ステータスが 「完了」 に切り替わり、検出結果の件数(重要・高・中程度・低)がサマリで表示されます。エージェントスペース詳細画面のペネトレーションテストタブで、対象のテスト名(tasks-api-handson-pentest)をクリックして詳細画面を開きます。

「現在の手順」が 「すべての手順が完了しました」、ステータスが 「完了」 になっていれば、テストは正常に終わっています。Tasks APIに意図的な脆弱性を仕込んでいるので、重要 / 高 / 中程度 が複数件、合計10件前後の検出結果が出ていれば期待どおりの状態です。
| 💡 ポイント |
|---|
ステータスが「失敗」になっている場合は、ターゲットURLへの到達性や認証情報のいずれかに問題があった可能性が高いです。手順1で指定したCloudFrontドメインが現在もアクセスできるか、手順3で指定した alice@example.com / alice1234 でログインできるかを確認してから、ペネトレーションテストを再作成してください。 |
ペネトレーションテストの実行詳細を確認する
完走したことが分かったら、次は「全体としてどのカテゴリの脆弱性が、どのくらいの重大度で出ているか」を俯瞰して掴みます。最初から個別Findingsの中身を1件ずつ読むのではなく、まずサマリで全体像を把握すると、後で個別Findingsを読む順番(重要度の高い順)を判断しやすくなります。「すべての実行」テーブルから個別の実行行をクリックすると、実行詳細画面 が開きます。ここでは、4フェーズの進捗・重大度レベルの分布(円グラフ)・リスクタイプ別の件数(横棒グラフ)が一目で把握できます。

円グラフは 重大度(Severity) ごとの件数を表しています。重大度の判定基準は AWS Security Agent が出力するレポート(後述の「サンプルレポートのダウンロード」を参照)の Executive Summary に明記されており、重要(Critical) が最優先で対応すべきレベルです(英語表示時の原文。日本語表示の場合は翻訳された日本語が表示されます)。
Critical Requires immediate action; exploitation could lead to system compromise. High Requires prompt attention; exploitation could result in significant security impact. Medium Should be addressed in a reasonable timeframe; contributes to overall security risk. Low Can be addressed as part of regular maintenance; minimal immediate risk. Informational For informational purposes; minimal to no immediate risk.
横棒グラフの リスクタイプ には、Sql Injection、Insecure Direct Object Reference、Privilege Escalation、Server Error 500 など、Tasks APIに仕込んだ脆弱性カテゴリが並びます。Tasks APIで意図したとおり、SQLインジェクションとIDOR(認可の不備)が複数件検出されていれば、AIが想定どおりに脆弱性を発見できている証拠です。
個別Findingsの詳細を確認する
サマリで全体像が見えたら、次は1件ずつのFindingに踏み込みます。Security Agentの強みは「指摘するだけ」ではなく実際に攻撃した証跡(Reproduction Steps)まで残してくれる点なので、ここで詳細パネルを実際に開いて、AIが「どんな攻撃ペイロードで脆弱性を確定させたか」を読み解きます。「検出結果」タブ をクリックすると、検出された個別の脆弱性(Findings)の一覧が左ペインに表示され、選択したFindingの詳細が右ペインに展開されます。

各Findingには、以下の情報が表示されます。これらの指標の意味も、レポートの Executive Summary に定義があります。
エージェントの信頼度(Agent confidence level) は、AIエージェントがそのFindingを本物の脆弱性だと判定した確度です。
Agent confidence level: Indicates AWS Security Agent's certainty that a finding represents a genuine security vulnerability. High confidence findings have been verified and confirmed through successful exploitation. Medium and low confidence findings may require additional manual validation.
重大度(Severity) は前述の Critical / High / Medium / Low / Informational の5段階です。リスクスコア(Risk score) は CVSS v3.1 に基づく数値で、10.0 が最大 です。
Risk score: A numerical assessment combining the severity of the vulnerability with the likelihood of exploitation using Common Vulnerability Scoring System (CVSS) metrics. Higher scores indicate findings that should be prioritized for remediation. Risk scores are calculated using CVSS v3.1 (Common Vulnerability Scoring System version 3.1).
たとえばスクリーンショットで選択している 「SQL Injection Authentication Bypass in Login Endpoint」 は、レポートで以下のように説明されています。/api/v1/auth/login の email と password の両方からSQLインジェクションが成立し、認証をバイパスして管理者トークンを取得できることが確認されています。
The POST /api/v1/auth/login endpoint is critically vulnerable to SQL injection via both the email and password JSON body fields. The application constructs raw SQL queries using unsanitized user input against a SQLite 3.40.0 database, allowing multiple injection techniques:
- OR-based predicate injection: Injects
' OR 1=1--into the email field, making the WHERE clause always true and returning the first database row (admin user) without valid credentials.- UNION-based data extraction: Injects
UNION SELECT sqlite_version(),2--to append an attacker-controlled SELECT statement, causing the DB to return arbitrary data ...- Password field injection: The password field is equally vulnerable — injecting
' OR '1'='1bypasses password verification and returns the admin token.
詳細パネルを下にスクロールすると、Reproduction Steps(再現手順)として実際に投げた curl コマンドと応答が掲載され、Risk Reasoning で CVSS の各メトリクス(AV / AC / PR / UI / S / C / I / A)の評価根拠が解説されます。「疑わしい」で止まらず 実際に攻撃リクエストを送って成功したログまで残している のが、AIペネトレーションテストの特徴です。
PDFレポートを生成する
画面で個別に確認する以外に、全Findingsを1つのPDFレポートにまとめて出力 できます。チームへの共有や、コンプライアンス監査の証跡として保管する用途を想定した機能です。
実行詳細画面の右上にある 「レポートを生成」 ボタンをクリックします。

レポートに含める内容を絞り込むダイアログが開きます。デフォルトではすべてのリスクレベル・リスクタイプ・タスクステータスが選択された状態になっています。

| 設定項目 | 値 | 設定の基準 |
|---|---|---|
| リスクレベル | Critical / High / Medium / Informational すべて選択 | 体験用途では網羅的に確認したいので絞り込まない |
| 信頼度レベル | High | 確証の取れた検出結果のみに絞る |
| 検出結果のステータス | Active | 未対応のFindingsのみを対象にする |
| リスクタイプ | すべて選択 | 13カテゴリすべての結果を確認する |
| タスクステータス | Completed | 完走したタスクの結果のみを対象にする |
設定したら、画面右下の 「生成してダウンロード」 をクリックします。1分前後でPDFがダウンロードされます。
サンプルレポートのダウンロード
参考として、本セクションの制作時に Tasks API で実際に実行したペネトレーションテストのレポートPDFを配布します。実行を見送った場合でも、このPDFを読むことで「どのような検出結果が出力されるのか」「Findings の証跡がどこまで詳細に書かれるのか」を体感できます。
PDFは大きく以下の構成になっています。
- Executive Summary: テスト全体の概要と、Severity / Confidence / Risk score の判定基準
- Scope: テスト対象ドメインと使用した認証情報
- Methodology: 4フェーズの実行アプローチと、各リスクカテゴリで実行した攻撃シナリオの一覧
- Findings (12): 検出されたFindingsの一覧(タイトル・重大度・ステータス)
- Detailed Findings: 個別Findingごとの詳細(Description / Reproduction Steps / Risk Reasoning)
メソドロジーのセクションには、AIエージェントが取る4フェーズのアプローチが明記されています。
This penetration test was conducted using AWS Security Agent, which deploys specialized AI agents through a four-phase approach: Preflight (connectivity validation), Static Analysis (code and configuration review), Penetration Testing (runtime vulnerability exploitation), and Finalizing (validation and reporting). The agent analyzes application context from source code and documentation to identify vulnerabilities through tailored multi-step attack scenarios.
そして、Security Agent の最大の特徴である 「証跡ベースの検証」 がここで宣言されています。
AWS Security Agent validates findings through proof-based exploitation, providing reproducible attack paths with step-by-step evidence. Each finding includes CVSS v3.1 severity assessment, confidence rating based on validation success, and detailed reproduction steps.
サンプルレポートでは、Tasks APIに意図的に仕込んだ脆弱性が 12件のFindings として検出されています。重要(Critical)3件・高(High)5件・中程度(Medium)3件・参考情報(Informational)1件という内訳で、特に Critical の上位3件は SQLインジェクション・認証バイパス・複数の脆弱性を連鎖させた完全な権限昇格チェーン という、いずれも単独で本番システムを致命的に侵害できるレベルの脆弱性です。
| 💡 ポイント |
|---|
| Security Agent のレポートPDFはコンソールの言語設定にかかわらず英語で出力されます。チームへ展開する際は、Critical / High などの重大度ラベルや、Description / Reproduction Steps の見出しが英語であることを前提に共有してください。社内向けに日本語化が必要な場合は、PDFのテキストを翻訳ツールに通すか、Findings 一覧(コンソール側は日本語表示に対応)からスクリーンショットで補足するのが現実的です。 |
6.6 修正PRを自動生成する
PDFレポートで結果を把握できたあと、AWS Security Agent には 検出された脆弱性に対する修正コードを生成し、GitHub にPRとして自動投稿する 機能が用意されています。Findingの詳細パネル右上にある「コードを修正」ボタンをクリックすると、Security Agent が修正案を考案し、フェーズ2で連携済みの tasks-api-handson リポジトリに 修正PRを自動作成 してくれます。

公式ドキュメントの Remediate a penetration test finding では、リポジトリ種別による挙動の違いが明記されています(英語表示時の原文。日本語表示の場合は翻訳された日本語が表示されます)。
For private GitHub repositories, AWS Security Agent opens a pull request with the proposed fix. For public repositories, the remediation is available as a downloadable diff file that you can apply locally.
本セクションの tasks-api-handson は Privateリポジトリ で連携しているため、ボタンを押すと修正PRがGitHubに自動作成されます。生成されたPRは Finding 詳細パネルの「Code Remediation」セクションにステータスとPRリンクが表示されるので、GitHubの Pull requests タブから通常のレビュー・マージのフローで適用できます。
なお、上記のスクリーンショットでは「コードを修正」ボタンが灰色で非活性になっています。Security Agent側で 修正対象のコード位置が明確に特定できたFinding に対してはこのボタンが活性化され、クリックすると修正PRが作成される、という挙動になります。
| 💡 ポイント |
|---|
| 自動生成された修正PRは、無条件にマージせず、必ず開発者がレビューしてからマージ することが推奨されます。AIが生成するコードは正しい修正方針になっているケースが多いものの、組織独自のコーディング規約・既存設計との整合性・テストカバレッジの担保などは人間がチェックする必要があります。次の「検出された脆弱性の解説と対策案」セクションで示す対策方針と照らし合わせて、修正PRの妥当性を評価するのがおすすめです。 |
Findings一覧に複数件が表示され、PDFレポートをダウンロードできていれば、ペネトレーションテストの体験は完了です。
| 💡 ポイント |
|---|
| 各FindingのProof of exploitationを開いて、AIがどんな攻撃リクエストを送ったか・どう応答を分析して脆弱性を確定させたかを読むと、AIペネトレーションテストの実力が実感できます。従来のスキャナが「疑わしい」で止まっていた指摘が、「実際に悪用できた」まで踏み込んで検証されている点に注目してみてください。 |
| 💡 ポイント |
|---|
Security Agentの真価は 複数のFindingsを連鎖させて1つの致命的な攻撃シナリオに昇華させる 点にあります。Tasks APIの場合、たとえば「/api/v1/auth/login でSQLi → 任意ユーザのpasswordを取得 → そのユーザでログイン」あるいは「/api/v1/admin/users で全ユーザの認証情報を取得 → 個別ユーザになりすまし → 他ユーザのタスク閲覧」のように、単独では中程度の問題が連鎖した結果として全データ漏えいに繋がるケースを発見してくれます。Findingsの「Attack chain」表示があれば、そこを開いて連鎖の道筋を確認してみてください。 |
| 💡 ポイント |
|---|
| 従来のペネトレーションテストは「外部ベンダに年1〜2回依頼、1回数百万円、結果はPDFレポート」が一般的でした。AWS Security Agentのペネトレーションテストは オンデマンドで実行でき、しかも修正PRまで自動生成 されます。1回あたり$400〜$600(小〜中規模APIの場合)と従量課金ではありますが、従来比で1/10〜1/100のコストで、リリース前の重要な変更タイミングごとに実行する、といった運用が現実的になります。 |
6.7 検出された脆弱性の解説と対策案
ここからは、サンプルレポートに掲載されている12件のFindingsの中から特に重要な4種類を取り上げ、レポートの記述を引用しながら何が問題で、どう直すべきか を解説します。Tasks APIには複数の脆弱性が連鎖した攻撃チェーンが成立していますが、根本原因は「入力値の検証不足」「暗号学的保護の欠如」「認可チェックの欠落」の3点に集約されます。Security Agent の「コードを修正」ボタンが自動生成するPRも、おおむねここで紹介する方針の修正コードになっています。
SQLインジェクション(Finding 1・2・6)
レポートの Finding 2 では、ログインエンドポイントが致命的なSQLインジェクションに対して脆弱であることが指摘されています(英語表示時の原文。日本語表示の場合は翻訳された日本語が表示されます)。
The POST /api/v1/auth/login endpoint is critically vulnerable to SQL injection via both the email and password JSON body fields. The application constructs raw SQL queries using unsanitized user input against a SQLite 3.40.0 database
Tasks APIの app/main.py ではログイン処理が、ユーザ入力を f-stringで生SQLに直接埋め込む 実装になっています。攻撃者が email フィールドに ' OR 1=1-- を渡すと、SQLが WHERE email='' OR 1=1--' AND password='...' のように展開され、WHERE 句が常に真になることで、認証なしに最初の行(管理者)のトークンが取得できてしまいます。
対策は、ユーザ入力を SQL構文の一部としてではなく値として扱わせる ことです。素のsqlite3を使う場合は ? プレースホルダによるパラメータ化クエリ、SQLAlchemyを使う場合はORMのfilterを利用します。
NGの実装例です。f-stringでSQLを組み立てており、入力値が構文として解釈されてしまいます。
cursor.execute(
f"SELECT * FROM users WHERE email='{email}' AND password='{password}'"
)
パラメータ化クエリで書き換えると、入力値は値として渡されるためSQL構文に影響しません。
cursor.execute(
"SELECT * FROM users WHERE email = ? AND password = ?",
(email, password),
)
SQLAlchemy ORMを使うと、SQL文字列を組み立てる必要がなくなり、より安全です。
user = db.query(User).filter_by(email=email).first()
公式のFastAPI SQL (Relational) Databases でも、SQLAlchemyを通じたDB操作が標準パターンとして示されています。
偽造可能な認証トークン(Finding 3・8)
レポートの Finding 3 では、トークンに署名検証メカニズムが完全に欠落していることが指摘されています。
The application uses plain base64-encoded tokens in the format base64('user_id:role') with no cryptographic signature, HMAC, or integrity protection. Any attacker can forge a valid token for any user ID and any role purely locally (e.g., echo -n '3:user' | base64).
Tasks APIは base64('user_id:role') という形式のトークンを発行していますが、サーバ側に秘密鍵がなく、署名検証もしていない ため、攻撃者がローカルで echo -n '1:admin' | base64 を打つだけで管理者トークンを偽造できます。
対策は、JWT (JSON Web Token)を使い、サーバ側の秘密鍵で HMAC署名 を付けて発行・検証することです。秘密鍵を知らない攻撃者は payload を改ざんしても署名検証で弾かれます。
import os
from datetime import datetime, timedelta, timezone
import jwt
JWT_SECRET = os.environ["JWT_SECRET"] # 本番ではSecrets Manager等から取得
def create_token(user: User) -> str:
payload = {
"sub": str(user.id),
"role": user.role,
"exp": datetime.now(timezone.utc) + timedelta(hours=1),
}
return jwt.encode(payload, JWT_SECRET, algorithm="HS256")
def verify_token(token: str) -> dict:
return jwt.decode(token, JWT_SECRET, algorithms=["HS256"])
JWTライブラリは PyJWT 公式ドキュメント に記載があります。exp クレームを必ず含めてトークンに有効期限を設けることで、漏えい時の影響範囲を時間的に限定できます。
パスワードの平文保存とレスポンスへの露出(Finding 4・7)
サンプルレポートでは、Finding 4(タイトル: IDOR on /api/v1/users/{user_id} - Unauthenticated Access to Any User Profile with Plaintext Passwords)と Finding 7(タイトル: Unauthenticated and Unprivileged Access to Admin User List with Plaintext Passwords)の両方で、レスポンスに平文パスワードが含まれることが指摘されています。Finding 4 の Description には次のように記載されています。
The passwords stored and returned are in plaintext (not hashed), compounding the severity.
Tasks APIは登録時のパスワードを平文のままDBに保存し、さらに APIレスポンスのJSONにも password フィールドを含めて返却 しています。万一DBやレスポンスが漏えいすると、全ユーザのパスワードがそのまま攻撃者の手に渡ります。
対策は2つを必ず両立させます。1つ目は、保存時に bcrypt などの適応的ハッシュ関数でハッシュ化することです。bcryptは計算コストが調整可能で、ブルートフォース攻撃に対する耐性があります。
import bcrypt
def register(email: str, password: str) -> User:
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode()
user = User(email=email, password=hashed)
db.add(user)
db.commit()
return user
def login(email: str, password: str) -> User | None:
user = db.query(User).filter_by(email=email).first()
if user and bcrypt.checkpw(password.encode(), user.password.encode()):
return user
return None
2つ目は、APIレスポンスのスキーマから password を除外 することです。FastAPIでは response_model にPydanticモデルを指定することで、モデルに定義していないフィールドは自動的にレスポンスから除外されます。
from pydantic import BaseModel
class UserResponse(BaseModel):
id: int
email: str
role: str
# password フィールドはあえて定義せず、レスポンスから除外する
@app.get("/api/v1/users/{user_id}", response_model=UserResponse)
def get_user(user_id: int):
return db.query(User).filter_by(id=user_id).first()
OWASP Password Storage Cheat Sheet では、現代のパスワードハッシュとして bcrypt / scrypt / Argon2 が推奨されており、平文保存や単純なMD5・SHA-1ハッシュは明確に非推奨とされています。
IDOR と認可チェックの欠落(Finding 4・7・10)
Finding 4 は IDOR と平文パスワード露出を1つにまとめたFindingで、ここでは IDOR の観点を取り上げます(平文パスワードの観点は前述の「パスワードの平文保存とレスポンスへの露出」セクションに記載があります)。レポートの Finding 4 の Description では、認証・認可の両方が完全に欠落していることが次のように指摘されています。
The GET /api/v1/users/{user_id} endpoint enforces no authentication or authorization controls. Any client — whether completely unauthenticated or authenticated as a low-privilege user — can access any user's full profile by manipulating the integer user_id path parameter.
Tasks APIは /api/v1/users/{user_id} で パスパラメータの user_id をそのままDB検索に使って返却 しているだけで、リクエスト元が誰かを確認していません。これは典型的な IDOR(Insecure Direct Object Reference、安全でない直接オブジェクト参照)です。
対策は、すべての保護対象エンドポイントで 2段階のチェック を行うことです。1段階目は 認証(リクエストに有効なトークンが付いているか)、2段階目は 認可(その認証ユーザがリソースにアクセスする権限を持つか)です。
FastAPIではDependsを使って認証処理を共通化し、エンドポイントの先頭で認可チェックを書きます。
from fastapi import Depends, Header, HTTPException
def get_current_user(authorization: str = Header(...)) -> User:
token = authorization.removeprefix("Bearer ")
try:
payload = verify_token(token) # 前述のJWT検証
except jwt.PyJWTError:
raise HTTPException(401, "Invalid token")
user = db.query(User).filter_by(id=int(payload["sub"])).first()
if not user:
raise HTTPException(401, "User not found")
return user
@app.get("/api/v1/users/{user_id}", response_model=UserResponse)
def get_user(
user_id: int,
current_user: User = Depends(get_current_user),
):
# 認可チェック:自分自身か管理者のみアクセス可能
if current_user.id != user_id and current_user.role != "admin":
raise HTTPException(403, "Forbidden")
user = db.query(User).filter_by(id=user_id).first()
if not user:
raise HTTPException(404, "Not found")
return user
/api/v1/admin/users のような 管理者専用エンドポイント では、current_user.role == "admin" の確認を必ず行います。
@app.get("/api/v1/admin/users", response_model=list[UserResponse])
def admin_list_users(current_user: User = Depends(get_current_user)):
if current_user.role != "admin":
raise HTTPException(403, "Admin only")
return db.query(User).all()
OWASP API Security Top 10 — API1:2023 Broken Object Level Authorization でも、オブジェクトIDを受け取るすべてのAPI操作にオブジェクトレベルの認可チェックを実装すること が原則として明記されています。
対策の優先順位
これら4種類の対策を Tasks API に適用すると、サンプルレポートで Critical / High に分類されているFindingsの大半が解消されます。実務で対応する際は、Findings の重大度の順(Critical → High → Medium → Informational)で着手するのが基本です。Critical の上位には複数の脆弱性が連鎖した攻撃チェーンが含まれていることが多く、チェーンの起点を1つ潰すだけで、連鎖していた複数のFindingsが同時に解消する ケースもあります。本セクションの場合、SQLインジェクションを潰すと、それを起点としていた認証バイパス・トークン取得・権限昇格のチェーンがまとめて成立しなくなります。
組織独自の追加要件(使用してよいライブラリ・ログ出力ポリシーなど)をコードレビューに組み込みたい場合は、次の「参考: 組織セキュリティ要件(Security requirements)の追加」セクションも参照してください。
7. 参考: 組織セキュリティ要件(Security requirements)の追加
ここまでのフェーズではAWS Security Agentが内蔵するセキュリティチェック(一般的な脆弱性・OWASP Top 10)を中心に体験してきました。Security Agentはさらに、組織固有のセキュリティポリシーをカスタム要件として定義し、設計レビュー・コードレビューで自動チェックさせることができます。本セクションは任意の発展課題として、その挙動を体験できる構成です。
7.1 セキュリティ要件(Security requirements)とは
セキュリティ要件は 組織レベル で定義され、全エージェントスペース共通で適用 されます。「使ってよいライブラリ」「ログ出力ルール」「DB接続方式」など、業務ドメインや組織のコーディング規約に合わせた独自ルールを言葉で記述しておくと、AIがレビュー時にそれらへの準拠性も判定してくれます。
7.2 セキュリティ要件の登録
組織独自のルールをAIに守ってもらうには、まずルール自体をSecurity Agentに登録する必要があります。本セクションでは、Tasks API で問題になっていた「f-string で組み立てる生SQL」を構造的に防ぐため、「DBアクセスはORM経由に限定する」というルールを1件登録します。Security Agent コンソールの左メニューから「セキュリティ要件」ページを開き、「カスタムセキュリティ要件」タブに切り替えて、画面右側の「カスタムセキュリティ要件を作成」をクリックします。タブには他に「マネージドセキュリティ要件」(AWSが提供するテンプレート一覧)と「有効なセキュリティ要件」(現在有効化されているもの)がありますが、組織独自の要件を一から定義する場合は「カスタムセキュリティ要件」タブを使います。

登録画面では、上部に「AWS マネージドセキュリティ要件をカスタマイズ - オプション」セクションがあります。AWSが用意するテンプレートを出発点にしたいときはここでテンプレートを選択しますが、本セクションでは一から定義するため未選択のまま進めます。その下の「セキュリティ要件の詳細」セクションに値を入力していきます。
ハンズオンでは、Tasks APIで露呈した f-string で組み立てた cursor.execute 起因のSQLインジェクション を構造的に防ぐ目的で、データベースアクセスを SQLAlchemy などのORM経由に限定する 生SQL禁止 の要件を1つ登録します。以下の値を入力し、画面右下の「セキュリティ要件の作成と有効化」ボタンで保存することで、作成と同時にレビュー対象として有効化できます(左隣の「セキュリティ要件を作成」は作成のみで有効化はしないボタンです)。
| 入力項目 | 何を指定するか | 値 |
|---|---|---|
| セキュリティ要件名 | 要件の識別名(80文字以内) | ORM-only database access |
| 説明 | 要件がチェックする内容の簡潔な説明(500文字以内) | データベースアクセスは必ずSQLAlchemyを経由し、生SQLの実行(cursor.execute 等)を禁止する。 |
| 適用性 | この要件を評価すべきシナリオ・システムタイプ・条件(10,000文字以内) | データベースに対するすべてのCRUD操作。ユーザ管理・タスク管理・認証情報の検証・管理者機能などのDB操作を含む。 |
| コンプライアンス条件 | 何を「遵守」とし、何を「違反」とするかの判定基準(10,000文字以内) | 遵守: SQLAlchemy ORM(db.query()、db.add() など)またはORMの text() ヘルパーとパラメータ化クエリでDBアクセスしている。違反: cursor.execute(f"SELECT ...") のように生SQLを文字列で組み立てている、f-string や + でユーザ入力をSQL文に埋め込んでいる。 |
| 是正ガイダンス - オプション | 違反を検出したときの修正方法ガイダンス(10,000文字以内)。組織内のコーディング規約ドキュメントへのリンクなどを記載する | SQLAlchemy ORMに移行し、User.query.filter_by(email=email).first() のようなORMクエリで書く。生SQLが必要な場合は text(...) とパラメータバインドを使用する。 |

保存後、「カスタムセキュリティ要件」タブの一覧に ORM-only database access が表示され、「セキュリティ要件のステータス」列が 「有効化済み」 になっていれば登録完了です。

実務では認証ライブラリの統一・構造化ログによるPII保護など複数の要件を組み合わせて運用しますが、本セクションでは挙動の確認が目的のため、この1件で十分です。
7.3 コードレビュー設定の切り替え
セキュリティ要件を登録しただけでは、コードレビューはそれを評価対象としてくれません。フェーズ2でコードレビュー設定を「セキュリティ脆弱性検出結果」のみで作成しているため、登録した組織要件もレビュー対象に含めるには、エージェントスペースのコードレビュー設定を切り替える必要があります。
エージェントスペース fastapi-sample-app の詳細画面を開き、「コードレビュー」タブ に切り替えます。「コードレビュー設定」セクションの右上にある 「設定を編集」 ボタンをクリックします。

「コードレビュー設定を編集」モーダルが開き、3つの選択肢が表示されます。「セキュリティ要件と脆弱性検出結果」 を選択して 「変更を保存」 をクリックします。

「コードレビュー設定」セクションの 「選択」 が「セキュリティ要件と脆弱性検出結果」に変わっていれば、設定変更は完了です。これで、以降に作成されるPRから組織要件への準拠性チェックも追加で行われるようになります。

7.4 期待される挙動の変化
設定を切り替えたあとに新しくPRを作成すると、Tasks APIに対するコードレビューでは、通常の脆弱性検出に加えて 組織要件への準拠性チェック が動きます。今回登録した要件であれば、app/main.py の cursor.execute による生SQL実行が「ORM-only database access に違反」として、組織要件側の指摘として現れる、という挙動になります。
| 💡 ポイント |
|---|
| 本セクションでは コードレビューの再実行は行いません。コードレビューにはプレビュー期間中の無料クォータ上限があり、検証のために何度もPRを作り直すと上限に達する可能性があるためです。コードレビュー自体の挙動はフェーズ2で確認済みなので、ここでは「設定を切り替えると次回PR以降のレビュー結果がこう変わる」という理解までで十分です。実務で実際に試したくなったタイミングで、必要なPRに対して1度だけ走らせるのがおすすめです。 |
このように、組織独自のコーディング規約を コードレビューに自動で組み込める ことが、Security Agentを実務で運用する際の大きなメリットになります。認証ライブラリの統一やPII保護など、組織のセキュリティポリシーに合わせて要件を増やしていくことで、AIレビューが守るべきルール集をそのまま組織のガードレールにできます。
| 💡 ポイント |
|---|
| 組織セキュリティ要件は、ハンズオン後の片付けで削除しなくても課金には影響しません(設計レビュー・コードレビューは無料クォータ内で利用できるため)。本番運用に向けて要件をブラッシュアップしていく場合は、そのまま残して継続的に育てていくのがおすすめです。 |
8. 不要リソースの削除
ハンズオン完了後、不要なリソースを削除して課金やセキュリティリスクを避けます。AWS Security Agent そのものについては、エージェントスペースを残しているだけでは課金は発生しません(設計レビュー・コードレビューはプレビュー相当の無料クォータ内で利用でき、ペネトレーションテストは実行時のみ task-hour 課金されるため)。一方で、フェーズ3でデプロイした Tasks API のインフラ(EC2・ALB・CloudFront等)は継続課金される ため、検証が終わったら 必ず削除 してください。
8.1 エージェントスペースの削除
エージェントスペース自体に課金は発生しませんが、検証で作成したワークスペースをそのまま残しておくと、後で別の本物のリポジトリ用途に使い回そうとしたときに混乱を招きます。検証用と分かるエージェントスペースは、用が済んだ時点で削除しておくのが安全です。Security Agent コンソールの左メニューから 「エージェントスペース」 を開きます。一覧で fastapi-sample-app を選択し、画面右上の 「エージェントスペースを削除」 をクリックします。エージェントスペース内のレビュー履歴・ペネトレーションテスト設定・検出結果に加えて、GitHubリポジトリとの連携も合わせて解除 されるため、別途連携解除の操作は不要です。

| 💡 ポイント |
|---|
| エージェントスペースを削除すると、過去のレビュー履歴やペネトレーションテスト結果がすべて削除されます。レビュー結果をポートフォリオや社内共有に使いたい場合は、削除前にスクリーンショットやエクスポートを取っておいてください。 |
| 💡 ポイント |
|---|
エージェントスペース自体は残し、tasks-api-handson リポジトリとの連携だけを解除したいケースもあります。その場合は、エージェントスペース詳細画面の 「コードレビュー」タブ で tasks-api-handson を選択し、「機能を管理」 から「コードレビュー」と「ペネトレーションテストの修正」のトグルを 無効化済み に切り替えてください。 |
8.2 カスタムセキュリティ要件の削除(任意)
「参考: 組織セキュリティ要件」セクションで登録した ORM-only database access は 組織レベルの設定 として保存されているため、エージェントスペースを削除しても残ります。残しておいても課金には影響しないので、本番運用に向けて要件を育てていきたい場合はそのまま残して構いません。完全に片付けたい場合は、以下の手順で削除します。
Security Agent コンソールの左メニューから 「セキュリティ要件」 を開き、「カスタムセキュリティ要件」タブ に切り替えます。ORM-only database access の チェックボックスを選択 したうえで、画面右側の 「アクション」プルダウン から 「削除」 をクリックします。

カスタムセキュリティ要件の一覧から該当行が消えていれば削除完了です。
8.3 Tasks API環境の削除(必須)
ペネトレーションテスト用にデプロイしたTasks API環境(CloudFront・ALB・EC2など)は、そのままにしておくと料金が発生し続けます。検証が終わったら必ず削除してください。
AWSマネジメントコンソールで CloudFormation を開き、スタック一覧から tasks-api-handson を選択して、画面右上の 「スタックを削除」 をクリックします。スタックが完全に削除されると、VPC・ALB・EC2・CloudFrontディストリビューションなどすべてのリソースが一括で削除されます。

| 💡 ポイント |
|---|
ドメイン検証のためにALBリスナーへ手動で追加した aws-security-agent-verification ルールは、CloudFormationスタックの外で作成されています。スタック削除時にALBリスナー自体が削除されるので最終的には消えますが、ルールが残っているとリスナー削除時にエラーになることがあるため、事前に手動で外しておくのが安全 です。EC2コンソール → ロードバランサー → tasks-api-alb → リスナーとルール → ルール一覧から aws-security-agent-verification を選択して削除してください。 |
| ⚠️ CloudFrontの削除には時間がかかる |
|---|
| CloudFrontディストリビューションは、CloudFormationが内部的に「無効化 → 全エッジロケーションへの伝搬待ち → 削除」という流れで処理するため、スタック削除に15〜30分程度 かかる場合があります。途中で「削除中」のまま長時間止まって見えてもエラーではありません。気長に待つか、別の作業を進めながら完了を待ってください。 |
スタックのステータスが DELETE_COMPLETE になったら、Tasks API環境の削除は完了です。
8.4 Privateリポジトリの削除(任意)
フェーズ2で作成した tasks-api-handson リポジトリは、ハンズオン用のため後片付けの観点では削除しておくのが望ましいです。継続して別の検証に使う場合はそのまま残しても構いません。GitHubの該当リポジトリの Settings → Danger Zone → Delete this repository から削除できます。
9. まとめ
この章では、AWS Security Agentを使った次世代の統合セキュリティレビューを体験しました。
- AWS Security Agentを初期セットアップし、最初のエージェントスペースを作成できる
- 事前準備でダウンロードしたzipを起点に、設計書・ソースコード・稼働環境の3つを同じアプリケーション(Tasks API)で一貫して扱える
- 設計ドキュメントをアップロードし、AIが設計段階でセキュリティ問題を指摘する設計レビューを組み込める
- GitHub連携とコードレビュー設定により、プルリクエストに対してAIが自動でセキュリティレビューを行う運用にできる
- Tasks APIをCloudFormationでデプロイし、ドメイン検証を経てペネトレーションテストを有効化することで、稼働中のアプリケーションに対してAIエージェントによるペネトレーションテストを実行できる
- SQLインジェクション・IDOR・認証バイパス・認可の不備などの脆弱性を、実際に攻撃を再現する形で検出できる
- 単独では中程度のFindingsを、Security Agentのコンテキスト横断分析によって致命的な攻撃チェーンとして扱える
- エージェントスペース・Tasks API環境の削除まで含めて、不要リソースを後片付けできる
本講座の前半で扱ったBandit(SAST)・OWASP ZAP(DAST)・Checkov(IaC scanning)などの個別ツールは、それぞれの役割に特化した強力なツールです。一方、AWS Security AgentはこれらをAIエージェントに統合した次世代のセキュリティプラットフォームで、特に設計書・コード・稼働環境を1つのアプリケーションコンテキストとして横断分析できる 点と、ペネトレーションテストのコストを大幅に下げる点で革新的です。従来は外部ベンダ依頼で1回数百万円が相場でしたが、AWS Security Agentでは $50/task-hour の従量課金(小〜中規模のAPIなら1回あたり$400〜$600程度)で実行できます。実運用ではコスト管理(テストの実行頻度・スコープ設定)と従来ツール(Bandit・ZAP等)との併用戦略が重要になります。
これでDevSecOps講座は一通り終了です。ここまでで、Shift Leftの考え方を土台に、SAST・SCA・DAST・IaCスキャン・コンテナ・ランタイム・AI統合レビューまで、開発から運用までを多層的にカバーするDevSecOpsの基本を身につけました。
| 💡 ポイント |
|---|
| AWS Security Agent でコストは大幅に下がりましたが、1回あたり $400〜$600 の従量課金が発生するため、「いつ・何に対して実行するか」の戦略 が実運用では重要になります。「便利だから毎日回す」というアプローチは現実的ではなく、リスクの大きさに応じて頻度と対象を絞るのが基本です。 いつ実施するか - 新規リリース時:本番公開前に必ず実施。設計・コードレビューでは検出できない動的な脆弱性や攻撃チェーンを潰す - 定期実行(年1回程度):依存ライブラリの脆弱性蓄積、新たな攻撃手法への耐性を再評価 - 大きめのリリース時:認証基盤の刷新、外部API公開化、決済機能追加など、攻撃面が変わる変更があったタイミング - アーキテクチャ変更後:マイクロサービス化、新クラウドサービス採用、ミドルウェア更新など - セキュリティインシデント発生後:再発防止策の有効性確認 - 依存ライブラリ・フレームワークに重大な脆弱性が出た後:自分たちの実装で本当に防げているかを確認 - コンプライアンス監査の前:PCI DSS / ISO 27001 / SOC 2 等の維持に必要なケース 優先度が高い対象システム(定期的にしっかり実施したい) - 個人情報を扱うシステム(個人情報保護法・GDPR等の法令遵守、漏えい時のレピュテーションリスク) - 決済情報・金融情報を扱うシステム(PCI DSS 等の規制対象になりやすい) - 認証・認可システム(突破されると他システムへの侵入起点になる) - インターネット越しに不特定多数からアクセスされるシステム(攻撃面が広い) - 停止したときのインパクトが大きいシステム(可用性が事業継続に直結) - 規制業種(医療・金融・公共)に該当するシステム 優先度が下がる対象システム(年1回程度の確認に絞る候補) - 社内限定で外部から到達できないシステム - 停止してもインパクトが小さい補助系システム ただし、「優先度が下がる」≠「不要」 です。社内限定システムにも、内部不正リスク(社員による悪意ある操作)、侵入後の横移動の起点(外部攻撃で別システムが破られた後のラテラルムーブメント)、委託先・退職者経由のアクセスリスクが存在します。完全にやらないのではなく、頻度を年1回程度に下げる、という運用が安全です。 コスト管理のコツ - 手順1の 「リスクタイプを除外する」 で範囲を絞れば task-hour が短縮され料金も下がる - 手順1の 「範囲外のURL」 で破壊的操作のパスを除外して、想定外のデータ操作と実行時間の両方を抑える - 本番ではなく ステージング環境 で実施し、本番への影響を回避する - AWS Budgets でアラートを仕掛けて、予算超過時に即時通知を受け取る |