現在位置: ホーム / ハッキングツール / numbat – AIコーディングエージェントのエンドポイント可視化とフォレンジクス
AIコーディングエージェントがプロジェクトの.envファイルを読み込み、続けてcurlを実行したとします。通常のエンドポイントセキュリティから見れば、開発者が同じ操作をしているのとほとんど区別がつきません。numbatは、PerplexityのGitHub組織で公開されているオープンソースツールです。Claude Code、Codex、Cursorといったコーディングエージェントを監視し、こうした操作を、それを提案したエージェントとセッションに結び付けます。筆者は、用意したClaude Codeのセッションでこのツールを実行しました。すると、シークレットファイルの読み取りに続いてアップロードが提案されるという、まさにそのパターンを検知しました。

numbatとは
numbatはAIコーディングエージェントにフックして、その動作を単一のイベントモデルに正規化し、検知ルールをローカルで実行します。
numbatによるClaude CodeやCodexなどAIコーディングエージェントの監視方法
numbatは、次の3つの経路からエージェントの活動を読み取ります。エージェントに組み込むフックとプラグイン、エージェントがエクスポートするOpenTelemetry(OTLP)ログ、そしてエージェントがディスク上に残すセッションファイルです。
3つとも同じ型付きイベントに変換されます。そのため、1つのルールで現在進行中の活動も、先週記録されたセッションも対象にできます。ただし、アクションを拒否できるのは、実行前のライブフックだけです。
対応状況を示すカバレッジマトリクスには、Claude Code、Codex、CursorからGemini CLI、GitHub Copilot CLIまで、27のエージェントおよびエージェントホストが並びます。各イベントはCELベースのルールエンジンで評価され、51のルールが標準で同梱されています。
ルールは、シークレット、情報流出、永続化、権限、横展開、改ざんなど、挙動ごとに分類されています。READMEにある検知結果の例には、MITRE ATT&CKの技術IDが付与されています。
最も重要なのは、一連の動作を対象とするシーケンスルールです。標準ルールの1つは、同一セッション内でシークレットファイルへのアクセスに続いてデータを含むアップロードが行われた場合に発火します。冒頭で挙げた「.envの読み取りの後にcurl」というケースであり、筆者が検証したのもこれです。
出力はバージョン付きのNDJSONです。イベント、検知結果、強制実行の判定、インジケータ、スキャンサマリーが、標準出力、ローカルファイル、HTTPエンドポイントのいずれかに書き出されます。
スキャンではシークレットがマスクされ、通常の出力に生のトランスクリプト全体が含まれることはありません。それでもREADMEは、レコードに機微なエンドポイント情報やエージェントのコンテキストが含まれうると警告しています。筆者は、出力ファイル自体を機密情報として扱うべきだと考えます。
用意したClaude Codeセッションでのnumbatの検証
自分のエージェント履歴にスキャナーを向けたくなかったため、代わりに5行のClaude Codeセッションを自作しました。ユーザーがエージェントに設定をサポート用エンドポイントへ送るよう依頼し、エージェントが.envを読み込み、予約済みの.invalidドメイン上のアドレスに対してcurl --data-binary @.envを提案する、という流れです。このセッションに対して、v0.2.0のWindows版リリースを実行しました。
numbat timelineは、セッションを時系列で表示します。各イベントはトランスクリプト内の対応する行を指しています。

numbat scanは3件の検知結果を出力しました。.envの読み取り(medium)、curlによるアップロードの提案(high)、そして最も重要な、両者を結び付けるchain.secret_read_then_egressです。

