0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

脆弱性対応を「2人のAIエージェント」で分担してみた——Sysdig Secure AI と Claude Code の役割分担を、自宅ラボで実測する

0
Last updated at Posted at 2026-09-16

この記事について

前回の記事では、私(TK)が自宅で運用している小さなKubernetesクラスタの外に新しいサーバを1台立て、その構成管理をAnsible + GitHub + Kubernetes JobでGitOps化するまでを書きました。その結びで「この基盤を前提に、Secure AI・Headless Cloud Securityと組み合わせた、より実践的なワークフローの検証に着手する」と予告しました。

この記事は、その続編です。

テーマは一言でいうと、脆弱性対応という1つの仕事を、2人のAIエージェントがどう分担するのかです。1人はSysdig Secureの中にいるエージェント。もう1人は、私の手元のターミナルで動くClaude Codeです。この2人の「境界線はどこにあるのか」を、想像や仕様書の読み合わせではなく、実際に1件の脆弱性を見つけて直し、直ったことを確認するまでを1周走らせて確かめました。

作業を実行したのは、前回と同じくFalcoya-co-CTO——Claude Codeを使って組み上げたAIエージェントです。調査クエリの発行、優先順位の読み解き、修正版の安全性検証、Issueとプルリクエストの作成、クラスタへの適用、そして結果の再確認まで、手を動かしたのはこのエージェントでした。私がやったのは、承認と方針判断、そして「それは本当にそうなのか」と問い返すことです。この記事の文章自体も、Falcoya-co-CTOとの対話を通じてAIエージェントが書いています。

この記事の数値について: 登場する件数・CVE番号・バージョン・時刻は、すべて2026年9月16日に自宅ラボ環境(Sysdig SaaSの東京リージョンに接続)で実際に取得した実測値です。推測が混じる箇所には (推定) と明記しました。ホスト名やIPアドレスは自宅ラボの構成例として一般化した表記です。

舞台の説明: 自宅には4ノードのKubernetesクラスタがあり、その外側に単体のLinuxサーバが1台あります(前回の記事で構築したサーバです)。今回の主役はクラスタ側で、検証用に隔離した専用のnamespaceに、意図的に古いnginxを置いてあります。ネットワークポリシーで外部との通信を遮断した、いわば「安全な標本」です。


1. 舞台と登場人物——1つの「頭脳」と、修正へ向かう2つの「道」

最初に全体像を置きます。この図が、記事全体の地図になります。
01-two-hands.drawio.png

登場人物 正体 持っているもの
Sysdig Secure バックエンド 判定エンジンとデータ基盤 脆弱性カタログ(SBOM × 既知CVE)/ランキングエンジン/作業単位(Job)とその計画(Plan)のカタログ
経路A: Secure AI の内製エージェント(Vuln Agent) Sysdig SecureのWeb UIに組み込まれた会話型エージェント Jobごとの「Start / Skip」ボタン。修正案の起草とレビューをUIの中で行い、承認するとJiraチケットが起票され、以後それを追跡する
経路B: Claude Code + sysdig-skills プラグイン(Headless Cloud Security) MCP(Model Context Protocol)経由でSysdigのツールを呼ぶ、利用者側のエージェント /sysdig-investigate → /sysdig-remediate という2つのスキル。判定材料はSysdigから受け取り、プルリクエスト・Issue・実適用は自分で書く
人間(私) 承認者 どちらの経路でも、書き込みの前に必ず承認が入る

1-1. 「Secure AI」は製品名です

ここは誤解しやすいところなので、公式の一次情報を引きます。Secure AI は Sysdig の正式な製品名です(Sysdig Secure AI のご紹介、2026-08-05)。Sysdig Secure(CNAPPプラットフォーム)の拡張として「専門家レベルのAIセキュリティチーム」を提供するもので、用途別のエージェント群——Vuln Agent(脆弱性の一貫した管理)/SOC Agent/Posture Agent/Risk Agent/Response Agent——で構成されます。この記事で扱うPlans / Jobsは、このうちVuln Agentの担当領域です。

そして、この記事のテーマにとって決定的に重要なのは、この製品が最初から「2つの担い手」を想定していることです。公式発表はこう書いています。

エージェントは、Sysdig のものであれお客様独自のものであれ、推奨事項の提示で止まることなくワークフロー全体を実行し、修正が完了するまでやり遂げます。

