Amazon Web Services ブログ

AI を活用した脆弱性検出ハーネス (パート 2 設定編): ステアリングファイルで実現する証拠ベースの脆弱性トリアージ

本ブログは 2026 年 10 月 7 日に公開された AWS Blog “Configuring your AI vulnerability harness, Part 2: The steering file” を翻訳したものです。

この記事では、AI モデルを設定し、経験豊富なセキュリティアナリストと同等の一貫性で、構造化された証拠ベースの脆弱性トリアージを実行させる方法を紹介します。すべての分析セッションで構造的検証、証拠ベースのスコアリング、インフラストラクチャを考慮した優先順位付けを徹底させる 5 つの設定セクションを取り上げ、それぞれの設計上の判断を解説します。アーキテクチャについてはパート 1 の記事「3 層パイプラインによる検出結果の絞り込み」で解説しました。この記事では設定を解説します。

この違いが重要なのは、同じフロンティアモデルでも、ある指示では厳密で証拠に基づいたセキュリティ評価を生成する一方で、別の指示ではハルシネーションによる攻撃チェーンや過大な重大度評価を生成してしまうからです。モデルの能力は変わりません。設定によって変えられるのは、モデルの判断です。

ハーネスを構築する中で、私たちはこのことを痛感しました。初期のイテレーションでは、一見もっともらしいものの、精査すると破綻してしまう検出結果が生成されていました。モデルは、存在しない関数で SQL インジェクションを報告したり、構造的な根拠が何もないまま HIGH の信頼度を主張したり、リクエストパス上にブロッキングモードで直接配置されている AWS WAF を無視したりしました。そのままの出力では、エンジニアリングチームの信頼は得られなかったでしょう。

解決策は、より優れたモデルではなく、モデルをより適切に方向付けることでした。

ステアリングファイルとは

ステアリングファイルとは、AI コーディングアシスタントがすべてのセッションの開始時に読み込む一連の指示です。規約はツールによって異なります。Kiro は .kiro/steering/ ディレクトリから Markdown ファイルを読み込みます。Claude Code は CLAUDE.md、Cursor は .cursorrules、GitHub Copilot は .github/copilot-instructions.md を使用します。ただし、役割はどれも同じで、リポジトリでの作業にモデルがどう取り組むかを方向付ける永続的な指示です。

セキュリティ分析に応用すると、ステアリングファイルはチームのトリアージ手法を機械で実行可能な指示としてエンコードします。個々のエンジニアが手法を一貫して適用することに頼る必要はありません。一度エンコードすれば、モデルがすべての分析に同じ手法を適用します。

今回公開するステアリングファイルは、ハーネスの記事で説明したアーキテクチャの原則を、運用上の指示としてエンコードしたものです。ハーネスの記事で apply infrastructure-aware assessment (インフラストラクチャを考慮した評価を適用する) と述べている部分について、ステアリングファイルでは具体的な方法を明示しています。どのコントロールにどの乗数を対応させるか、乗数をどのように掛け合わせるか、単一のコントロールへの過信を防ぐ下限値をいくつにするかを規定しています。

設定がプロンプトより優れている理由

シングルターンのプロンプト (find vulnerabilities in this code: このコード内の脆弱性を見つけて) では、モデルはデフォルトの動作のまま出力を生成します。そのデフォルトは、厳密さではなく有用性を重視して最適化されています。何かを見つけるよう依頼されたので、モデルは報告できるものを見つけようとするのです。

ステアリングファイルは、このデフォルトを変更します。具体的には、次の点を定めます。

  • 証拠とみなすもの: 明示的な指示がない場合、モデルは自らの推論を十分な証拠として扱います。ステアリングファイルでは、検出結果を報告する前に、構造的検証 (データフローの確認、関数の存在確認、呼び出しパスの確認) を必須としています。
  • 信頼度の意味: 指示がなければ、モデルは自らの説明が自分にとってどれだけもっともらしく思えるかに基づいて信頼度を割り当てます。ステアリングファイルでは、自己申告の信頼度を、二値の構造的シグナルから計算する式に置き換えます。テイント分析でフローが確認できるか、できないか。コールグラフがエントリポイントからシンクまでつながっているか、いないか。判定はどちらかしかありません。
  • インフラストラクチャが優先度に与える影響: デフォルトのままでは、モデルは脆弱性をデプロイのコンテキストから切り離して評価します。ステアリングファイルでは、優先度を割り当てる前に Infrastructure as Code (IaC) を解析し、コントロールごとの乗数を適用することを必須としています。