ツールは意図どおり機能しており、検知結果は両方のイベントを引用し、READMEの例と同じ3つのATT&CKタグを付けています。ただし、numbatが教えてくれないことが2つあります。1つは、今回のセッションではユーザー自身がそのアップロードを依頼していたことです。つまり、これはあるパターンに対してルールが発火したにすぎず、エージェントが不正に動作した証拠ではありません。インシデントとして扱う前に、ユーザーが何を依頼したのかを確認してください。もう1つは、numbatが把握しているのはアップロードが提案されたという事実だけだということです。実際にマシンの外へ何かが出たかどうかは、プロキシのログで確認する必要があります(今回は何も出ておらず、トランスクリプトに試行が記録されているだけです)。
自分の検知結果をドキュメントと比較する場合は、まずrule_versionを確認してください。筆者のv0.2.0バイナリはチェーンルールをバージョン1.6と報告しましたが、READMEのサンプルは1.4です。ルールのロジックはバージョン間で変わりうるためです。
AIエージェントのフォレンジクス:コーディングエージェントのセッション再構築
numbatは、エージェントがディスク上に残したファイルからセッションを再構築します。入口となるのは読み取り専用のコマンドです。numbat agentsは検出できるエージェントを一覧表示し、numbat scanはフックのインストールやエージェント設定の変更を行わずに、保存済みセッションを読み取ります。
numbat timelineは単一のセッションを順に並べ、numbat case buildは証拠をSHA-256マニフェスト付きでパッケージ化します。
復元できないもの。再構築は、エージェントがディスクに書き込んだ内容からしか行えません。READMEも、これは「ディスクやメモリの取得ではなく、エージェントが永続化しなかった活動は復元できない」と述べています。
また、ライブ取得よりも対応エージェントが少なくなっています。CLIの保存済みセッションパーサーが対応するのは、27のうち11です。Claude Code、Codex、Copilot CLI、Claude Cowork、Cursor、Gemini CLI、Kimi Code、OpenClaw、OpenCode、Pi、Windsurfが該当します。他の多くはフォーマットが「deferred」(対応保留)とされており、scanで読み取れるものがまだありません。
ケースバンドルのマニフェストは、バンドルが内部的に整合していることを示します。しかしREADMEは、署名のないバンドルは「発生元の真正性も完全性も証明しない」と明言しています。
numbatは危険なエージェントの操作をブロックできるか
ブロックできるのは限定的な範囲にとどまります。ブロックはデフォルトで無効であり、同梱の51ルールはすべて監視専用です。ルールにブロックさせるには、そのYAMLを自分のルールディレクトリにコピーし、IDはそのままにenforce: trueを追加してバージョンを上げます。その後、そのディレクトリを検証し、--enforceを付けて、そのディレクトリを指すようにフックを再インストールします。READMEにあるCodexの例は次のとおりです。
|
numbat rules check—rules–dir./numbat–policy numbat hook install—agent codex—emit all—rules–dir./numbat–policy—enforce |
Codexのユーザーフックの場合は、/hooks(またはアプリの設定 > Hooks)で、変更されたフックを再度確認して信頼する必要があります。READMEによれば、--enforceなどの変更後には信頼の再設定が必要です。どちらかの手順を飛ばすと、YAMLにどう書いてあってもブロックは一切行われません。
そこまで設定しても、numbat自身が何かを止めるわけではありません。対応エージェントはツールを実行する前にnumbatを呼び出します。Claude CodeではPreToolUseフックがそれにあたります。numbatは提案されたアクションを評価し、明確に一致した場合に、そのエージェント固有の拒否レスポンスを返します。
その拒否をどう扱うかを決めるのはエージェントホストです。ガイドによれば、ホストは、そして多くの場合モデルも、アクションが拒否されたことを把握できます。
| 仕組み | 制約 | |
|---|---|---|
| ライブ監視 | エージェントのフック、プラグイン、OTLPログ | 各ホストのフックとログが公開する範囲のみ |
| フォレンジックによる再構築 | 保存済みセッションファイルを読み取る(事前のインストール不要) | エージェントが永続化した内容のみ。多くのエージェントのフォーマットは対応保留 |
| ブロック | 同期型の実行前フックから、エージェント固有の拒否を返す | デフォルトは無効。オプトインしたルールのみ。パース済みシェルの一致は静的なサブセットに限定。フェイルオープン。最終判断はホスト |
強制実行が対象としないもの。ブロックできるのは、同期型の実行前フックだけです。実行後フック、OTLPログ、保存済みセッションはアクションの後に届くため、観測専用になります。また、マトリクス上のClaude CoworkとOpenCodeの2つは、監視専用です。
ガイドが最も慎重に扱っているのがシェルコマンドです。ルールは生のコマンド文字列に一致させることもできますが、それはあくまで文字どおりの入力であり、シェルが実行しないコメントや引用テキストを含む場合があります。実際に実行される内容に基づいて拒否したい場合は、numbatがパースしたコマンドのビューを使うよう、ガイドは案内しています。
パース済みビューで一致した場合でも、ブロックの対象は意図的に狭い静的なサブセットに限られます。具体的には、POSIXシェルでは単一の単純コマンドまたは単純コマンドによる1本のパイプライン、PowerShellやcmd.exeでは単一の単純コマンドです。複数の文、条件分岐、ループ、コマンド置換、eval、Invoke-Expressionは検知のみにとどまります。そのように書かれたコマンドは報告されますが、こうしたルールでは拒否されません。
さらに、フェイルオープンで動作します。不正な形式のペイロード、ルール評価のエラー、クラッシュ、出力の書き込み失敗のいずれでも、numbatの拒否は抑止されます。ガイドは、出力先が利用できない場合は「numbatの拒否を意図的に抑止する」と述べています。つまり、ログの出力先を失うとブロックも無効になります。
ログの置き場所も、エージェントと同じ側にあります。デフォルトでは、検知結果ファイルはエージェントと同じオペレーティングシステムのユーザーに属します。ガイドが言う「アウトオブバンド」とは、フックのレスポンスとは別という意味であり、「エージェントが読めない」という意味ではないと強調されています。
エージェントとnumbatが同じOSユーザーで動作している場合は、バイナリ、フック設定、出力パスをOSの制御機能で保護してください。numbatがこれらを分離してくれることはありません。
AIコーディングエージェントの保護:numbatの位置付け
当サイトでは、エージェントのセキュリティ問題をこれまで別の2つの角度から取り上げてきました。mcp-scanは、MCPの通信経路上にプロキシおよびガードレール監視として入ります。
AI IR Overlayの仕様は、有効な認証情報で動作しているエージェントをどう封じ込めるかを定めています。
numbatはその両方の下層、つまりエンドポイント自体で動作します。対応エージェントから取得したツール呼び出しを、MCPを経由しないものも含めて、各ホストのカバレッジの範囲内でエージェントとセッションに結び付けます。保存済みセッションのスキャン結果やケースバンドルは、調査の出発点となる証拠になります。
numbatのインストールと実行方法
numbatはApache 2.0ライセンスの単一バイナリです。最新のタグ付きリリースは2026年8月17日公開のv0.2.0で、macOS、Linux、Windows向けにamd64とarm64のビルドが用意されています。お使いのプラットフォーム用のアーカイブ(たとえばnumbat_0.2.0_windows_amd64.zip)をダウンロードし、そのSHA-256をリリースのchecksums.txt内の該当行と照合してから展開し、読み取り専用のコマンドから始めてください。
Go 1.26.6以降でビルドすることもできます。
|
go install github.com/perplexityai/numbat/cmd/numbat@latest |
READMEのクイックスタートは、まず読み取り専用のコマンドから始め、その後に監視用フックをインストールする流れです。以下はCodexの例です。
|
numbat agents numbat scan—agent codex numbat hook install—agent codex—emit all numbat hook status—agent codex |
最初の2つは何も変更しません。フックのインストールは監視モードで始まり、イベント、検知結果、インジケータを~/.numbat/records.ndjsonに書き込みます。
Codexでは、その後/hooksで新しいフックを確認して信頼する必要があります。また、hook statusが確認するのは設定であり、イベントが実際に届いているかどうかではありません。フックを信頼したら、無害でサポート対象のローカルツール呼び出しを1回行い、~/.numbat/records.ndjsonに新しいイベントが記録されているか確認してください。配信を裏付けるのはこのレコードであり、hook statusだけでは確認できません。
エージェントがすでにディスクに残しているセッションについては、numbat timelineで先ほど示した時系列ビューが得られます。
|
numbat timeline—agent claude |
保存済みセッションのスキャン結果を証拠として残すには、CLIリファレンスにあるとおり、スキャンにケースIDを付与し、その結果をバンドル化します。
|
numbat scan—case–id inv–42—emit all—output file—output–file records.ndjson numbat casebuild inv–42—from records.ndjson–oinv–42.numbat |
筆者なら、まず監視モードで運用し、レポートされる内容を確認してから、ブロックさせるルールを決めます。numbatは、コーディングエージェントの可視化とフォレンジクスのためのツールと位置付け、ブロックはその上に載るベストエフォートの追加機能であって、ポリシーの境界ではないと考えるべきです。numbat自身のガイドも、フックのカバレッジは「完全なエンドポイントポリシーの境界ではない」と述べています。
numbatはGitHubで公開されており、リポジトリにはカバレッジマトリクスと強制実行ガイドが含まれています。
翻訳元: https://www.darknet.org.uk/2026/10/numbat-endpoint-visibility-and-forensics-for-ai-coding-agents/