ここで大事なのは、Sysdigのものも、お客様独自のものも、どちらも正規の担い手として想定されているという点です。前者が図の経路A、後者が経路Bにあたります。しかも経路Bには公式の名前があります——Headless Cloud Security。Sysdigの知見を利用者側のコーディングエージェント(公式発表はClaude Code・Codex・Cursorを名指ししています)へ直接届ける機能で、今回使っているプラグインの名前そのものです。

つまり経路Aも経路Bも、Sysdig Secure AIの公式機能です。外部のツールが横から繋いでいるわけではありません。そして両者には共通点が1つあります——実際にコードや設定を書き換える作業は、どちらの経路でも Sysdig の外側で起きるということです。Sysdigが担うのは、見つけて・並べて・安全性を判定して・追跡すること。ここが第6章で詳しく見る、もう1本の境界線です。

実際の画面がこれです。

s0-plans-list.png

この画面で見てほしいところ: 左ナビゲーションの最上段に「Secure AI」があること。そして3つのPlan(Default — SLA Compliance - Copy / Default — SLA Compliance / Default — Reduce Exposure Time)が、それぞれ異なる指標値(99+ % / 7 % / 9 d)と 「5 Jobs」 を表示していること。この「Job」が、以降ずっと主役になる作業単位です。

📌 この章のまとめ: 判定と追跡を担うのは1人(Sysdigのバックエンド)、修正に向けて動く経路は2つ(Secure AIの内製エージェントとClaude Code)。そして修正そのものは、どちらの経路でもSysdigの外側で行われます。


2. 「検出」の正体——その場で調べているわけではない

この章で分かること: Sysdigの「検出」が実際にやっていること。そして「脆弱性は何件?」という素朴な問いに、7つの正しい答えがある理由。

2-1. 舞台裏は「あらかじめ描かれた地図」

02-detection-flow.drawio.png

  1. SBOM抽出 — 対象に何のパッケージが入っているかを棚卸しします。
  2. 既知CVEデータベースとの照合 — そのパッケージ一覧を、Sysdigが保有する脆弱性情報と突き合わせます。
  3. グラフDBへの事前保存 — 「このパッケージはこの脆弱性の影響を受ける」という関係を、Image AFFECTED_BY Vulnerability というグラフの辺としてあらかじめ計算して保存します。
  4. クエリで取得 — エージェントが投げるのは、この事前計算済みグラフへの問い合わせだけです。

つまり「検出」という言葉から想像しがちな「その場でスキャンする」動作ではありません。すでに描かれた地図から、必要な部分を読み出しているわけです。

速度がそれを裏付けます。今回のクエリは287行を返すのに33ミリ秒でした。スキャンではなく読み出しだから、この速さになります。

💡 知っておくと得をする点: この辺の名前は資産の種類で変わります。コンテナイメージなら Image AFFECTED_BY Vulnerability、物理サーバやVMなら Host AFFECTED_BY Vulnerability です。/sysdig-remediate の標準クエリはイメージ向けなので、単体ホストを調べたいときは資産の種類に合った入口を選ぶのがコツです。

2-2. 実物を見る——意図的に古いnginx

検証対象は nginx:1.25.3 です。この日の朝に、隔離したnamespaceへ意図的に置いた「標本」です。

s1-inventory-badges.png

この画面で見てほしいところ: 右側の2組のバッジです。In Use Vulns が 7 / 37 / 29、Vulnerabilities が 51 / 236 / 231 / 35 / 128。後者を合計すると 681。この数字を覚えておいてください。次の節で、同じイメージに対して7通りの「正しい件数」が出てきます。(バッジの配色から左がCriticalと読めますが、画面上に凡例がないため (推定) としておきます)

2-3. コラム: このイメージの脆弱性は何件?——全部正しい7つの答え

「このnginxの脆弱性は何件ですか」と聞かれたとき、答えは質問の単位を決めないと確定しません。同じイメージ・同じ時刻で実測した数字を並べます。

