rust-panosmcp について
rust-panosmcp は、スコープ制御と監査に対応したツールで Palo Alto Networks PAN-OS ファイアウォールを操作するRust製MCPサーバーです。読み取り操作と保護された設定変更に対応し、独立承認を要する永続的な変更セットも扱います。
主な機能
- 01stdioとHTTPで27のツール
- 02トークンごとのデバイス・ツール範囲設定
- 03TLSと制限付きリクエスト処理
- 04監査可能なPAN-OS設定ライフサイクル
- 05独立承認付き変更セット
活用シーン
- 01ファイアウォールの一覧と状態を確認
- 02PAN-OSの設定やログを照会
- 03ファイアウォール設定変更を準備して承認
MCP 対応
stdioまたは認証付きStreamable HTTPで、PAN-OSファイアウォール操作をMCPクライアントに公開します。読み取り専用操作とスコープ制御された設定変更を提供し、検証、承認、監査の制御を備えています。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
docker run -i --rm ghcr.io/mechubsec/rustpanosmcp:0.17.0ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ghcr.io/mechubsec/rustpanosmcp:0.17.0stdioツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
rust-panosmcp
Palo Alto Networks PAN-OS ファイアウォール向けの非同期 Rust Model Context Protocol サーバー
mechub プロジェクト — 主権的なネットワークセキュリティ自動化
非公式/コミュニティプロジェクトです。 これは独立したコミュニティプロジェクトであり、Palo Alto Networks との提携や同社による推奨を主張するものではありません。製品名および商標は、このソフトウェアが相互運用するシステムを識別する目的でのみ使用しています。
このリポジトリには、v0.16.2 リリースが含まれています。共有の mecmcp-auth クレートと mecmcp-audit クレートによって認証と監査を提供する、ベアラー認証保護付きサーバー、構造化監査ログ、保護された PAN-OS 候補設定ライフサイクル、および強化されたリリースパッケージが含まれます。
このプロジェクトの目標は、rust-junosmcp と同じセキュリティ態勢を備えた、小型で高速な、本番環境向けのサーバーです。ベアラートークン認証、トークンごとのデバイスおよびツールのスコープ、TLS、リモートバインドの厳格な拒否ルール、入力と出力の上限、監査可能な変更操作、効率的な接続再利用を備えています。
アーキテクチャと提供計画については、PLAN.md をご覧ください。セキュリティ境界とリリースを阻止する制御については、THREAT_MODEL.md で追跡しています。
ワークスペース
rust-panosmcp/ # MCP binary and stdio adapter
rust-panosmcp-auth/ # bearer and secret-handling foundations
rust-panosmcp-core/ # inventory, PAN-OS client, validation, tool logic
config/ # secret-free inventory examples
docs/ # operator guidance and phase notes
fuzz/ # isolated cargo-fuzz workspace
packaging/ # distroless/container and systemd assets
scripts/ # release, matrix, fuzz, and benchmark gates
クイックスタート
インストール
次の3つのインストール方法から選択してください。
リリース tarball(Linux x86_64)
GitHub のリリースから最新リリースをダウンロードしてください。アセットは rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz のような名前で、対応する .sha256 ファイルもあります。
# Download and verify
curl -LO https://github.com/mechubsec/rustpanosmcp/releases/download/v0.16.2/rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz
curl -LO https://github.com/mechubsec/rustpanosmcp/releases/download/v0.16.2/rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz.sha256
sha256sum -c rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz.sha256
# Extract
tar xzf rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz
cd rust-panosmcp-v0.16.2
# Install the binary and systemd assets
sudo install -m 0755 bin/rust-panosmcp /usr/local/bin/rust-panosmcp
sudo install -m 0644 packaging/systemd/rust-panosmcp.sysusers /usr/lib/sysusers.d/rust-panosmcp.conf
sudo install -m 0644 packaging/systemd/rust-panosmcp.tmpfiles /usr/lib/tmpfiles.d/rust-panosmcp.conf
sudo install -m 0644 packaging/systemd/rust-panosmcp.service /etc/systemd/system/rust-panosmcp.service
# Create the service user and directories
sudo systemd-sysusers
sudo systemd-tmpfiles --create
# Generate the HMAC key for audit redaction (required).
# Guarded: NEVER overwrite an existing key. The key is what makes an HMAC-redacted
# device identifier comparable across audit history, so replacing it silently
# breaks correlation with every record already written. These steps are safe to
# re-run during an upgrade only because of this guard.
sudo sh -c '[ -f /etc/rust-panosmcp/audit-hmac.key ] ||
head -c 32 /dev/urandom | base64 > /etc/rust-panosmcp/audit-hmac.key'
sudo chmod 0600 /etc/rust-panosmcp/audit-hmac.key
sudo chown rust-panosmcp:rust-panosmcp /etc/rust-panosmcp/audit-hmac.key
# Start the service
sudo systemctl daemon-reload
sudo systemctl enable --now rust-panosmcp
これにより、専用の rust-panosmcp システムユーザーが作成され、/etc/rust-panosmcp(設定、root 所有)と /var/lib/rust-panosmcp(状態)が用意されます。監査ログでデバイス情報を秘匿するには、/etc/rust-panosmcp/audit-hmac.key の HMAC キーが必要です。このキーがない場合、サービスは起動しません。展開したアーカイブには config/ に設定例が含まれています。起動前に devices.example.json と tokens.example.json をテンプレートとして /etc/rust-panosmcp に配置してください。ユニットの詳細については、packaging/systemd/ をご覧ください。
LXC(Debian 13)
Proxmox またはスタンドアロンの systemd-nspawn 上に専用の非特権 LXC コンテナを用意する場合、リリース tarball に、上記の手動手順を自動化する冪等なインストーラーが含まれています。コンテナの作成方法を含む完全なセットアップガイドについては、HOW-TO-SETUP-LXC.md をご覧ください。
# Download and verify
curl -LO https://github.com/mechubsec/rustpanosmcp/releases/download/v0.16.2/rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz
curl -LO https://github.com/mechubsec/rustpanosmcp/releases/download/v0.16.2/rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz.sha256
sha256sum -c rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz.sha256
# Extract and run the installer
tar xzf rust-panosmcp-v0.16.2-x86_64-unknown-linux-gnu.tar.gz
cd rust-panosmcp-v0.16.2
sudo packaging/lxc/install.sh
# Configure the inventory and mint the first token
sudo vi /etc/rust-panosmcp/devices.json
sudo rust-panosmcp token add \
--tokens-file /var/lib/rust-panosmcp/tokens.json \
--name initial-token \
--devices fw-example \
--tools list_devices,gather_device_facts,execute_panos_op,get_panos_config
# Start the service
sudo systemctl enable --now rust-panosmcp.service
インストーラーは systemd-sysusers と systemd-tmpfiles を使って rust-panosmcp ユーザーとディレクトリを作成し、バイナリとユニットをインストールします。また、モード 0600 の空の tokens.json を作成し、/var/lib/rust-panosmcp/mutation-state.json がすでに存在する場合は上書きしません(変更セットの監査証跡)。エンドポイントはデフォルトで http://127.0.0.1:30031/mcp をリッスンします。環境変数による上書きとアップグレード時の動作については、packaging/lxc/install.sh をご覧ください。
Docker / GHCR
リリースタグごとに、ビルド済みイメージが ghcr.io/mechubsec/rustpanosmcp に公開されます。ビルドパイプラインについては .github/workflows/release-image.yml をご覧ください、2 人構成モードとラボモードの両方を含む完全なセットアップガイドについては HOW-TO-SETUP-DOCKER.md をご覧ください。
# Pull the image
docker pull ghcr.io/mechubsec/rustpanosmcp:latest
デフォルトの CMD はコンテナー内で 127.0.0.1:30031 にバインドするため、-p も --host/--allowed-host/--allowed-origin も指定せずに docker run を実行すると、正常に起動しますが、コンテナー外からはアクセスできません。動作する 2 人構成またはラボモードの docker run の実行方法(ポートの公開と、組み込みの ENTRYPOINT がすでに指定しているフラグを含む)については HOW-TO-SETUP-DOCKER.md をご覧ください。または、付属の compose.example.yaml を使用してください。
Docker で実行する(stdio)
stdin/stdout 経由でサーバーを起動する MCP クライアントの場合は、config/devices.example.json と同じ形式のインベントリを用意してください。
{
"version": 1,
"policy": {
"mode": "allowlist",
"allow": ["show system info", "show interface all"]
},
"devices": [
{
"name": "panos-demo",
"endpoint": "https://panos-demo.example.net",
"vsys": "vsys1",
"api_key": { "type": "env", "name": "PANOS_DEMO_API_KEY" },
"tags": ["lab", "read-only"]
}
]
}
コンテナーを起動する前に、API キーの環境変数をエクスポートしてください。この受け渡し方法ではキーがコマンドラインに表示されませんが、Docker デーモンへのアクセス権があると、インスペクションを通じて環境変数の値が露出する可能性があります。より厳格に扱うには、以下の設定セクションで説明するファイルベースの API キー形式({"type":"file","path":"/protected/path"})を使用し、そのファイルを読み取り専用かつモード 0600 でマウントしてください。
export PANOS_DEMO_API_KEY=replace-with-runtime-secret
マウントしたインベントリファイルと状態ファイルは、コンテナーユーザー(uid:gid 65532:65532)のみが読み書きできるようにしてください。シークレットを含むファイルのモードは 0600 にしてください。プロセス境界で stdio は認証されません。ランチャーはマウントされたインベントリ内のすべてのデバイスとすべてのツールを使用できるため、インベントリを制限し、読み取り専用の PAN-OS API ロールを使ってアクセス範囲を限定してください。サーバーが監査状態を作成するため、状態ディレクトリは書き込み可能である必要があります。
mkdir -p state
chmod 0600 devices.json
sudo chown 65532:65532 devices.json state
docker run --rm -i \
--user 65532:65532 \
-e PANOS_DEMO_API_KEY \
-v "$PWD/devices.json:/etc/rust-panosmcp/devices.json:ro" \
-v "$PWD/state:/var/lib/rust-panosmcp" \
ghcr.io/mechubsec/rustpanosmcp:0.15.0 \
--transport stdio
イメージの ENTRYPOINT は設定、トークン、状態、監査キーの各パスをすでに指定しているため、イメージ名の後にこれらのフラグを重ねて指定しないでください。トークンのパスは HTTP でのみ使用されます。この実行方法では HTTP とリスナー TLS は無効になります。--transport stdio を指定すると、HTTP のバインドおよびポートの各フラグを含むイメージの CMD が置き換えられるためです。ファイアウォールへの接続では、インベントリの TLS 信頼設定に従って引き続き HTTPS が使用されます。
ソースからビルドする
Rust 1.89 以降(MSRV)が必要です。
git clone https://github.com/mechubsec/rustpanosmcp.git
cd rustpanosmcp
cargo build --release --locked
./target/release/rust-panosmcp --version
実行する(stdio)
config/devices.example.json を出発点として、実際のインベントリを Git に含めないようにし、参照されている環境シークレットを用意してください。
export PANOS_LAB_API_KEY='runtime-secret'
cargo run --locked --release -- --device-mapping /absolute/path/devices.json
実行する(認証付き streamable-http)
まず最小権限のトークンを発行し、その後 TLS Streamable HTTP トランスポートを起動してください。
cargo run --locked --release -- \
--device-mapping /etc/rust-panosmcp/devices.json \
token add \
--tokens-file /etc/rust-panosmcp/tokens.json \
--name read-only-client \
--devices fw-example \
--tools list_devices,gather_device_facts,execute_panos_op,get_panos_config
cargo run --locked --release -- \
--device-mapping /etc/rust-panosmcp/devices.json \
--transport streamable-http \
--host 0.0.0.0 --port 30031 \
--tokens-file /etc/rust-panosmcp/tokens.json \
--tls-cert /etc/rust-panosmcp/server.crt \
--tls-key /etc/rust-panosmcp/server.key \
--allowed-host mcp.example.net \
--allowed-origin https://client.example.net
最初のコマンドの標準出力は安全に取り扱ってください。新しいベアラーシークレットが表示されるのはこのときだけです。トークンのローテーション、再読み込み、拒否ルール、リバースプロキシへのデプロイ、すべてのセキュリティ既定値については docs/PHASE2_OPERATIONS.md をご覧ください。フェーズ 1 のインベントリとファイアウォール TLS の詳細については docs/PHASE1_OPERATIONS.md をご覧ください。
ステータス
フェーズ 1 では、検証済みのインベントリおよびシークレットプロバイダー、システムルート/カスタム CA/リーフ証明書の完全一致ピンニングに対応した厳格な HTTPS、プール化された非同期 PAN-OS XML API 呼び出し、型付きエラー、タイムアウト、キャンセル、出力上限、デバイスごとのセマフォを実装しました。
フェーズ 2 では、ダイジェストのみを保存するベアラートークン、デバイス/ツールの完全一致スコープ、アトミックなインベントリ/トークンの再読み込み、TLS Streamable HTTP、Host/Origin 検証、リクエストボディのサイズ制限、IP/トークンのレート制限、監査に安全なリクエストトレースを追加しました。どちらのトランスポートも、以下の MCP ツールリファレンス に記載されている同じ 27 個のツールを共有します。ワイルドカード * のトークンスコープでアクセスできるのは、読み取り専用の 16 個(list_devices、gather_device_facts、
execute_panos_op、get_panos_config、list_panos_entries、
get_panos_entry_digest、list_panorama_device_groups、
list_panorama_templates、get_panorama_push_status、
list_panos_rulebase_entries、get_panos_ha_state、get_panos_license_info、
get_panos_content_status、get_panos_software_status、
test_panos_security_policy_match、query_panos_logs)のみです。11 個のライフサイクル/変更ツールには、明示的な指定が必要です。
フェーズ 3 では、オプトインの候補フィンガープリント、対象を絞った XPath ポリシー、PAN-OS 設定ロック、デバイスごとの直列化、ステージング/差分/完全検証、管理者スコープの部分コミット/復元、ジョブの整合性確認、構造化された変更監査を追加します。書き込みツールには明示的なトークンスコープが必要です。* は引き続き読み取り専用です。
フェーズ 4 では、ダイジェストでピンニングされた非 root の distroless イメージ、強化された systemd ユニット、読み取り専用のデプロイガイダンス、PAN-OS リリースファミリーマトリックス、5 つのパーサーファズターゲット、バイト単位で再現可能なアーカイブ、セキュリティ/運用手順書のドキュメント、公開済みの Rust/Python 測定結果を追加します。
v0.2 では、複数アクションに対応した永続的な変更セット、トークン固有の XPath/アクション許可と有効期限、正規化されたエンドポイント単位の直列化、所有者/デバイス/フィンガープリント/アクションダイジェストの完全一致にひも付く独立した承認を追加します。承認済みのセットは、1 つの PAN-OS 設定ロックのもとで適用され、後続のアクションが失敗した場合は自動的に管理者権限で復元されます。その後、既存の差分、完全検証、コミット、または破棄のライフサイクルを使用します。docs/V0.2_CHANGE_SETS.md を参照してください。
v0.2.1 では、PAN-OS 設定ロックの解放を、確認を伴う状態遷移に変更しました。コミット/破棄の記録で config_lock_held がクリアされるのは、デバイスがロック解除を受け入れた後のみです。ロック解除に失敗した場合は、明示的な整合性確認が必要な indeterminate として永続化されます。また、デフォルトで信頼される TLS とラボ展開の証拠を docs/V0.2.1_ACCEPTANCE.md に記録しました。
v0.2.2 では、v0.2.1 の PAN-OS ツール、認可、インベントリ、変更状態のインターフェースを維持しながら、保守対象の Rust 依存関係グラフと GitHub Actions を更新しました。公開リリースと、ガード付きラボ展開の証拠については docs/V0.2.2_ACCEPTANCE.md を参照してください。複数の vsys、HA、Panorama に関する作業は引き続き延期されています。
v0.3.0 では、認証を共有の
mecmcp-auth クレートに移行しました。このリポジトリ独自のトークン、ストア、トークンファイルの実装を廃止し、独立してテストされた共有クレートを使用します。PAN-OS ツールの範囲、認可スコープ、インベントリ、変更状態のインターフェースに変更はありません。運用者に見える変更は 2 つあります。tokens.json のモードが 0600 でない場合、サーバーは起動を拒否します。また、ディスク上のエンベロープバージョンが書き込み時に保持されるため、このリリースで変更されたファイルは以前のリリースでも読み取り可能です。アップグレード手順については CHANGELOG.md を参照してください。
完全な HTTPS モック、MCP エンドツーエンド、および明示的に設定された panosvm ラボファイアウォールの受け入れテストスイートはすべて合格しています。フェーズ 1 は完了しており、再現可能な証拠は docs/PHASE1_ACCEPTANCE.md に記録されています。
Phase 2 の受け入れ証跡は
docs/PHASE2_ACCEPTANCE.md に記録されています。設定変更の
受け入れについては docs/PHASE3_ACCEPTANCE.md に、運用要件については
docs/PHASE3_OPERATIONS.md に記載されています。
Phase 4 のリリース証跡は
docs/PHASE4_ACCEPTANCE.md に記載されています。本番環境へのデプロイ、
ローテーション、バックアップ/復旧、アップグレードについては
docs/OPERATIONS.md をご覧ください。あわせて、
docs/COMPATIBILITY.md、
docs/BENCHMARKS.md、SECURITY.md もご覧ください。上記の MCP
ベアラーロールとは別の、PAN-OS 側の最小権限管理者アカウントについては、
docs/PANOS_ADMIN_ROLES.md をご覧ください。
MCP ツールのリファレンス
サーバーは 27 個の MCP ツールを公開しており、操作の種類ごとに分類されています。
読み取り専用ツール
list_devices— 認可された PAN-OS デバイスと安全なメタデータを一覧表示します。API キーは決して返しません。gather_device_facts— 認可されたデバイスからホスト名、モデル、シリアル番号、バージョン、管理 IP、稼働時間を取得します。execute_panos_op— 出力上限を設けて、認可されたデバイス上で<show>をルートとする読み取り専用の PAN-OS XML コマンドを実行します。get_panos_config— 認可されたデバイス上の、検証済み/configXPath にある実行中または候補の PAN-OS 設定を読み取ります。list_panos_entries— ルールまたはオブジェクトのリストコンテナにある<entry>子要素を構造化 JSON でページ単位に取得します。大規模なルールベースでもエラーにせず、切り詰められたことを示します。get_panos_entry_digest— 単一ルールのドリフト検出のため、XPath で PAN-OS 設定エントリを正確に 1 つ取得してハッシュ化します。list_panorama_device_groups— Panorama のデバイスグループと、各グループに属するファイアウォールのシリアル番号を一覧表示します。list_panorama_templates— Panorama のテンプレートと、宣言されている変数名を一覧表示します。get_panorama_push_status— ジョブ ID を指定して、Panorama の commit-all/プッシュジョブの全体ステータスと、対象ファイアウォールごとのステータスを読み取ります。list_panos_rulebase_entries— vsys のセキュリティルール、NAT ルール、アドレスオブジェクト、またはサービスオブジェクトを、ページ単位で構造化 JSON として一覧表示し、切り詰められたことを示します。get_panos_ha_state— 認可されたデバイス上で、PAN-OS の高可用性状態(有効/無効、モード、ローカル状態、ピア状態)を読み取ります。get_panos_license_info— 認可されたデバイス上で、PAN-OS のライセンス状態(機能、シリアル番号、発行日、有効期限、期限切れ)を読み取ります。get_panos_content_status— 認可されたデバイス上で、PAN-OS のコンテンツバージョン状態(バージョン、リリース日、ダウンロード済みか、最新か)を読み取ります。get_panos_software_status— 認可されたデバイス上で、PAN-OS のソフトウェアバージョン状態(バージョン、リリース日、ダウンロード済みか、最新か、最新バージョン)を読み取ります。test_panos_security_policy_match— シミュレーションしたパケットが、認可されたデバイス上のどの PAN-OS セキュリティルールに一致するか(または一致しないか)をテストします。query_panos_logs— 認可されたデバイス上で、上限を設けた期間の PAN-OS ログ(トラフィック、脅威、システム、または設定)を取得します。常に上限が適用され、無制限には取得しません。
候補のライフサイクルツール(変更)
get_candidate_fingerprint— オペレーターが認可したすべての候補サブツリーを対象に、SHA-256 フィンガープリントを返します。stage_panos_config— 期待されるフィンガープリントを使用して、ポリシーで制限された PAN-OS 候補の set/delete 操作を 1 つステージングします。diff_panos_candidate— ステージング済みの候補フィンガープリントと完全に一致するものについて、上限を設けた PAN-OS の変更概要を返します。validate_panos_candidate— ステージング済みの候補を検証し、同じフィンガープリントの候補のみをコミット可能にします。commit_panos_candidate— 正確な候補フィンガープリントを指定して、正常に検証された操作のみをコミットします。discard_panos_candidate— 管理者スコープの部分的な候補リバートによって、ステージング済みの操作を破棄します。get_panos_operation— 所有する PAN-OS 候補ライフサイクル操作の安全なステータスを返します。
変更セットツール(v0.2+)
create_panos_change_set— インベントリとトークンの XPath/アクションスコープに従って、順序付けされた PAN-OS の候補アクションを 1~64 件計画し、保存します。approve_panos_change_set— 有効期限内の、正確な変更セットダイジェストを承認します。自己承認は拒否されます。get_panos_change_set— 確認または復旧のため、正確なアクション、ダイジェスト、承認、期限、操作状態を返します。apply_panos_change_set— 独立して承認された正確な変更セットを、単一のエンドポイント/設定ロックのもとで適用し、部分的な失敗があれば元に戻します。
書き込みツールには、明示的なトークンスコープが必要です。ワイルドカード * の許可は読み取り専用のままです。
設定
config/ にある 3 つのサンプルファイルで、設定項目を確認できます。
devices.example.json— 認証、TLS 検証モード(システムルート、カスタム CA、またはリーフ証明書の完全一致によるピン留め)、デバイスごとの同時実行数制限、候補操作用の任意の管理者オーバーライドを含むデバイスインベントリです。tokens.example.json— ベアラートークンストアの形式です。ダイジェストのみの保存、トークンごとのデバイスおよびツールの許可リスト、任意の変更許可(XPath ルート、許可アクション)、有効期限のタイムスタンプを設定できます。devices.mutation.example.json— 変更ルート設定と、管理者スコープの候補ワークフローフィールドを示すインベントリのバリエーションです。
インベントリファイルに認証情報を直接記述することはありません。各デバイスの api_key は参照情報であり、環境変数の場合は {"type": "env", "name": "VAR_NAME"}、アクセスモードを制限したシークレットファイルの場合は {"type": "file", "path": "/protected/path"} を指定します。
コマンドポリシー(execute_panos_op、test_panos_security_policy_match)
インベントリファイルのトップレベルにある policy キーは、execute_panos_op が実行する運用コマンドを制御します。同じゲートは、test_panos_security_policy_match が発行するサーバー側で構築された <test><security-policy-match> コマンドにも適用されます。
-
mode: "allowlist"(フェイルクローズ、既定)—allow(パイプ出力の場合はallowed_pipes)のエントリに一致しないコマンドは拒否されます。新規作成したインベントリや、policyセクションのないインベントリはこのモードになります。config/devices.example.jsonには、読み取り専用の基本セットが用意されています。"policy": { "mode": "allowlist", "allow": [ "show system info", "show interface all", "show routing route", "show running security-policy", "show session info", "test security-policy-match" ] }許可リストのエントリは、CLI テキストではなく、コマンド自身の XML 構造から取得した要素タグのパスと完全一致するかで判定されます。略記の展開は行われないため、
sh sys infoのような短縮形も、allowに含まれない他のコマンドと同様に拒否されます。test_panos_security_policy_matchを実行するには、test security-policy-matchのエントリが許可リストに必要です。このエントリがない場合、他の設定に関係なくすべての呼び出しが拒否されます。 -
mode: "blocklist"(フェイルオープン、レガシー)— デバイスのblocklist.commandsにある拒否ルールに一致するコマンドを除き、すべてのコマンドが許可されます。拒否ルールはあるもののpolicy.modeキーが明示されていないインベントリは、後方互換性のため、このモードで読み込まれます。サーバーは起動時に WARN を 1 回ログに記録します。フェイルオープンのブロックリストモードでは、ルールに網羅されていないケースに備える許可リストがないためです。新しいデプロイでは、代わりにmode: "allowlist"を設定してください。
各デバイスでは、デバイス固有の blocklist.allow/blocklist.allowed_pipes 配列を使って、共有の policy.allow/policy.allowed_pipes リストを拡張できます。統合方法は、現在の blocklist.commands の拒否ルールと同じです。
どちらのモードでも、拒否はすべて、基盤となるポリシーライブラリから取得した理由コードとともに監査ログへ記録されます。
監査ログ
v0.4.0 では、共有の mecmcp-audit クレートを使用した構造化監査ログが導入されました。ツール呼び出しごとに、呼び出し元の識別情報、対象デバイス、結果、実行時間を含むイベントが 1 件出力されます。
変更セットのライフサイクル監査により、承認の独立した証拠を提供します。approve_panos_change_set イベントには変更セット ID とフィンガープリントダイジェストの両方が含まれ、後に apply_panos_change_set で適用される正確なダイジェストを 2 人目のプリンシパルが確認したことを証明します。
監査設定フラグ
--audit-format {text|json}—text(デフォルト。人が読み取れる形式)またはjson(機械解析可能な形式)を選択します。--audit-log-file <PATH>— 監査イベントをファイルパスに書き込みます。--audit-journald— 監査イベントを systemd ジャーナルに出力します。--audit-redact— 宣言されたフィールド(デバイス名、呼び出し元の識別情報)を HMAC で仮名化し、運用上の識別情報を漏らさずにログを SIEM に送信できるようにします。--audit-hmac-key-file <PATH>— 編集に使用する HMAC キーへのパスです。--audit-redactを有効にする場合は必須です。
監査出力先はすべて任意で、組み合わせて指定できます。監査出力先が指定されていない場合、監査イベントは出力されません。
イベントストアへの転送
監査証跡はこのホスト上に留まりません。このサーバーは、ファミリー標準である AUDIT-FORWARDING-STANDARD.md に準拠しています。
生成元のマシンにしか存在しない監査記録は、監査証跡ではありません。記録の対象となっている当事者が運用者であるマシン上のログファイルにすぎません。
出力(現在有効)
--audit-format json \
--audit-log-file /var/lib/rust-panosmcp/audit.jsonl
JSON は必須です。text 形式はターミナルでの読み取り用であり、解析対象ではありません。ファイルは運用者向けの成果物であり、ローテーションする必要があります。サーバーがファイルを切り詰めることはありません。
転送(仕様策定済み、未実装)
SSDF の統合証拠コントラクトに従い、レコードは SSDF の ssdf.audit にハッシュチェーン形式の行として直接書き込まれます。これにより、行の削除や編集を検出できます。mecmcp#292 で追跡されています。
より低コストな syslog 経由の方法も設計されましたが、却下されました。この方法は機能しますが、レコードがチェーン化されません。一方、ここにあるその他すべてのリンクは、構造上、改ざんを検出できます。プランダイジェストは承認に紐づけられ、承認には別のプリンシパルが記録され、token_verified_fields は保証された来歴と申告された来歴を区別します。最後の段階がチェーン化されていないと、監査担当者が最も必要とする箇所でその保証が失われます。この判断に至った理由は標準に記録されています。
結果の読み方
token_verified_fields は、トークンが保証した来歴フィールドを示します。同じグループ内の残りのフィールドである client_name、model_id、session_id はクライアントが申告したもので、何によっても認証されていません。これらを同等のものとして扱わないでください。
request_id は、転送イベント、ハンドラーイベント、および(Junos の場合)デバイスのコミットコメントを関連付けます。
セキュリティ
全項目については、THREAT_MODEL.md と SECURITY.md を参照してください。主なポイントは次のとおりです。
- HTTP では認証が必須 — SHA-256 ダイジェストのみを保存するベアラートークンを使用し、秘密情報を平文で永続化しません。
- デフォルトではループバックのみ — ループバック以外で HTTP を使用するには TLS または明示的な
--allow-insecure-bindが必要です。ループバック以外で TLS を使用するには--allowed-hostが必要です。 - TLS 検証は常に有効 — システムのルート証明書、カスタム CA バンドル、または完全一致するリーフ証明書のピン留めを使用します。初回接続時の信頼や検証の無効化は行いません。
- I/O に上限を設定 — 出力上限(デフォルトは 512 KiB、最大 5 MiB)、リクエスト本文の上限(デフォルトは 1 MiB)、すべての PAN-OS 呼び出しへのタイムアウトを設定します。
- 変更操作を監査 — 候補操作はデバイスごとにシリアル化され、プリンシパルとフィンガープリントを記録します。検証後に明示的なコミットを要求し、復旧に備えてロックとジョブの状態を永続化します。
CLI リファレンス
Secure, async MCP server for PAN-OS firewalls
Usage: rust-panosmcp [OPTIONS] [COMMAND]
Commands:
token Manage the digest-only bearer-token store
state Perform offline recovery on the private mutation-state file
help Print this message or the help of the given subcommand(s)
Options:
-f, --device-mapping <DEVICE_MAPPING>
Validated JSON device inventory [default: devices.json]
-t, --transport <TRANSPORT>
MCP transport [default: stdio] [possible values: stdio, streamable-http]
-H, --host <HOST>
Numeric bind address for Streamable HTTP [default: 127.0.0.1]
-p, --port <PORT>
TCP port for Streamable HTTP [default: 30031]
--tokens-file <TOKENS_FILE>
Absolute digest-only bearer-token file path
--state-file <STATE_FILE>
Absolute private JSON file for persistent change-set and operation state
--lab-mode
Run without two-person control: change sets are approved on creation
--approval-timeout-secs <APPROVAL_TIMEOUT_SECS>
Seconds a change-set approval stays valid before it expires [default: 900]
--allow-plane-owned-writes
Allow destructive operations on devices owned by a management plane
--allow-direct-commit
Allow committing an operation with no change-set approval at all
--tls-cert <TLS_CERT>
Absolute PEM certificate path; requires `--tls-key`
--tls-key <TLS_KEY>
Absolute PEM private-key path; requires `--tls-cert`
--allow-no-auth
Disable bearer auth for a loopback-only development listener
--allow-insecure-bind
Permit a non-loopback plaintext listener behind a trusted TLS proxy
--allowed-host <ALLOWED_HOST>
Additional accepted HTTP Host authority. Repeat for multiple values
--allowed-origin <ALLOWED_ORIGIN>
Accepted browser Origin URL. Repeat for multiple values
--ip-rate-per-minute <IP_RATE_PER_MINUTE>
Per-source-IP requests allowed per rolling minute window [default: 120]
--token-rate-per-minute <TOKEN_RATE_PER_MINUTE>
Per-authenticated-token requests allowed per rolling minute window [default: 240]
--request-body-limit <REQUEST_BODY_LIMIT>
Maximum Streamable HTTP request body in bytes [default: 1048576]
--max-inflight-requests <MAX_INFLIGHT_REQUESTS>
Max concurrent in-flight requests across all callers. 0 = unlimited [default: 64]
--max-inflight-requests-per-token <MAX_INFLIGHT_REQUESTS_PER_TOKEN>
Max concurrent in-flight requests per bearer token. 0 = unlimited [default: 16]
--max-inflight-requests-per-target <MAX_INFLIGHT_REQUESTS_PER_TARGET>
Max concurrent in-flight requests per target device. 0 = unlimited [default: 4]
--max-sessions <MAX_SESSIONS>
Max concurrent MCP sessions. 0 = unlimited [default: 128]
--max-sessions-per-token <MAX_SESSIONS_PER_TOKEN>
Max concurrent MCP sessions per bearer token. 0 = unlimited [default: 16]
--enable-metrics
Expose unauthenticated Prometheus metrics at /metrics (streamable-http only)
--audit-format <AUDIT_FORMAT>
Audit log format: `text` or `json` [default: text]
--audit-log-file <AUDIT_LOG_FILE>
Optional dedicated JSON audit log file path
--audit-journald
Enable journald audit sink for `target="audit"` events
--audit-redact <AUDIT_REDACT>
Optional per-field redaction policy (e.g., `devices=hmac,host=drop`)
--audit-hmac-key-file <AUDIT_HMAC_KEY_FILE>
HMAC key file for audit redaction (required if audit-redact requests hmac)
--ssdf-audit-endpoint <SSDF_AUDIT_ENDPOINT>
ClickHouse endpoint for the SSDF evidence sink. Enables the pipeline
--ssdf-audit-server-id <SSDF_AUDIT_SERVER_ID>
This writer's chain identity. Required whenever the endpoint is set
--ssdf-audit-database <SSDF_AUDIT_DATABASE>
ClickHouse database holding the audit table [default: ssdf]
--ssdf-audit-user <SSDF_AUDIT_USER>
INSERT-only write identity [default: ssdf_audit]
--ssdf-audit-password-file <SSDF_AUDIT_PASSWORD_FILE>
File holding the write identity's password. Must be 0600
--ssdf-audit-verify-user <SSDF_AUDIT_VERIFY_USER>
SELECT-only read identity, used for the high-water and tail reads [default: ssdf_audit_verify]
--ssdf-audit-verify-password-file <SSDF_AUDIT_VERIFY_PASSWORD_FILE>
File holding the read identity's password. Must be 0600
--ssdf-audit-ca-file <SSDF_AUDIT_CA_FILE>
PEM trust anchor for the ClickHouse certificate. Required for `https://`
--ssdf-audit-outbox <SSDF_AUDIT_OUTBOX>
Durable outbox for closed segments. Required when the endpoint is set
--ssdf-audit-ledger <SSDF_AUDIT_LEDGER>
Delivery ledger. Required when the endpoint is set
--ssdf-audit-interval-secs <SSDF_AUDIT_INTERVAL_SECS>
Seconds between delivery attempts. Must be positive [default: 30]
--ssdf-audit-records-per-segment <SSDF_AUDIT_RECORDS_PER_SEGMENT>
Records per segment before one is closed and spooled [default: 64]
-h, --help
Print help (see more with '--help')
-V, --version
Print version
Token subcommands:
add Mint a token, store only its digest, and print the secret once
list List token names and scopes without secrets or digests
revoke Revoke a named token
rotate Replace a token secret while preserving its scopes
set-scopes Replace a token's scopes or mutation grant, keeping its secret
State subcommands:
resolve Mark an indeterminate operation terminal after manual PAN-OS reconciliation
--lab-mode
--lab-mode は第 2 のプリンシパルを免除します。これは、2 人による制御が形骸化していて制御として機能しない、単独オペレーターのラボ向けです。デフォルトでは無効であり、環境が重要な場所では無効のままにしてください。
変更されることと、変更されないこと:
- 変更セットの作成時に免除が自動的に適用されます。免除用ツールはなく、フローは本番環境と同じく作成 → 適用のままです。
- 計画、計画ダイジェスト、ドリフト検出、適用時の再検証はすべて引き続き実行されます。ラボモードで取り除かれるのは第 2 のレビュアーであり、変更記録ではありません。
- 承認者が捏造されることは決してありません。 免除された変更セットには
approver: nullとapproval_waiver: "lab-mode"が記録され、(change_set_id, plan_digest, owner, approved_at)に対する免除ダイジェストが含まれます。これは正規の 2 人による承認と暗号学的に区別でき、後から別のものとしてラベル付けすることはできません。これは、後日、どの変更で職務分掌が実際に行われたかを証明する必要が生じた場合に重要です。 - 有効にすると、サーバーは起動時に大きく警告します。
制御を免除せずに単独で書き込みテストを行う場合は、名前の異なる 2 つのトークンを発行し、一方で作成し、もう一方で承認してください。プリンシパルはトークン名であり、自己承認は拒否されます。これなら制御を維持したまま、1 人でライフサイクル全体を実行できます。手順に何らかの価値がある場所では、こちらの方法をおすすめします。
有効にする
サービスユニットにフラグを追加します。パッケージをインストールしている場合は、配布されたユニットを編集するのではなくドロップインを使用してください。そうすれば、アップグレード時にフラグが気付かないうちに削除されることを防げます。
sudo systemctl edit rust-panosmcp
ExecStart を置き換える場合は、全体を改めて記述する必要があるため、短縮版を書くのではなく、配布されたコマンドをコピーしてフラグを追加してください。他の引数を削除すると、ラボモードを有効にした副作用として、状態ファイルの場所やトランスポート設定が気付かないうちに変わってしまいます。
[Service]
# Clear the shipped ExecStart before replacing it; systemd appends otherwise.
ExecStart=
ExecStart=/usr/local/bin/rust-panosmcp \
--device-mapping /etc/rust-panosmcp/devices.json \
--transport streamable-http \
--host 127.0.0.1 \
--port 30031 \
--tokens-file /var/lib/rust-panosmcp/tokens.json \
--state-file /var/lib/rust-panosmcp/mutation-state.json \
--lab-mode
適用する前に packaging/systemd/rust-panosmcp.service と照合してください。配布された引数が正しい情報源であり、このスニペットは古くなる可能性のあるコピーです。
sudo systemctl daemon-reload && sudo systemctl restart rust-panosmcp
有効になったことを確認します。起動時の警告では、説明文に lab mode、結果の説明に approval_waiver=lab-mode が使われます。
sudo journalctl -u rust-panosmcp --since='5 minutes ago' | grep -i lab
想定される出力:
Aug 15 12:34:56 host rust-panosmcp[1234]: lab mode enabled: change sets are approved on creation with no second principal. Records carry approval_waiver=lab-mode. Do not run this against production devices.
承認者トークンは human である必要があります
approve_panos_change_set が受け付けるのは、トークンに actor_type: human が設定された第 2 のプリンシパルのみです。--actor-type を指定せずに発行されたトークンは unknown であり、agent トークンと同様に承認者として拒否されます。承認者トークンは rust-panosmcp token add ... --actor-type human で発行してください。stdio セッションには呼び出し元の ID がなく、承認できません。承認は認証済み HTTP 経由で行ってください。
--allow-direct-commit
stage_config で直接作成されたオペレーションに対する commit_panos_candidate は、create_panos_change_set / approve_panos_change_set / apply_panos_change_set を経由しない場合、ステージング、検証、コミットを1つのライフサイクルで実行します。独立した第2のプリンシパルによるレビューは一切なく、レビュー対象として指定できる変更セットもありません。デフォルトでは無効です。このフラグがない場合、ファイアウォールに一切触れる前にコミットが拒否されます。これは stdio と HTTP のどちらでも同じです(stdio には呼び出し元のコンテキストが一切ないため、認証済みセッションより寛容に扱うことはできません)。
残存リスク。 --allow-direct-commit は回避策であり、修正ではありません。このフラグを設定するオペレーターは、独立したレビューなしでこの特定のパスを実行することが、このデプロイメントでは許容可能なリスクだと判断したことになります。この判断は次のとおりです。
- 上記の
--lab-modeと同様、起動時に明確にログへ記録されます。 - 呼び出しごとに監査されます。 このフラグが有効な状態で実行された
commit_panos_candidate呼び出しでは、監査記録にdirect_commit_allowed=trueが含まれます。拒否された場合も、authorization=denied、reason=direct_commit_disabledとして監査されます。
このフラグは第2のプリンシパルによるレビューを追加するものではなく、レビューなしでの実行を可視化するだけです。ワークフローで利用できる場合は変更セットのフロー(create_panos_change_set → approve_panos_change_set → apply_panos_change_set)を優先し、このフラグはその形にどうしても適合できないオペレーションに限って使用してください。
--lab-mode と同じ方法で有効にします。systemd のドロップインを使って、同梱されているコマンド全体をコピーしたうえで、サービスユニットの ExecStart に --allow-direct-commit を追加してください。有効になったことを確認します。このフラグは、ラボモードのバナーとは異なり、監査ストリームの呼び出しごとのスキーマには意図的に含まれないため、通常の起動メッセージを grep してください。
sudo journalctl -u rust-panosmcp --since='5 minutes ago' | grep -i "allow-direct-commit is enabled"
検証
cargo fmt --all -- --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace --locked
cargo check --manifest-path fuzz/Cargo.toml --bins --locked
scripts/verify-packaging.sh
scripts/build-release.sh で再現可能なリリースアーカイブを作成するか、2回コンパイルして、scripts/verify-reproducible-build.sh でバイト単位の同一性を確認してください。コンテナーおよび systemd へのインストールについては、オペレーター向けランブックに記載されています。
ライセンス
MIT ライセンスのもとで提供されています。
a mechub project · 決定論に基づいて判断し、モデルが説明し、人間が承認する
github.com/fastrevmd-lab
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。