AppSec Toolbox MCP について
AppSec Toolbox MCPは、信頼できないリポジトリを監査するエージェントに、受動的なセキュリティスキャナーを提供します。固定の引数なしツールでネイティブレポートと来歴情報を収集し、リポジトリのコードを実行せず、エージェントにシェルや対象パスの制御権を与えません。
主な機能
- 01固定された8つの引数なしMCPツール
- 02信頼できないコードの受動スキャン
- 03SAST、シークレット、依存関係、IaCのスキャン
- 04ネイティブのスキャンレポートとSBOM
- 05ツリーフィンガープリントとレポートダイジェスト
- 06監査可能なツール呼び出しログ
活用シーン
- 01コードを実行せずに信頼できないリポジトリを監査
- 02エージェントによる確認用のセキュリティ証跡収集
- 03スキャン範囲の制約と来歴情報の記録
- 04オフラインモードでのスキャン実行
MCP 対応
固定された8つの引数なしセキュリティスキャンツールを提供するMCPサーバーです。MCPクライアントは全体監査や個別カテゴリのスキャンを要求でき、対象リポジトリのパスはツール引数ではなくオペレーターが設定します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
docker run -i --rm -e APPSEC_LANGS ghcr.io/ai-ronin-systems/appsec-toolbox-mcp:0.3.0APPSEC_LANGSLanguage profiles: auto, none, or a list such as python,nodeローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ghcr.io/ai-ronin-systems/appsec-toolbox-mcp:0.3.0stdioツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
appsec-toolbox-mcp
信頼できないコードを、シェルや任意のパスを選択する権限、リポジトリのコードを実行する権限を与えずに、AI エージェントに監査させます。
1つの強化されたコンテナ内で、固定された10個のセキュリティスキャナーを、パラメーター不要の8つの MCP ツールとして提供します。監査対象のリポジトリは攻撃者として扱われます。エージェントが行うのは、証拠の収集だけです。
このデモは、examples/vulnerable-sampleを対象にexamples/agent_demo.pyを実行して記録したものです。待ち時間は短縮されています。実際のスキャン時間は最後の行に記載されています。
30秒でわかる概要
- これは何か。 Semgrep、Gitleaks、OSV-Scanner、Trivy、Checkov、Syft、および言語別のスキャナー(Bandit、FindSecBugs、njsscan、gosec)を、固定された機能として任意の MCP クライアントに提供します。機能には
security.sast、security.secrets、security.dependenciesなどがあります。 - 脅威モデル。 監査対象のリポジトリは悪意あるものです。スキャナーが解析するすべてのファイルと、エージェントが読み取るすべての文字列を制御します。そのため、エージェントに操作の余地はありません。引数、対象パス、シェルは与えられず、リポジトリのビルドやコードを実行する手段もありません。
- 得られるもの。 ネイティブ形式のスキャナーレポート、各レポートの SHA-256 とスキャン対象ツリーから再計算可能なフィンガープリントを結び付ける実行マニフェスト、そしてすべてのツール呼び出しを記録する監査ログです。
エンジニアリングの主な特長
各項目には、その主張を裏付けるコードまたはテストへのリンクがあります。
| 問題 | アプローチ | 証拠 |
|---|---|---|
| シェルを使えるプロンプトインジェクションを受けたエージェントは、何でも実行できます。 | エージェントが操作できる範囲は、Makefile MCP によって管理される、パラメーター不要の8つのタスクだけです。保守用のターゲットもありますが、実行は拒否されます。 | .makefile-mcp.yaml、デモ |
信頼できないコードをスキャンすると、通常はそのコードが実行されます。たとえば、setup.py、postinstall、Gradle プラグイン、Go ツールチェーンのダウンロード、スキャナープラグインなどです。 | 厳格な受動的解析を行います。ビルド、インストール、依存関係の解決は行いません。Go は GOPROXY=off および GOTOOLCHAIN=local で実行します。敵対的レビューにより、仕込まれた .checkov.yaml によって Checkov がリポジトリの Python コードをインポートできることが判明しました。この経路は遮断され、回帰テストも追加されています。 | examples/hostile-sample、tests/image.sh |
悪意のあるリポジトリは、.semgrepignore、.gitleaksignore、# nosec、# nosemgrep などを使って、自らの検出結果を隠せます。 | すべてのスキャナーは、ツールボックスが所有する設定で実行されます。スキャナーが対応している場合はインライン抑制を無効にし、見つかったマーカーは抑制の有無にかかわらず、レビュー担当者向けにすべて一覧化します。 | 設定一覧、output/suppressions.json |
| 証拠は、スキャン対象と結び付いていなければ価値がありません。 | マニフェストは、find . -type f -print0 | LC_ALL=C sort -z | xargs -0 sha256sum | sha256sum とまったく同じ方法でツリーのフィンガープリントを生成します。UTF-8 ではないファイル名や sha256sum がエスケープするファイル名も対象に含め、各レポートのダイジェスト、ツールのバージョン、データソースも記録します。 | scripts/write-manifest.py、tests/unit/test_manifest.py |
| 形式が不正なファイルが1つあっても、ターゲットが監査を中断してはなりません。 | ターゲットに起因してスキャナーが読み取れない入力(読み込み不能な Go パッケージや破損したロックファイルなど)は、記録されたカバレッジ上の制限になります。バンドル全体の失敗にも、実態を反映しないクリーンな結果にもなりません。 | scripts/run-language-profiles.py、scripts/run-osv.sh |
| 結果は再現可能であるべきであり、侵害されたスキャナーがコードを送信できる場所があってはなりません。 | オフラインモードでは、ルールとアドバイザリーデータを一度取得した後、--network none のもとでスキャンします。マニフェストには、データの経過時間とダイジェストが記録されます。 | オフラインモード |
| セキュリティツールはサプライチェーン攻撃の標的になります。 | ダウンロードするすべてのバイナリを、アーキテクチャごとに公開されている SHA-256 と照合します。ベースイメージはダイジェストで固定し、Actions はコミットで固定します。プロジェクトコードを実行するリリースジョブには書き込みトークンを付与せず、イメージには署名済みのビルド来歴を付与します。 | Dockerfile、release.yml |
段階的な検証。 単体テストでスクリプトを検証します。スモークテストでは、ハードニング用フラグが欠けていると失敗するスタブを備えた偽のスキャナーを使い、Makefile MCP 経由で Makefile を実行します。イメージテストでは、既知の脆弱性があるサンプル、上記の攻撃をすべて試みる悪意のあるサンプル、オフラインモードに対して、文書化されたリソース制限のもとで実際のスキャナーを実行します。独立した敵対的レビューではイメージへの攻撃が行われ、確認された問題はすべて回帰テストとともに修正しました。残る事項は脅威モデルに記載しています。
クイックスタート
IMAGE=ghcr.io/ai-ronin-systems/appsec-toolbox-mcp:0.3.0
docker pull "$IMAGE"
gh attestation verify "oci://$IMAGE" --owner ai-ronin-systems
オフラインモード、リソース制限、ターゲット設定のハードニングは main に反映されており、次のリリースに含まれます。今すぐ使うには、docker build -t appsec-toolbox-mcp:dev . を実行し、IMAGE=appsec-toolbox-mcp:dev を設定してください。
1つのリポジトリに対して、MCP の stdio サーバーとして実行します。
docker run --rm -i \
--read-only --cap-drop=ALL --security-opt=no-new-privileges:true \
--tmpfs /tmp:rw,nosuid,nodev,size=3g --memory=6g --pids-limit=512 \
--user "$(id -u):$(id -g)" \
-v "$PWD/my-project:/runner/target:ro" \
-v "$PWD/appsec-output:/runner/output:rw" \
"$IMAGE"
同じコマンドを、任意の MCP クライアントで stdio サーバーとして登録します。
{
"mcpServers": {
"appsec-toolbox": {
"command": "docker",
"args": ["run", "--rm", "-i", "--read-only", "--cap-drop=ALL",
"--security-opt=no-new-privileges:true",
"--tmpfs", "/tmp:rw,nosuid,nodev,size=3g", "--memory=6g", "--pids-limit=512",
"-v", "/abs/path/my-project:/runner/target:ro",
"-v", "/abs/path/appsec-output:/runner/output:rw",
"ghcr.io/ai-ronin-systems/appsec-toolbox-mcp:0.3.0"]
}
}
}
Compose、オフラインモード、言語の選択、すべての証拠ファイルについては、使用方法をご覧ください。
仕組み
untrusted repository (read-only)
|
v
/runner/target
|
v
trusted Makefile + Makefile MCP
| | | | | |
Semgrep Gitleaks OSV Trivy Checkov Syft
|
+---- language profile selection ----+
| | | |
Bandit FindSecBugs njsscan gosec
Python Java Node/JS Go
|
v
/runner/output reports, run-manifest.json, suppressions.json, audit log
オペレーターは、リポジトリを正確に1つ /runner/target にマウントし、書き込み可能なディレクトリを1つ /runner/output にマウントします。監査対象のパスは MCP のパラメーターではないため、エージェントにホストパスへのアクセス権限はありません。信頼された Makefile にすべてのスキャナーコマンドが記述されており、Makefile MCP がエージェントに呼び出しを許可するターゲットを決定します。言語別のスペシャリストは、検出によって選択するか(APPSEC_LANGS=auto)、オペレーターが選択します。エージェントが選択することはありません。
| 機能 | ツール | 証拠 |
|---|---|---|
security.audit | 以下のすべて | 完全なバンドル |
security.sast | Semgrep + 抑制一覧 | semgrep.json、suppressions.json |
security.secrets | Gitleaks | gitleaks.json |
security.dependencies | OSV-Scanner | osv.json |
security.repository | Trivy | trivy.json |
security.iac | Checkov | checkov.json |
security.language | 該当する場合は Bandit、FindSecBugs、njsscan、gosec | language-profile.json + レポート |
supply_chain.sbom | Syft | sbom.cdx.json(CycloneDX) |
脅威モデル
監査対象のリポジトリは攻撃者であり、そのレポートを読むエージェントは、リポジトリによって誘導される可能性があります。脅威モデルをお読みください。攻撃者の目的、対策と残存リスクを含む16の脅威、保証されることと保証されないこと、およびオペレーター向けチェックリストを記載しています。
| 保護対象 | 保護対象外 |
|---|---|
| 対象のビルド、インストール、フック、Makefile は実行されません。 | スキャナーのパーサーのバグ。境界となるのはコンテナーです。 |
| 対象が所有するスキャナー設定ファイルによって、検出結果が抑制されたり、コードが読み込まれたりすることはありません。 | インラインの trivy:ignore および njsscan-ignore コメント。Checkov はインラインのスキップを skipped_checks として一覧表示します。これらはすべて一覧化されます。 |
| エージェントは対象を選択できず、8つのスキャン以外を実行することもできません。 | レポートの内容を誤って報告するエージェント。 |
| コンテナーに認証情報はなく、読み取り専用、非特権、非 root で、リソースが制限されています。 | オンラインモードで侵害されたスキャナーによる情報の持ち出し。オフラインモードでは、ネットワークを使わずに実行します。 |
| 各実行のマニフェストにより、レポートのダイジェストがスキャン対象ツリーのフィンガープリントに紐付けられます。 | output/ に書き込める人による改ざん。マニフェストには署名されていません。 |
設計上の選択
- 判定ではなく証拠。 レポートは各スキャナーのネイティブ形式のまま保持されます。このツールボックスは検出結果の評価、重複排除、正規化を一切行いません。利用者はすべての証拠を使ってそれらを行います。
- 閉じたスキャナーのセットは1つ。 言語プロファイルは4つで、プラグインフレームワークやユーザー定義のパイプラインはありません。汎用 SCA は OSV と Trivy が担い、スペシャリストは重複するエンジンではなく、異なる分析エンジンを追加します。
- カバレッジの不足は記録し、隠蔽しません。 ソースのみの Java プロジェクトでは、信頼できないコードをコンパイルしない方針のため FindSecBugs による検査は行われず、その旨はマニフェストに記載されます。
- すべてバージョンを固定。 スキャナーのバージョンは固定されており、既知の脆弱性を含むフィクスチャと悪意のあるフィクスチャを使って、1つずつ更新します(更新ポリシー)。
自律型の監査ツール、LLM エージェント、DAST エンジン、認証情報マネージャー、レポート正規化ツール、またはシェルサーバーではありません。
より大きなシステムの一部
appsec-audit-hound (planned) decides why to scan, correlates evidence, writes findings
| MCP
appsec-toolbox-mcp collects governed, passive evidence <- this repository
| built on
makefile-mcp exposes trusted Make targets to agents, deny-by-default
Makefile MCP は PyPI と公式 MCP レジストリで公開されており、独自の脅威モデルがあります。
ドキュメント
| ドキュメント | 内容 |
|---|---|
| 脅威モデル | 攻撃者の目的、脅威と対策、保証、制限、運用者向けチェックリスト |
| 使用方法 | 実行方法、ツールと証跡ファイル、言語プロファイル、オフラインモード、スキャナーの動作、ネットワークの使用、バージョン、開発 |
| アーキテクチャ | 信頼境界、所有権、設計ルール |
| ツール | 固定バージョン、各スキャナーが無視する設定、更新ポリシー |
| セキュリティポリシー | サポート対象バージョンと非公開の脆弱性報告 |
| 変更履歴 | リリース済みおよび未リリースの変更 |
| コントリビューション | 境界を広げずにスキャナーを追加する方法 |
開発
pipx install pytest==8.4.2 && pipx install ruff==0.14.0
make test # ruff, unit tests, smoke test
make image
make test-image # the real image: known positives, hostile sample, offline mode
詳細については、使用方法をご覧ください。
ライセンス
Apache-2.0.
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。