目指しているのは再現性です。誰がいつ分析を実行しても、同じコードベースからは同じ評価済みの検出結果が得られるべきです。重要なのは一貫性です。

重要な 5 つのセクション

ステアリングファイルの全文は、関連リポジトリで公開しています。ここでは、特に重要な 5 つのセクションについて、その設計上の判断を説明します。

LLM を信頼するのではなく構造的に検証する

Never trust an LLM's self-reported confidence about a vulnerability.
Verify claims against the code structure:
1. Do referenced files exist?
2. Do referenced functions exist?
3. Does dataflow confirm the claim?
4. Is there a call path?

If a finding fails all structural checks, reject it regardless of how
convincing the narrative sounds.

これは、ファイル内で最も重要な指示です。この指示がないと、モデルはもっともらしい攻撃チェーンを生成してしまいます。しかし、その攻撃チェーンが参照しているのは、3 コミット前に名前が変更された関数、別のパッケージにあるファイル、あるいはモデルが見落としたサニタイズ処理を通過するデータフローです。

検証したところ、ステアリングなしのモデルによる検出結果の約 30% が、対象リポジトリに存在しないコード構造を参照していました。解釈の誤りではなく、完全に捏造されたパスです。報告前に検証するよう指示したところ、テストでは捏造されたパスはゼロになりました。

ここで重要なのは、セキュリティ分析におけるハルシネーションは些細な問題では済まないという点です。ハルシネーションによる検出結果が 1 件でも開発者に届けば、パイプライン全体の信頼性は急速に損なわれます。捏造された脆弱性を目にしたエンジニアは、その後レポートを読まなくなる可能性が高くなります。

証拠ベースの信頼度スコアリング

次の式は、モデルの直感的な信頼度を、観測可能なシグナルから計算するスコアに置き換えるものです。各要素は二値で、確認済みか未確認かのどちらかです。

confidence = 0.30 * taint_confirms_flow
           + 0.25 * no_sanitization_found
           + 0.20 * entry_point_is_public
           + 0.15 * call_graph_confirms_path
           + 0.10 * sink_type_matches_category

テイントの確認に最も高い重み (0.30) を設定したのは、確認済みのデータフローパス (ユーザーが制御するデータがセキュリティ上重要な操作に到達するという証拠) が、検出結果が本物であることを示す最も有力な予測因子だからです。脆弱性が既知のアプリケーションを対象とした検証では、テイントが確認され、かつサニタイズが見つからなかった検出結果は、89% が悪用可能でした。一方、構造的な確認なしにモデルが HIGH confidence (HIGH の信頼度) と報告した検出結果のうち、悪用可能だったのは 34% にとどまりました。

この式はあくまで出発点であり、固定された標準ではありません。重みには、チーム独自の検証データを反映させてください。既知の真陽性と偽陽性をラベル付けしたデータセットに対してこの式を実行し、適合率 (precision) がチームのノイズ許容度に合うまで調整します。

インフラストラクチャを考慮した評価

このセクションは、よくある過剰な優先順位付け、つまり補完的コントロールが既に導入されているにもかかわらず、脆弱性を緩和前の重大度のまま報告してしまう問題に対処するものです。

score_after_controls = max(0.15, score * block_1 * block_2 * ... * block_n)

コントロールは、特定の脆弱性クラスにマッピングされます。SQL インジェクションルールをブロッキングモードで適用した AWS WAF は、SQL インジェクションに対しては STRONG コントロール (乗数 0.25 倍) ですが、デシリアライゼーション攻撃には効果がありません。ステアリングファイルでは、このマッピングをモデルに推測させるのではなく、明示的に規定しています。

攻撃ブロック型コントロールの乗数を掛け合わせ、下限値を 0.15 とすることで、多層防御の考え方をエンコードしています。複数のコントロールを組み合わせれば単一のコントロールよりもリスクは下がりますが、どのような組み合わせでもリスクがゼロになることはありません。下限値を設けることで、脆弱性が完全に緩和されたので無視してよい、とモデルが結論付けるのを防ぎます。