# 数え方(母集団の定義) 件数 取得方法
1 UIバッジの合計(全severity・finding単位) 681 Inventory画面
2 findings APIのイメージ行 findingsCount 681 query_vulnerability_findings(group_by=image)
3 finding単位・Criticalのみ 51 同(group_by=none, severity=critical)
4 CVE単位・Criticalのみ 42 同(group_by=cve, severity=critical)
5 CVE単位・Critical + High 204 同(group_by=cve, Critical+High)
6 (CVE, パッケージ) 対・Critical + High 287 SysQLの RETURN DISTINCT
7 実行中 ∧ ネットワーク到達可能 ∧ 修正版あり 37(Critical 6 / High 31) get_job_impact

気持ちのよい一致が2つありました。 ①と②が681でぴったり揃い、UIバッジのCritical(51)と③のAPI値(51)も揃いました。UIとAPIは同じものを数えている——ただし単位が違うだけだと、実測で確認できたわけです。

差が生まれる理由も特定できました。 ③の51と④の42の差は、同じCVEが複数のパッケージにヒットするためです。実例を挙げます。

  • CVE-2024-37371 → libgssapi-krb5-2 / libk5crypto3 / libkrb5-3 / libkrb5support0 の 4パッケージ
  • CVE-2026-53613 → bsdutils / libblkid1 / libmount1 / libsmartcols1 / libuuid1 / mount / util-linux / util-linux-extra の 8パッケージ

⑤の204 CVEと⑥の287対の差(83)も、同じ現象です。

📌 この章のまとめ: 「検出」は事前計算済みグラフの読み出しです。そして件数を語るときは、severityの範囲・finding単位かCVE単位か・実行時フィルタの有無という3つの軸を先に決めると、会話が噛み合います。7つの数字はどれも正しいのです。


3. どれから直すか——指標の選択が、実は戦略そのもの

この章で分かること: 優先順位の付き方。そして同じイメージが1位にも5位にもなるという、今回いちばん驚いた事実。

3-1. ランキングの材料

03-ranking-signals.drawio.png

Sysdigは1つのCVEを単独で見るのではなく、複数の信号を合成して「今すぐ直すべきものはどれか」を決めます。使われる信号はAPI仕様から読み取れます——CVSS、EPSS(悪用予測スコア)、CISA KEV(悪用実績が確認された脆弱性のリスト)、修正版の有無、実行中かどうか、ネットワークから到達できるか。

合成スコアの重み付けは製品側の領分です。 Claude Code側は「もう並んだ結果」を受け取るだけで、スキルの定義には「並べ替えてはならない」と明記されています。これは分業として筋が通っていて、おかげで利用者はもう一段上のレバーに集中できます。そのレバーとは「どの指標で世界を見るか」です。次の節が、その威力の実測です。

3-2. Planは「どの指標で世界を見るか」の宣言

Planを開くと、Secure AIが自然文で「このPlanは何を追っているか」「調子はどうか」「どこから始めるべきか」を説明してくれます。ここが読みどころです。

s2-plan-detail.png

この画面で見てほしいところ: 3点あります。

  1. 「How is this plan doing?」の表 — Criticalが compliant 2 / at risk 1 / breach 109、最も古い違反が180日、SLAの閾値は30日。現在値7.4%(前日は24.4%)。
  2. 「Where do I start?」 — 最上位のJobとして nginx:1.25.3 を名指しし、「243 findings、Plan全体1,794の13.5%、227件がSLA違反(Critical 42・最古180日/High 185)」と根拠を添えていること。なぜそれが1位なのかが、文章で説明されるわけです。
  3. 右下の Start / Skip ボタン — これが経路Aの入口です(第6章で詳しく見ます)。

3-3. 同じイメージが「1位」にも「5位」にもなった

ここが今回の核心です。同じ日・同じ環境・同じ nginx:1.25.3 が、選んだPlanによって最優先にも最下位にもなりました。

04-measure-decides-rank.drawio.png

Plan 指標が測るもの nginx:1.25.3 の扱い
Default — SLA Compliance 修正版が公開されてからの経過日数 1位(Critical 42件が最古180日のSLA違反)
Default — Reduce Exposure Time 環境内に存在した日数 × 件数 5位=最下位(平均0日、スコア0)

なぜ逆になるのか。「いつから数えるか」が違うからです。

  • libc6 の修正版は約180日前に公開済み → SLA指標では「パッチが出てから180日経っている」
  • 脆弱イメージ自体はこの日の朝にデプロイした → Exposure Time指標では「環境内にはまだ0日しか存在していない」

同じfindingが「180日」と「0日」を同時に満たします。どちらも正しい。前者は組織の対応速度を測り、後者は危険が環境内に居座った時間を測っているからです。

