こんにちは!PSIRT red team の kaworu と yusui です。4月に公開した脆弱性診断 with AIエージェント、はじめました。では、 AIエージェントを利用した脆弱性診断内製化について紹介しました。
約3ヶ月が経過し、記事で目標に掲げていた「開発のタイミングでAIエージェントによる脆弱性診断を実施し、結果に問題がなければそのままリリース」が実現し、開発チームでの脆弱性診断がついにひろがってきました! 本記事では、実際に開発チームに展開されるまでと、工夫点をまとめました。
展開した脆弱性診断 with AIエージェント
4月の記事から、以下のような変化がありました!
- AIエージェント……Cline から Roo Code へ
- 診断ナレッジを渡す方法……Memory Bank から freee 社内の MCP server へ

Cline → Roo Code
4月の記事ではClineを利用した脆弱性診断を紹介しましたが、実は並行してRoo Codeでの検証も進めていました。 Roo Codeには3月ごろからサブタスク機能*1と、Orchestration Modeと呼ばれる、複数のAIエージェントの連携や制御の仕組みが実装されていました。これらを利用することで、複数の脆弱性診断タスクの流れを柔軟に自然言語でカスタマイズできるようになりました。
脆弱性診断で利用するAIエージェントの方針として、自分たちでエージェントを作り込むより、モデルの進化や最新のアーキテクチャに柔軟に対応し、進化の恩恵を積極的に取り込んでいきたいと考えています。この方針にちょうどよかったため、AIエージェントをClineからRoo Codeに切り替えました。
Roo Code では Custom mode を用いて、役割に特化したエージェントを定義できます。この Custom mode に、脆弱性診断に特化した「診断モード」を定義しました。1APIずつプロンプトでの診断を指示するのではなく、複数のAPIをまとめて指示しても、orchestratorが適切なタスクに分割して診断を実施してくれるようになりました!
Memory Bank → 社内の MCP Server
脆弱性診断の精度を向上させるにはいくつかのポイントがありますが、中でもfreee固有のナレッジをLLMに渡すことは特に重要だと考えています。4月の記事ではMemory Bankを使った方法を紹介しましたが、Memory Bankの実態はMarkdownファイルの集合であり、これをどうやってエンジニアに展開し、今後メンテナンスしていくかが課題でした。
そんななか、MCP Server の存在が広がり、freeeでもこれを活用していく流れになりました。社内ツールとして、社内標準の MCP Server 群をまとめて扱えるツールが開発されました。MCP Server を簡単に起動したり、必要な設定を手軽にできるようになっています。これに目をつけて、脆弱性診断に利用する固有のナレッジを社内の MCP serverとして実装しました。
これで、エンジニアの環境に自然と展開され、ナレッジの更新もコマンド1行で完了します。
開発チームへの展開
6月中旬ごろから、脆弱性診断 AIエージェントの開発チーム展開が始まりました。 ちょうど社内でClineの全社展開がすすんでおり、AIエージェント利用の土台が整っていたことから、非常に順調なスタートでした。
そして、かねてからの課題であった、脆弱性診断のスケジュールの調整の煩雑さや、PSIRTへ脆弱性診断依頼により待たせてしまう、開発速度を阻害するといったことが、大きく改善されました。

今後は、開発チームやエンジニア自身が、それぞれのスケジュールや都合に合わせて、いつでも脆弱性診断を実施できるようになります。開発の目処が立ったタイミングで診断エージェントを実行することで、従来の診断よりもかなり早い段階で脆弱性を検出し、修正と、いわゆるSHIFT LEFTが進みました。
AIエージェントがほとんどの作業をやってくれるとはいえ、検出結果の確認は開発チームやエンジニアにもお願いしています。開発チームやエンジニアが肯定的な反応をしてくれたこと、ときには楽しみながら診断をかけてくれることに感謝しかありません。
工夫した点
品質・精度
4月〜6月の脆弱性診断の対象に対し、とにかく実践投入しながら*2、最適な形を探っていきました。最終的に、モデルの進化によって解決した部分と、それでもどうにもならなかった部分が明確になりました。後者については、開発チーム展開後もPSIRTで軽量な診断を行っています。
診断レポートの使いやすさ
AIエージェントによる脆弱性診断の結果は、全てJiraチケットに出力するようにしました。これは、開発チームの多くがJiraチケットで課題管理をしているため使い勝手が良いと考えたことと、これまでの脆弱性診断の管理もJiraで行ってきた経緯があるためです。
診断対象を管理するJiraチケットから、具体的な結果チケットを確認できるような構成にしています。 結果チケットの種別は3つあり、それぞれ以下のような工夫をしました。
| 結果チケットの種類 | 工夫点 |
|---|---|
| 脆弱性診断結果レポート | AIエージェントが「どこまでは診断できたのか」「どこは診断(コード分析)できていないのか」を正直に書かせる欄を作る |
| コード分析結果レポート | 人間が後から理解・追跡しやすいように、関連するコードの概要とファイルパスや行数などを出力させる |
| 検出事項詳細 | 「どこのコードがなぜ問題なのか」「どういう修正案があるのか」まで具体的に出力させる。(それぞれ、具体的なコードスニペットも出力させる) |
次の課題
直近はレビューの体制のアップデートを検討しています。
従来の内部脆弱診断では、診断作業を担当したPSIRTメンバーと、それ以外のメンバーによる最低2名でのチェック体制を設けていました*3。 AIエージェントによる脆弱性診断においても、変わらず、現状でも最低2名の人の目が入るようにしてます。具体的には、開発チームメンバーが結果チケットを確認した上で、PSIRTが最終レビューを行う体制です。
おわりに
この取り組みは、かねてよりの私たちの理想がようやく形になったものでした。私たちはこれまでも、脆弱性診断がブロッカーにならないようにしたい、より開発フローの前段階で脆弱性を検出し修正に繋げたいと考えて、折々で改善の施策を行ってきました。部分的にうまくいったこともあれば、成果につながらなかったものもあります。
脆弱性診断 with AIエージェントの構想が出てきたのは2025年の1月ごろで、そこからは半年、4月の記事から3ヶ月が経過しました。AIエージェントをとりまく状況が日々変化していて、「これで展開しましょう!」の判断が難しい取り組みでした。 5月中頃ごろには、さらに精度が出せそう、使いやすくできそう、といった状況でしたが、過去の経験を踏まえて「でもまずは、開発チームに使ってもらって意見をもらおう。うちの脆弱性診断 with AIエージェントは、いまはこれ!」を決めたことも、ポイントだったように考えています。
*1:https://github.com/RooCodeInc/Roo-Code/blob/HEAD/CHANGELOG.md#381---2025-03-07
*2:閑話ですが、ナレッジの中身を調整しながら、AIエージェントの脆弱性診断を続けた結果、yusuiは一時期、社内のトークン利用数において大差をつけて1位の日々が続きました。「開発でAIを活用している人から話を聞こう」というコンセプトの企画では「諸事情により今回は2位の人に発表してもらいます」という話があったことも。
*3:明示的に2名としているだけで、診断に携わるメンバー複数名でわいわいと目を通す診断対象もしばしばあります。日々プロダクトの挙動やコードについて楽しく向き合っています。