検証を通じてわかった注意点があります。アクセスコントロール (認証と認可) と攻撃ブロック型コントロール (AWS WAF ルールと入力検証) は、果たす役割が異なります。認証が制限するのは、誰がエクスプロイトを試みられるかです。認証済みのユーザーがエクスプロイトを試みたときに何が起こるかまでは制限しません。AWS Identity and Access Management (IAM) の認証で保護されていても、コマンドインジェクションはコマンドインジェクションです。攻撃者の母数は小さくなりますが、悪用されたときの影響は変わりません。ステアリングファイルでは、一律の乗数を適用するのではなく、コントロールの種類ごとに特定のスコア構成要素へマッピングすることで、この違いを反映しています。

脅威インテリジェンスの統合

ステアリングファイルでは、CISA Known Exploited Vulnerabilities (KEV) カタログと Exploit Prediction Scoring System (EPSS) のシグナルを取り入れ、脅威インテリジェンスが現実的な悪用リスクを示す場合に優先度を引き上げます。

次の表に、ステアリングファイルが認識する主なシグナルと、各シグナルが検出結果のスコアに与えるブーストを示します。各シグナルは、実環境での悪用リスクについて、それぞれ異なる観点から答えを提供します。

  • CISA KEV – 攻撃者が実環境でその脆弱性を悪用したことを示し、ランサムウェアキャンペーンとの関連の有無も示します。
  • EPSS – 今後 30 日以内に攻撃者がその脆弱性を悪用する確率を推定します。
  • 公開されている概念実証 (PoC) – 動作するエクスプロイトコードが既に公開されており、攻撃者にとって残りの作業がほとんどないことを示します。
シグナル ブースト
悪用が確認されている (CISA KEV) +0.30
ランサムウェアとの関連あり (CISA KEV) +0.15
EPSS >= 0.5 +0.20
公開 PoC あり +0.10

脅威インテリジェンスがスコアの大半を占めてしまわないよう、ブーストの合計には +0.50 の上限を設けています。攻撃者に狙われているからといって、脆弱性が技術的に悪用しやすくなるわけではありません。しかし、理論上悪用可能な状態から実際に悪用される状態までの期間は非常に短い場合があるため、緊急度は高くなります。

緊急度と重大度は、意図的に区別しています。重大度が中程度の依存関係の脆弱性であっても、ランサムウェアグループに実際に悪用されているのであれば、複雑な前提条件が必要で既知のツールも存在しない、重大度がクリティカルのコードレベルの検出結果よりも迅速に対応する必要があります。

優先度分類

スコアリングで得られるのは数値であり、優先度分類はその数値を判断に変換します。検出結果を受け取る開発者が必要としているのは、この判断です。

次の表は、ステアリングファイルで定義している 4 つのアクション階層を示しています。スコアと証拠のしきい値によって検出結果が該当する階層が決まり、階層ごとに具体的な対応が規定されています。ステアリングファイルでは、これらのしきい値を最終スコアと比較します。最終スコアとは、ベーススコアに攻撃ブロック型コントロールの乗数と、該当する場合は脅威インテリジェンスのブーストを適用した後のスコアです。この記事の前半で紹介した式による信頼度の値でも、スキャナーが報告した重大度でもない点に注意してください。

優先度 基準 アクション
P0 スコア >= 0.8、効果的な攻撃ブロック型の緩和策なし 直ちに修正
P1 スコア >= 0.6 または現実的な悪用リスクを示す脅威インテリジェンスあり 今回のスプリントで修正
P2 スコア >= 0.4、部分的な証拠あり 対応余力があるときに調査
P3 スコア < 0.4 または効果的に緩和済み リスクを受容、またはバックログに追加

ファイル内で最も議論を呼ぶ指示は、Do not file P3 findings as security issues. (P3 の検出結果をセキュリティ課題として起票しない) です。この指示を含めたのは、信頼度の低い検出結果や完全に緩和済みの検出結果までチケットとして起票すると、チームがセキュリティツールを無視するようになるからです。偽陽性や無関係な検出結果がバグとして起票されるたびに、システムの出力に対する関心は薄れていきます。確認済みの検出結果を 10 件出すパイプラインの方が、確証のない検出結果を 200 件出すパイプラインよりも、エンジニアリングチームの注目を集めます。

検証結果