さらに面白いのは、指標を変えるとJobの"母集団"まで変わることです。SLA ComplianceのTOP 5は nginx:1.25.3 / etcd / calico/cni / kube-proxy / calico/kube-controllers。一方Reduce Exposure Timeでは etcd / kube-controller-manager / kube-apiserver / kube-scheduler / nginx。メンバーが半分入れ替わっています。 「実行中 ∧ 到達可能 ∧ 修正版あり」を条件に含む指標では、その条件を満たすfindingが0件の資産は母集団から外れるためです。

つまり——Plan選びは、技術的な設定ではなく戦略判断です。 「パッチ適用の遅れを詰めたい」のか「危険が環境に居座る時間を縮めたい」のか。目的に合う指標を選べば、上位に並ぶ顔ぶれがそれに応じて変わります。

3-4. Claude Code側で同じものを見る

/sysdig-investigate は、この順序を改変せずそのまま提示します。今回ターミナル側で歩いたのは Reduce Exposure Time のPlanです——つまり、さきほどの画面(SLA Compliance)で1位だった nginx:1.25.3 が、ここでは5位として現れます。

s3-ranked-jobs-terminal.png

この画面で見てほしいところ: スコアの降順(615 → 582 → 582 → 571 → 0)がそのまま1〜5位になっていること。Claude Codeは並べ替えないので、表の順序はSysdigの計算結果そのものです。

3-5. Jobカタログは「生き物」だった

もうひとつ、実測でしか分からなかったことがあります。Jobの件数は、見るたびに変わります。

時刻(UTC) SLA Compliance Reduce Exposure Time 何が起きたか
前日まで 0 0 Jobがまだ生成されていない状態
09-16 00:36:45 5 5 Sysdigのバックエンドが自動生成(実行者はシステム)
09-16 01:00:18 (+9件) — 2度目の生成バッチ
09-16 01:05(API) 5 5 最初にAPIで一覧を取った時点の値
09-16 01:35(UI) open 17 / closed 1 — スクリーンショットの表示
09-16 01:44(API) 17 4 再取得。SLAは増え、Exposure Timeは1件closeした分だけ減った

APIとUIの数字が食い違って見えたのは、両者が違う瞬間を写していたからでした。 Jobのカウントはクローズ済みを含まない生きた値で、5 → 17 はバックエンドによる段階的な追加、5 → 4 は私たちが1件クローズした結果です。UIの「Jobs closed: 1」とも完全に整合していました。

なお、SLA Complianceのopenが17件ある一方で、Job追加のイベントは10件でした。差の7件は、他のPlan向けに作られたJobが、スコープと指標の重なりによって共有されたためと考えられます(ツール仕様に「JobはスコープがカバーするPlanやビューの間で共有される」と明記されています)。イベントログで直接裏付けたわけではないので (推定) です。

📌 この章のまとめ: ランキングの重み付けは製品側の領分ですが、「どの指標で見るか」という一段上のレバーは完全に利用者の手の中にあります。そしてJobカタログは静的な台帳ではなく、Sysdig側が動かし続ける生きたキューです。


4. その修正版は安全か——4つの出口

この章で分かること: 「この版に上げれば安全」という判断の作り方。そして教科書の二分法に収まらなかったときの、実務的な着地。

4-1. 教科書の形

修正版を決めるとき、/sysdig-remediate は「候補のバージョン自身が新しい重大な脆弱性を持っていないか」を確認します。これをchain analysisと呼びます。

05-safe-version-loop.drawio.png

  • 各ステップの判定(「このバージョンにCVEはあるか」)は、第2章と同じグラフDBへの問い合わせ。判定はSysdigの仕事です。
  • 何度繰り返すか、いつ切り上げるか(最大5回)というループ制御はClaude Code側のロジックです。
  • そして重要なのが、「安全」の意味を二段階に分けている点です——「調べた結果、重大な脆弱性が無かった」のか、「そもそもまだ観測されていない」のか。後者を「未観測(unassessed)」として警告付きで扱います。0件を安全と読み替えない、誠実な設計です。

4-2. 実際には出口が4つあった

今回の標的は CVE-2024-2961(libc6 / libc-bin、Critical・CVSS 9.8・悪用実績あり・EPSS 88.3パーセンタイル)です。Sysdigが提示した修正版は 2.36-9+deb12u6 でした。

