脆弱性スキャンをCI/CDに組み込んでも、「どこで止めるか」を設計しないまま運用を始めると、スキャンは形式的な通過儀礼に終わる。ビルドで落とすべき指摘と受容して先へ進む指摘の判断基準を設計段階で定め、稼働後の監視と役割を分けて持たせることが、実効性のあるスキャン運用の出発点になる。ツールを入れることと、スキャン結果に基づいて判断できる状態を作ることは別の問題であり、この記事ではその設計判断を整理する。
リリース直前にスキャンを回して止める判断ができない構造
スキャンが「形式」に留まる設計の問題
脆弱性スキャンを導入した現場でも、リリース直前になって初めてスキャンを実行し、大量の指摘が出た状態でリリースを強行するケースは珍しくない。現場では「スキャンは回しているが、その結果をどう扱うかルールがない」という話をよく聞く。スキャン結果がSlackに流れるだけで、誰も止める権限と基準を持っていない状態では、ツールは導入されても機能していない。問題の核心は、「検知」と「判断」が分離していないことにある。検知はツールが行うが、判断は人が設計する必要がある。この設計がなければ、スキャンはレポートを生成するだけの儀礼に留まり続ける。
検知から判断までのフローが定義されていない
スキャンが指摘を出した後、誰が何を基準に「止める/進める」を決めるか。この判断フローが未定義のまま運用を始めると、担当者ごとに判断が異なり、同じ重大度の脆弱性でもリリースできたりできなかったりという非一貫性が生まれる。ある現場では本番環境50台以上のイメージに高重大度の指摘が蓄積し続け、誰も止める基準がなかったために6か月以上放置された。フローの未定義は個人の判断に責任を押しつける構造を生み、結果として「見て見ぬふり」を組織的に再生産する。スキャン組み込みの設計は、まずこの判断フローを定義することから始めなければならない。
リリース直前という配置自体が問題を生む
スキャンをリリース直前だけに配置する設計には構造的な欠陥がある。リリース直前の段階ではコードもイメージも固まっており、指摘が出ても修正コストが最大になっている。開発フローの上流、具体的にはコードのpush時やイメージのビルド時にスキャンを配置することで、指摘を早期に発見し修正コストを下げられる。下流に配置されたスキャンは「止める道具」としてしか機能せず、チームに対してネガティブな摩擦だけを生む。上流に配置されたスキャンは「設計の補助線」として機能し、開発者がセキュリティを意識しながら実装を進める文化を支える。配置の判断は、スキャンに何をさせたいかという目的の整理から始まる。
ビルドで落とす指摘と受容して先へ進める指摘の判断
ブロックすべき指摘の条件
すべての指摘をビルドで落とす設計は現実的ではない。ブロックの対象は「現在の環境で実際に悪用可能」かつ「修正手段が存在する」指摘に絞るべきだ。具体的には、CVSSスコアが9.0以上のCritical、かつ既知のExploitが公開されている脆弱性、かつ修正済みバージョンが存在するパッケージ、という3条件を重ねることで即時ブロックの対象を絞り込める。スコアだけで判断すると、自環境で攻撃面が露出していない脆弱性もブロック対象になり、後述する「全件ブロックによる開発停止」に陥るリスクが高まる。ブロック判断の設計は、スコア・Exploit公開状況・修正可能性の3軸で考えるのが実装層の標準的な出発点になる。
受容して先に進む指摘の条件
受容できる指摘は、「現在の攻撃面に露出していない」か「修正手段が存在しない」ケースが中心になる。ネットワーク非接触なコンポーネントの脆弱性、攻撃経路がローカルアクセス限定のもの、ベンダーが修正バージョンを未リリースのものは、ブロックよりも受容と監視の組み合わせが適切な判断になる。受容する場合は必ずトレードオフの記録を残す。「この指摘を知った上でリリースする」という意思決定の証跡がなければ、後から監査を受けたとき「見落とした」と「受容した」の区別がつかない。受容の記録は、次の例外管理設計と連動させることで初めて機能する。
判断の属人化を防ぐルール設計
ブロックと受容の判断基準を文書化せずに運用すると、担当者が変わるたびに基準がリセットされる。現場では「前の担当者はこの指摘を通していた」「自分は通せない」という混乱が起きやすい。判断基準はコードと同じリポジトリにポリシーファイルとして管理し、レビューと承認のプロセスを経て変更できる状態にすることが望ましい。OPAやConftestあるいはスキャンツール固有のポリシー定義形式を使えば、判断基準をコードとして管理できる。人の判断が必要な領域を最小化し、ルールで自動判定できる範囲を最大化する設計が、スキャン運用の持続性を左右する。
IaCコードスキャン・イメージスキャン・稼働ホストスキャンの比較
スキャンの組み込み位置は大きく3層に分類できる。それぞれ検知できる問題の種類・組み込みタイミング・修正コストが異なる。どれか1つで完結させようとすると必ず死角が生まれるため、3層の役割分担を理解した上で組み合わせを設計する。
| スキャン層 | 検知対象 | 組み込みタイミング | 修正コスト | 代表的ツール例 |
|---|---|---|---|---|
| IaCコードスキャン | 設定ミス・権限過多・暗号化未設定などの構成上の問題 | コードpush / PR作成時 | 低(コード変更のみ) | Checkov、tfsec、Trivy(IaC) |
| イメージスキャン | OSパッケージ・アプリ依存ライブラリのCVE | ビルド完了後・レジストリpush前 | 中(ベースイメージ更新・依存更新) | Trivy、Grype、Snyk Container |
| 稼働ホストスキャン | 稼働中OSの未適用パッチ・設定ドリフト・新規CVE | 定期実行(日次〜週次) | 高(本番への変更を伴う) | OpenVAS、Qualys、Wiz(ランタイム) |
IaCコードスキャンを上流に置く意味
IaCスキャンはコードレビューの段階で実行できるため、修正コストが最も低い。Terraformのセキュリティグループ設定やIAMポリシーの過剰権限を、インフラが実際に作られる前に検知できる点が強みだ。ただし、IaCスキャンはデプロイ後の実態を見ていない。コードが正しくてもデプロイ後のドリフトや手動変更は検知できないため、稼働後の監視と必ず組み合わせる必要がある。上流で拾える問題と下流でしか拾えない問題を区別した上で、スキャン層の配置を決める。
イメージスキャンをゲートとして使う判断
イメージスキャンは、ビルドされたコンテナイメージがレジストリに登録される前の段階に配置することで、脆弱なイメージの流通を防ぐゲートとして機能する。CI上でビルドした直後に実行し、CriticalあるいはHighの閾値を超えた場合にパイプラインを止める設計が最も一般的だ。注意点は、ベースイメージ由来のCVEが大量に検知されるケースで、1回のスキャンで100件以上の指摘が出ることも珍しくない。この量の多さを見てすべてをブロックにすると、次節で述べるパイプライン機能不全を引き起こす。
稼働ホストスキャンを「見張り」として位置づける
稼働ホストスキャンは、ビルド時には存在しなかった新規CVEや、デプロイ後のパッケージ追加、設定ドリフトを検知するために不可欠だ。ビルド時にクリーンだったイメージも、数週間後には新しいCVEが公開されて危険になり得る。稼働ホストスキャンはパイプラインを止める道具ではなく、継続的な監視と通知の仕組みとして設計する。検知した際の対応フロー(誰が何日以内に対応するか)を定義しないと、通知が来ても誰も動かないという状況に行き詰まりやすい。
重大度のどこにしきい値を置いてパイプラインを止めるか
CVSSスコアだけを基準にする危険性
CVSSスコアは汎用的な指標だが、自環境の文脈を考慮しない。スコア7.5のHighでも、該当機能が自環境では使われていなければ実際のリスクは低い。逆にスコア6.0のMediumでも、インターネット公開エンドポイントが直接影響を受けるなら優先度は高くなる。スコアだけで機械的に閾値を引くと、実際には問題のない指摘が大量にブロックを生み出し、開発速度との衝突が起きる。現場で「Criticalのみブロック」に絞ったところ検知件数が激減して運用が安定した事例がある一方、Criticalが0件でもHighが蓄積してインシデントが起きたケースも存在する。スコアは一次フィルタに過ぎないと割り切ることが重要だ。
実装環境のコンテキストを加味したしきい値設計
しきい値設計に組み込むべきコンテキストは主に3つある。第一に攻撃経路(ネットワーク経由か、ローカルアクセスのみか)。第二に攻撃対象の公開範囲(インターネット公開か、VPC内部のみか)。第三にExploitの成熟度(概念実証段階か、実際に悪用されているか)。この3軸を組み合わせると、「CVSSがHighでも攻撃経路がローカルかつVPC内部のみなら受容」「CVSSがMediumでもExploit公開済みかつインターネット公開なら即時ブロック」といった、実態に即した判断ルールを設計できる。これをポリシーコードに落とし込むことで属人的な判断を排除できる。
しきい値を段階的に引き上げる運用設計
スキャン導入直後に厳しいしきい値を設定すると、既存の技術的負債が大量にブロック対象になり、パイプラインが機能不全に陥ることがある。現場では最初の3か月はCriticalのみブロック、その後Highを追加、半年後にExploit公開済みのMediumを追加、という段階的な引き上げアプローチが現実的だ。しきい値の引き上げスケジュールを事前に合意しておくことで、開発チームも心理的に準備できる。急激な変更は回避行動(スキャンを外す、例外を乱発する)を引き出すため、緩やかな移行計画が実効性を高める。
例外登録と再評価期限をどう設計するか
例外登録の申請フロー設計
ブロックをすり抜けるための例外登録は、どんな組織にも必要になる。問題は、例外を「無制限に認める抜け穴」にしないことだ。例外申請には最低限、対象のCVE ID・影響範囲の説明・受容の根拠(攻撃経路が存在しない理由など)・申請者と承認者の記録・再評価期限の5項目を必須にする。これらが揃わない申請は却下する運用を徹底することで、例外が「深く考えずにブロックを回避するための手段」になることを防げる。承認者はセキュリティ担当と開発リードの2名による二者承認方式とすると、判断の質を上げる上で有効だ。
再評価期限の設定と自動失効
例外に再評価期限を設けず永久に有効な例外として運用すると、時間が経つにつれて例外リストが肥大化し、誰も中身を把握できない状態になる。例外の有効期限は最長90日を標準とし、期限到来の2週間前に申請者に通知する仕組みを組み込む設計が現実的だ。期限を過ぎた例外は自動的にブロック扱いに戻るよう設計すると、更新されない例外が自然に淘汰される。再評価の際には最初の申請時と状況が変わっていないかを確認し、変化があればポリシー側を更新するトリガーとして活用する。
例外台帳の管理責任の明確化
例外台帳の管理責任が曖昧だと、更新も削除も行われずに形骸化する。台帳の管理責任はプロジェクト単位またはチーム単位で1名のオーナーを指定し、四半期ごとに棚卸しするサイクルを設計に組み込む。台帳はスプレッドシートではなく、GitリポジトリのYAMLファイルとして管理することで、変更履歴の追跡とレビュープロセスが自然に機能する。例外台帳の棚卸し結果をセキュリティ報告の一部として記録に残すことで、監査対応にも活用できる。
全件ブロックにして開発が回らなくなる境界
過剰ブロックが生む回避行動
スキャンで検知されたすべての指摘をブロックに設定すると、開発チームは必ず回避策を探し始める。スキャンステップをコメントアウトする、スキャン結果を無視するフラグを追加する、スキャン対象外のブランチを使う、といった行動が現場では観測される。過剰なブロックは、セキュリティを強化するどころかスキャンの形骸化を加速させる。構築を任されたある担当者が「全件ブロック」を設定した結果、3週間後には開発チームがスキャンをスキップする非公式の手順を作り上げていた、という事例は教訓として重い。ブロックの設計はセキュリティ要件と開発継続性の両立を前提にしなければならない。
ブロック率の目安と運用限界
実務的な経験則として、スキャン実行ごとのブロック率が20%を超えると開発フローへの摩擦が顕在化し始める。ブロック率が50%を超えると、チームがスキャンを「障害」と認識し、回避行動が組織化されるリスクが高まる。導入初期は既存の技術的負債の影響でブロック率が高くなりがちであり、段階的なしきい値引き上げと並行して、既存の負債を計画的に解消する工数を確保することが欠かせない。3か月で20件以上の例外を登録しなければ回らなかったという話は珍しくなく、例外数が急増しているときはしきい値の見直しサインと捉えるべきだ。
スキャンを「外す」判断が起きる前に設計で予防する
開発チームがスキャンを外すという判断を下す前に、設計段階で予防策を組み込む必要がある。第一の予防策は、スキャン結果の通知と判断フローを開発者にとって使いやすい形にすること。PRコメントへのインライン表示やSlackへのサマリ通知など、結果を「見に行かなくてもわかる」状態にする。第二の予防策は、セキュリティチームと開発チームが定期的にスキャン結果を共同でレビューする場を設けること。月次でも隔週でもよいが、「スキャンが出した結果を一緒に解釈する」文化を育てることが長期的な運用継続の鍵になる。
スキャン組み込み設計チェックリスト
以下の項目は、スキャン組み込みを設計する際の判断の漏れを防ぐための確認リストだ。コマンドの設定手順ではなく、設計判断の観点を整理している。手を動かす実装ステップはセミナーや専門書で補ってほしい。
- スキャン層の選択:IaCスキャン・イメージスキャン・稼働ホストスキャンの3層のうち、どれをいつ組み込むかを決定しているか。
- 組み込みタイミングの設計:スキャンをリリース直前のみに配置していないか。上流(push時・ビルド時)への配置を検討しているか。
- ブロック基準の定義:「即時ブロック」の条件(CVSSスコア・Exploit公開状況・攻撃経路)を文書またはポリシーコードとして定義しているか。
- 受容フローの定義:ブロックせず受容する場合の記録項目(根拠・承認者・期限)が定義されているか。
- しきい値の段階的引き上げ計画:導入初期のしきい値と、3か月後・6か月後の引き上げスケジュールを事前に合意しているか。
- 例外申請の必須項目:CVE ID・影響範囲・受容根拠・承認者・再評価期限の5項目が例外申請に必須になっているか。
- 例外の自動失効:期限を過ぎた例外が自動的にブロック扱いに戻る仕組みが組み込まれているか。
- 例外台帳の管理責任:台帳のオーナーと四半期ごとの棚卸しサイクルが明確になっているか。
- 稼働後スキャンの対応フロー:稼働ホストスキャンが新規CVEを検知した場合の通知先・対応期限・担当者を定義しているか。
- ブロック率のモニタリング:スキャン実行ごとのブロック率を定期確認し、過剰ブロックの兆候を早期に検知できる仕組みがあるか。
- 開発チームとの合意:しきい値と例外フローについて開発チームと事前に合意し、スキャンを回避する動機を設計で減らせているか。
▶ 手を動かして本番まで到達する
設計の型は掴めても、本番でTerraformを通しきる経験は別物です
ここまでの設計判断は、読めば腹に落ちます。ですが「自分の手で本番まで通しきる自信」は、それとは別の話になります。
2日間の集中ハンズオンで、AWS上にIaCで構築しきる経験を持ち帰れます。設計判断を、動くコードと本番環境の手応えに変える場です。
脆弱性スキャンをIaCパイプラインに組み込むTerraformハンズオンへ →
Terraformマスターセミナー|2日間ハンズオンでAWS上にIaCで本番構築