既知の脆弱性を 10 件 (悪用可能なもの 8 件と、インフラストラクチャのコントロールで緩和されているもの 2 件) 含む、検証専用の脆弱なアプリケーションを使ってステアリングファイルをテストしました。このアプリケーションには、SQL インジェクションルールをブロッキングモードで適用した AWS WAF、Amazon Virtual Private Cloud (Amazon VPC) で分離された AWS Lambda 関数、各エンドポイントでの IAM 認証が含まれています。

  • ステアリングファイルなしの場合、モデルは 10 件の脆弱性をすべて検出し、緩和済みの 2 件を正しく低い優先度と判断しました。しかし、重大度は証拠ではなく直感 (this is a command injection, so it’s CRITICAL: これはコマンドインジェクションなので CRITICAL) に基づいて割り当てられ、主張に対する構造的検証も行われませんでした。
  • ステアリングファイルありの場合、モデルは 10 件中 9 件の脆弱性を検出しました (検出しなかったのは、単体テストのコードに意図的に埋め込まれ、定義されているものの呼び出されていないハードコードされた認証情報です)。さらに、緩和済みの 2 件の検出結果を、根拠を文書化したうえで正しく P3 に引き下げ、各検出結果の信頼度の計算過程を示し、主張した各データフローを実際のコードと照合して検証しました。

スコアリングのキャリブレーションには、1 回のイテレーションが必要でした。初期バージョンでは認証を一律の乗数として適用していたため、影響の大きさにかかわらず、IAM で保護されたすべての検出結果が P2 に抑えられていました。そこで、アクセス制限型コントロール (到達可能性のスコア構成要素を低減) と攻撃ブロック型コントロール (信頼度スコア全体を低減) を分けて扱うように修正しました。現在のバージョンでは、IAM 認証で保護されたコマンドインジェクションを正しく P0 に分類します。認証によって到達できるユーザーは限られますが、悪用された場合の影響はリモートコード実行であることに変わりはないからです。

ステアリングファイルの使用方法

ここでは 3 つのオプションを紹介します。常時有効な Kiro のステアリングファイルとして使う方法、同じ内容をオンデマンドで使える Kiro のスキルとして使う方法、そして同じ内容を Claude Code などのアシスタントで利用する方法です。

オプション 1: Kiro のステアリングファイルとして使用する

ステアリングファイルを、リポジトリの .kiro/steering/vuln-triage.md に配置します。Kiro の組み込みのデフォルトエージェントを使用するセッションでは、指示が自動的に読み込まれます。コードのセキュリティ問題の分析をモデルに依頼すると、追加のプロンプトなしでこの手法が適用されます。

デフォルトではなくカスタムエージェントを使用している場合、ステアリングファイルは自動的に読み込まれません。エージェントの resources にファイルを明示的に追加する必要があります。

{
    "resources": ["file://.kiro/steering/**/*.md"]
}

your-repo/
├── .kiro/
│   └── steering/
│       └── vuln-triage.md   ← steering file
├── src/
├── cdk/
└── ...

また、~/.kiro/steering/ に配置すると、単一のリポジトリだけでなく、マシン上のすべてのワークスペースにこの手法を適用できます。

オプション 2: Kiro のスキルとして使用する

毎ターンでコンテキストウィンドウを消費するのではなく、必要なときにだけこの手法を使いたい場合は、スキルとして配置します。Kiro は起動時にスキルの名前と説明だけを読み込み、スキルが有効化された時点で指示の全文を取り込みます。そのため、関係のない会話に指示が入り込むことはありません。

スキルは、SKILL.md ファイルを含むフォルダです。フォルダ名は、YAML フロントマターの name と一致させる必要があります。

name: vuln-triage
description: Structured vulnerability triage methodology with evidence-based scoring and infrastructure-aware prioritization. Use when analyzing code for security vulnerabilities.

your-repo/
├── .kiro/
│   └── skills/
│       └── vuln-triage/
│           └── SKILL.md   ← skill file
├── src/
└── ...

Kiro のデフォルトエージェントは .kiro/skills/ 内のスキルを自動的に検出するため、設定は不要です。スキルは、Kiro がリクエストと説明を照合して合致すると判断したときに自動的に有効化されるか、スラッシュコマンドで明示的に有効化されます。vuln-triage という名前のスキルは /vuln-triage として呼び出せるため、エンジニアは必要なときに評価を実行できます。

> /vuln-triage focus on the authentication changes

スキルを ~/.kiro/skills/ に配置すると、マシン上のすべてのプロジェクトで使用できます。デフォルトではなくカスタムエージェントを使用している場合、スキルは自動的に読み込まれないため、エージェントのリソース (resources) にスキルを追加する必要があります。

{

	"resources": ["skill://.kiro/skills/*/SKILL.md"]

}

オプション 3: 他のツール向けに適応させる