候補として nginx:1.30.4(Debian 13.6 / trixieベース、libc6@2.41-12+deb13u3)を評価したところ、教科書の二分法(観測済みclean/未観測)に収まらない状態に出ました。

06-four-exits.drawio.png

出口 意味 今回
① 観測済みclean スキャン済みで既知の重大CVEなし。最も強い「安全」の主張 —
② 未観測(unassessed) 0件は「安全」ではなく「まだ見ていない」 libc6@2.41-12+deb13u4(該当パッケージの記録が1件も無かった)
③ 次の候補へ 見つかったCVEの最小修正版を新しい候補にしてループ —
④ 対象CVEはclean、ただし別の未修正findingsが残る ループでは先へ進めない。残存リスクを明示して採用する libc6@2.41-12+deb13u3(採用したもの)

出口④の内訳はこうです。

  • 標的の CVE-2024-2961 は含まれていない(=解消)。パッケージの記録は存在する(=観測済み)。
  • 一方、同じパッケージ・同じバージョンに Highが4件ありました: CVE-2026-19499(7.3)/CVE-2026-6368(7.5)/CVE-2026-18374(8.1)/CVE-2026-5435(8.1)。
  • 4件とも、この時点では修正版が出ていません。 だからアルゴリズムの「最小修正版を次の候補にする」という手は使えません。悪用実績はいずれも確認されていません。

さらに興味深いことに、パッケージ自身が指し示す推奨修正版(2.41-12+deb13u4)は未観測でした。つまり——

「より新しい版」と「より確かめられている版」が、逆方向を向いた。

私たちは「観測済みで、標的CVEを確実に含まない」u3を採り、残存するHigh 4件をプルリクエストとIssueに明記しました。この判断が正しかったかは、第8章の事後実測が答えます。

📌 この章のまとめ: chain analysisは静的な照合であり、動的テストではありません。そして現実には「完全に安全」と「まだ分からない」の間に、**「狙った穴は塞がったが、別の課題が残っている」**という中間状態があります。この状態を隠さず書くことが、エージェントに求められる誠実さだと思います。


5. 「やらない」という判断——上位4件を飛ばした理由

歩いたPlan(Reduce Exposure Time)の上位4件は、すべてKubernetesのcontrol planeを構成するイメージ(etcd / kube-controller-manager / kube-apiserver / kube-scheduler)でした。標的の nginx:1.25.3 は、このPlanでは5位です。

ここで私たちはSkip(今回は手を付けない)を選びました。理由は明快です。control planeの構成イメージは、クラスタ管理ツール側のバージョン整合の方針に従う必要があるからです。findingの量と古さを測る指標の上位に来ることは正しい。しかし「この流れで直接タグを書き換えて良いか」は別の問題で、そこは運用側が判断する領域です。

大事なのは、Skipを「何もしなかった」で終わらせなかったことです。Claude Codeは4件それぞれについて理由を記録として残しました。第7章で見るように、この記録はSysdig側の画面にちゃんと現れます。

💡 実務的な含意: Sysdigのランキングは「どれが危ないか」を測ります。「どれを安全に直せるか」は、環境の事情を知っている側が足す情報です。2つを掛け合わせて初めて着手順が決まる——この足し算がエージェントと人間の共同作業になります。


6. 誰が手を動かすか——2つの経路

この章で分かること: 「UIのStartボタンは、Claude Codeからも押せるのか?」という自然な疑問への答え。そして修正の実行がどこで起きるのかという、いちばん大事な一点。

6-1. 問いの発端

第3章で見たPlan詳細画面には、Jobごとに Start / Skip のボタンが並んでいます。Startを押すと、Sysdig側が修正案(推奨パッケージ版やイメージ更新)を起草し、その内容をレビューできます。そして承認すると、その修正案がJiraのチケットとして起票されます。Sysdigは以後、そのチケットを追跡します。

ここが肝心です。実際にコードや設定を書き換える作業は、チケットを受け取った人間、あるいはAIエージェントが、Sysdigの外側で行います。

作業中、私はこう聞きました——「UIでStartできるようだが、Claude Codeから起動して結果を受け取ることもできるのか?」

6-2. 答え: MCPのツール面は「追跡」に閉じている

07-two-execution-paths.drawio.png

Claude Codeに許可されているSysdig MCPのツールを全件精査しました(スキル自身の許可ツール定義も含めて)。JobとPlanに対して書き込めるツールは、次の3つです。

ツール できること
track_job 未追跡の候補を追跡対象へ昇格させる(状態遷移のみ)
close_job Jobをクローズする(不可逆。戻す操作は用意されていない)
create_artifact 成果物のURLやメモを記録する(成果物そのものの作成は行わない)。今回記録したのはプルリクエストのURLとメモです

3つに共通しているのは、どれも「追跡」の操作だということです。これはツールの説明にも明記されています——JobとPlanには更新用のツールがなく、進捗・状態・外部への参照(Jiraチケットやプルリクエスト)はartifact(記録)として積み上げる設計です。

つまり、**Job / Plan は「追跡レイヤ」**です。脆弱性対応という仕事を、見つけて・並べて・安全性を判定して・追跡する。修正の実行そのものは、どちらの経路でもSysdigの外側で起きます。

そう捉えると、2つの経路の違いはきれいに整理できます。

経路A(Secure AI の Start) 経路B(Claude Code)
Sysdig側がすること 修正案を起草し、レビューと承認を経てJiraチケットを起票し、以後追跡する ランク済みJobと判定材料を渡し、記録を受け取る
外側で起きること チケットを見た人間またはAIが修正して適用する Claude CodeがIssueとプルリクエストを書き、マージから適用まで行う
成果の残り方 チケットの状態として追跡される create_artifact / close_job でSysdigへ書き戻す

6-3. 2つは競合ではなく、つながりうる

ここで気づくことがあります。経路Aが起票したチケットを、経路Bのエージェントが受け取って直す——この組み合わせが自然に成立します。

しかもこれは思いつきではなく、スキルの設計に最初から織り込まれています。/sysdig-remediate は作業に入る前に重複チェックを行いますが、そのとき**「Sysdigのチケット連携が作ったチケット」を明示的に探しにいきます**。見つかれば、新しく作るのではなくそのチケットを引き継ぐという選択肢を人間に提示します。

つまり「UIで起票 → エージェントが直す」は、正規の使い方として想定されている流れです。今回はチケット連携を使わず、Claude Code側で最初から最後まで走らせました(UIのStartは一度も押していません)。どちらから入っても、成果は同じJobカタログに集まります。

⚠️ 運用上の注意: 両経路が同じJobに同時に触れると、記録が重複しえます。着手前に「このJobはどちらが担当するか」を決めておくのが安全です。

📌 この章のまとめ: Sysdigは「見つける・並べる・判定する・追跡する」。修正の実行は、必ずその外側で起きます。 その外側を人間が担うのか、エージェントが担うのか——選べるのはそこです。


7. 記録が戻ってくる——書き戻しはUIに現れる

この章で分かること: Claude Codeの書き込みが、Sysdig側で本当にどう見えるか。そして誰の名義で記録されるか。

7-1. ここは「判断」ではなく「状態管理」

第2章から第4章までは「何かを計算・判断する」仕事でしたが、track_job / close_job / create_artifact には計算がありません。ここは純粋な状態管理です。

だからこそ、関心事はひとつだけ——本当に書き戻っているのか。今回、実データに対して初めて1周が通りました。

08-job-lifecycle.drawio.png

今回の5件のJobに実際に起きたことを追うと、こうなります。

  • 上位4件(control planeイメージ)をSkip — 理由をメモとして記録。状態はopenのままです。スキップは「状態」ではなく「記録」として表現されます。
  • 5件目(nginx:1.25.3)をRemediate — track_job は呼びませんでした。Plan経由のJobは最初から追跡対象なので、スキルの規則に従った正しい非実行です。
  • 成果物を作る — プルリクエストとIssue。ここは完全にClaude Codeの領分です。
  • 記録して閉じる — create_artifact でプルリクエストのURLを記録し、close_job でクローズ。

7-2. 証拠——Sysdigの画面に、確かに現れた

Artifacts(成果物)タブ:

s4-artifacts-tab.png

この画面で見てほしいところ: 赤丸で囲まれた PRS (1) にプルリクエストのURLが入っていること。その下の NOTES (5) は、チケットの代わりにIssueを作ったことを記したメモが1件と、Skipの理由が4件。第5章で「やらない」と決めた判断が、Sysdig側にちゃんと残っています。