この手法は Kiro 専用ではありません。リポジトリには、同じ内容を Claude Code 用の CLAUDE.md ファイルとしても収録しています。また、この原則は、リポジトリから永続的な指示を読み込むアシスタントであれば、どれにでも適用できます。想定されるファイル名と配置場所については、各ツールのドキュメントを参照してください。

ステアリングファイルでは代替できないもの

ステアリングファイルが提供するのは手法であり、それを実行する仕組みではありません。検出結果についてどう考えるかをモデルに指示しますが、次の機能は提供しません。

  • プログラムによるテイント追跡: モデルは、コードを読んでデータフローを推定します。一方、専用のテイントトラッカーは、抽象構文木 (AST) に基づいてデータフローを決定論的に確認します。Python のコードベースであれば、Tree-Sitter などのパーサーを基盤とした静的解析ツールでこれを実現できます。それ以外の言語では、モデルによる推定は妥当ではあるものの、確実な根拠にはなりません。
  • 稼働中のインフラストラクチャの検証: ステアリングファイルは、IaC ファイルを解析するようモデルに指示します。しかし、API コールを実行して、デプロイ済みの環境で AWS WAF ルールが Amazon API Gateway にアタッチされていることや、デプロイ後にセキュリティグループが変更されていないことまでは検証できません。
  • 脅威インテリジェンスフィード: このファイルは、CISA KEV と EPSS のデータを考慮するようモデルに指示します。モデルのトレーニングデータには過去の KEV エントリが含まれていますが、ライブフィードを照会することはできません。最新の悪用状況を把握するには、API 統合が必要です。
  • 実行ベースの検証: ステアリングファイルで得られるのは、評価済みの検出結果です。稼働中の環境に対して PoC を実行し、悪用可能性を確認するには、サンドボックス、リクエスト署名、差分テスト用のインフラストラクチャといった追加のツールが必要です。

これらの機能を加えるごとに、パイプラインの信頼性は高まります。ただし、これらの機能がなくても、ステアリングファイルを使えば、ステアリングなしのモデルと比べて定量的にも優れた結果が得られます。構造化された検出結果、引用された証拠、インフラストラクチャを考慮した優先順位付けです。とはいえ、ステアリングファイルは成熟したハーネスの最初のレイヤーにすぎず、システム全体ではありません。

次のステップ

ステアリングファイルを使えば、AI を活用した脆弱性トリアージのための構造化された手法を、今すぐチームに導入できます。既存のツールでそのまま動作し、インフラストラクチャの変更も、新しいサービスも、調達プロセスも必要ありません。

ステアリングファイルは GitHub リポジトリで公開しています。ぜひ実際に使用し、環境に合わせて調整して、気付いた点をお知らせください。

著者らは、AWS でセキュリティの自動化に取り組んでいます。ここで紹介したパターンは、複数のチームとデプロイ環境で、AI を活用した脆弱性検出システムを構築、検証する中で生まれたものです。


justin kontny

Justin Kontny

Justin は AWS の Senior Software Engineer, Security で、ソフトウェア開発への情熱とクラウドセキュリティに関する深い専門知識を兼ね備えています。AI-Driven Development Lifecycle (AIDLC) のプラクティスを用いたエージェンティックなセキュリティソリューションの構築に注力し、セキュリティを障壁からビジネスを後押しするものへと変えることに取り組んでいます。仕事以外では、子どもたちと過ごしたり、アウトドアで体を動かしたりすることを楽しんでいます。

Ievgeniia Ieromenko

Ievgeniia Ieromenko

Ievgeniia は AWS の Software Development Engineer です。デリバリーを遅らせることなくセキュリティポスチャを強化するためのツールやエージェンティック AI システムを構築しています。仕事以外では、旅行やボランティア活動、そしてとてもお利口な愛犬 Pickle とのアウトドアでの冒険を楽しんでいます。

nidhi ramakant

Nidhi Ramakant

Nidhi は AWS の Software Development Manager で、セキュリティとエンタープライズアーキテクチャの分野で 20 年の経験があります。お客様が環境をセキュアに保てるよう支援することや、セキュリティ上の意思決定を容易にする創造的なソリューションを構築することに情熱を注いでいます。また、周囲の人材育成にも同じように力を入れています。仕事以外では、番組を一気見したり、子どもたちが安全に探求し学べるよう、セキュアなローカル LLM 向けのアプリをバイブコーディングしたりしています。

本ブログは Security Solutions Architect の 中島 章博 が翻訳しました。