COMPLETED JOBS(完了したJob):

s5-completed-jobs.png

この画面で見てほしいところ: 赤丸の COMPLETED JOBS に緑のチェックが付いていること。これはターミナルから close_job を呼んだ結果です。TOP 5 JOBSのリストからは外れ、「Jobs still open: 17 / Jobs closed: 1」というカウンタも更新され、「Where do I start?」の推奨は次のJob(etcd:3.5.16-0)へ自動的に移っています。

Activity(監査ログ)タブ:

s6-activity-log.png

この画面で見てほしいところ: すべての行が同一の人間アカウントで始まっていること。transitioned job…(= close_job)、created Pull request…、added a note × 5。

7-3. 発見: 監査ログは「人間の名義」で残る

Claude CodeがMCP経由で行った書き込みは、ボットやサービスアカウントではなく、APIキーの持ち主(人間アカウント)の名義で記録されます。APIのレスポンスも「種別=ユーザー」を返しました。

表記について: スクリーンショットとこの記事では、個人名にあたる部分(メールアドレスのローカル部・GitHubアカウント名)を伏せています。所属を示すドメインやリポジトリ名はそのままです。論旨は「誰か」ではなく「人間アカウントの名義で記録される」という事実にあるためです。

これは実務上、二重の意味を持ちます。

  • 良い面: 承認者と実行者が同一人物として一貫して記録されます。「誰の責任で閉じられたか」が明確です。
  • 設計に織り込むべき面: 監査ログだけを見ると、「人間がUIで操作したのか、エージェントがMCP経由で行ったのか」は区別されません。エージェントが何をしたかの証跡は、利用者側(この記事・作業記録・プルリクエストの履歴)で持つのが正解です。

📌 この章のまとめ: 書き戻しは実在しました。Skipの理由まで含めてSysdig側に残り、UIから見えます。記録される名義は人間なので、エージェント運用の証跡は自分たちで持ちましょう。


8. 本当に直ったのか——事前/事後の実測

この章で分かること: 修正の効果。適用の数分後にSysdigが再スキャンしてくれたおかげで、「本当に直った」の確認まで到達できました。

8-1. 何を変えたか

変更はたった1行です。

s7-pr-diff.png

この画面で見てほしいところ: 実質的な変更はマニフェストの image: nginx:1.25.3 → image: nginx:1.30.4 の1行だけ(他は経緯を残すコメントです)。Debian 12.5から13.6 / trixieへ、OS世代をまたぐ更新になります。

成果物の中身も見ておきます。

s8-github-issue.png

この画面で見てほしいところ: 「Chain analysis」の節に、残存するHigh 4件の表と、その残存リスクを受け入れる判断の根拠が、起票した時点から書かれていること。後から訂正を足したのではありません。

8-2. 実測: 681 → 253、そして「悪用実績あり」が消えた

適用の約7分後、Sysdig側で新しいイメージがスキャン済みになりました。同じクエリを事前・事後で撃ち比べた結果です。

指標 1.25.3(修正前) 1.30.4(修正後) 差
findingsCount(全severity・finding単位) 681 253 −428(−63%)
Critical のCVE数 42 13 −29(−69%)
Critical + High のCVE数 204 53 −151(−74%)
悪用実績が確認された脆弱性を含むか あり なし 解消
CISA KEV掲載の脆弱性を含むか あり なし 解消

数の減少以上に重要なのは下の2行です。このイメージはもう、悪用実績が確認された脆弱性も、CISA KEV掲載の脆弱性も抱えていません。

8-3. 予測は当たったか

CVE 修正前 修正後 事前の予測
CVE-2024-2961(標的、Critical 9.8、悪用実績あり) あり なし 解消すると予測 → 的中
CVE-2026-42533(nginx本体、High 8.1) あり なし — → 副次的に解消
CVE-2026-60005(nginx本体、High 8.2) あり なし — → 副次的に解消
CVE-2026-19499(libc6、High 7.3) — あり 残ると予測 → 的中
CVE-2026-6368(libc6、High 7.5) — あり 残ると予測 → 的中
CVE-2026-18374(libc6、High 8.1) — あり 残ると予測 → 的中
CVE-2026-5435(libc6、High 8.1) — あり 残ると予測 → 的中

表の2行目・3行目は、事前には予測していなかったうれしい副産物です。イメージのタグを上げたことでnginx本体も新しくなり、libc6 とは別のCVEが2件まとめて解消しました。

chain analysisの予測は、7件すべて当たりました。 標的は消え、「残ります」と書いた4件は正確に残りました。第4章で残存リスクを明記して採用した判断は、事後の実測で裏付けられたことになります。

📌 この章のまとめ: 件数は681→253に減り、悪用実績が確認された脆弱性もCISA KEV掲載の脆弱性も解消し、chain analysisの予測は7件すべて的中しました。「直したつもり」ではなく「直ったことを数字で確認した」——ここまで来て、ようやく1周が閉じます。


9. 通しで見る——1周の流れ

ここまでの工程を、誰が・いつ・何をしたかで一覧にします。

09-end-to-end.drawio.png

縦に並んだものが同じ工程です。①〜⑤の各ステップで、Claude Codeが使ったSysdig側のツールが真下に対応しています。ながめていて気持ちがいいのは、人間のレーンに並ぶのが「承認」だけだという点です。調べる・決める・書く・適用する・確認する、の実作業はすべて下のレーンで進んでいます。

補足: この「適用」はAnsibleではありません。 今回のnginxはKubernetesのDeploymentなので、適用は kubectl apply です。一方、前回の記事で作ったクラスタ外の単体サーバはAnsibleで構成管理され、Kubernetes Job経由でSSHして適用します。GitOpsの型(ブランチ → プルリクエスト → CI → 承認 → マージ)は共通でも、最後の一手は対象によって変わります。


10. 用語の小辞典

この記事に出てきた用語と、画面で出会う用語を整理します。会話の単位を揃えるのに役立ちます。

用語 定義 注意
finding 実行時に結合された1行(CVE × パッケージ × リソース) UIのバッジはこの単位
CVE単位 CVEごとに畳んだ数 findingより少なくなる
(CVE, パッケージ) 対 SysQLの RETURN DISTINCT の単位 1つのCVEが複数パッケージにヒットする分だけ増える
fixable exposed 実行中 ∧ ネットワーク到達可能 ∧ 修正版あり 最も絞られる。攻撃されやすさに最も近い
SLA違反 修正版が公開されてからの経過日数が閾値を超過 「環境内での経過日数」ではない
observed / clean パッケージの記録が存在し、重大CVEなし 最も強い「安全」の主張
unassessed(未観測) パッケージの記録が存在しない 0件 ≠ 安全
Job 「この資産のこの脆弱性群を直す」という作業単位 Sysdig側が自動生成し、状態を持つ
Plan どの指標でJobを並べるかの宣言 指標を変えると順位も母集団も変わる
RTG(Remediation Target Group) Jobが対象とする資産のまとまり UIの説明文に頻出

おわりに

この1周で見えたことを、ひとことにまとめます。Sysdigは「見つける・並べる・安全かを判定する・追跡する」までを担い、修正そのものは必ずその外側で起きる。 そして今回、その外側をAIエージェントが担えることを、数字で確認できました。

いちばん印象に残ったのは、予測が当たったこと自体ではありません。「何が起きるはずか」を先に書いてから確かめられたことです。修正の前に「標的のCVEは消えます。ただしこの4件は残ります」とIssueに明記し、適用後の実測が宣言どおりだった——7件すべてで。

判定材料はSysdigが出す。エージェントがそれを使って予測と記録を残す。人間が方針を決めて承認する。この3者の噛み合いが、脆弱性対応を「勘の作業」から検証できる作業に変えてくれます。


次にやること

今回は1つのコンテナイメージで1周を走らせました。次は、

  • もう1つの経路(Secure AI の UI から Start を押す流れ)を実際に走らせて、起票されたチケットの中身を経路Bの結論と比べ、さらに**そのチケットをエージェントに引き継がせる「つなぎ」**を試してみる
  • 単体ホスト側(クラスタ外のサーバ)を、findingsを直接絞り込む入口から同じ密度で扱う
  • Posture(設定の健全性) のドメインでも、同じ「判定と実行の分担」が成り立つかを確かめる

あたりを予定しています。実際にやってみたら、また書きます。


この記事は、Falcoya-co-CTO(Claude Codeで構築したAIエージェント)との対話を通じて作成しました。登場する数値・画面・CVE番号は2026年9月16日の実測値です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?