rustsdcmcp について
rustsdcmcpは、HPE Juniper Security Director CloudとそのSRX環境を管理する運用担当者向けの非同期Rust製MCPサーバーです。範囲を限定した読み取り・変更管理ツールを提供し、変更には準備、独立した承認、適用の手順を求めます。
主な機能
- 01SDC管理用ツールを80個提供
- 02テナントとツール単位のアクセス制限
- 03二者による変更承認フロー
- 04リクエストとレスポンスのサイズ制限
- 05認証情報を保護する監査記録
活用シーン
- 01管理対象のSRXデバイスとポリシーの確認
- 02ポリシー変更の準備と承認
- 03指定したテナントとツールへのアクセス制限
MCP 対応
80個のツールを通じて、HPE Juniper Security Director CloudのSRXデバイスとポリシー管理APIをMCPクライアントに公開します。読み取りと変更管理に対応し、変更には準備、独立した承認、適用が必要です。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
docker run -i --rm ghcr.io/mechubsec/rustsdcmcp:0.5.1ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ghcr.io/mechubsec/rustsdcmcp:0.5.1stdioツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
rustsdcmcp
HPE Juniper Security Director Cloud 向けの非同期 Rust Model Context Protocol サーバー
mechub のプロジェクト — 主権的なネットワークセキュリティの自動化
非公式/コミュニティプロジェクトです。 本プロジェクトは独立したコミュニティプロジェクトであり、Hewlett Packard Enterprise または Juniper Networks との提携や、これらの企業による推奨を主張するものではありません。製品名および商標は、本ソフトウェアが相互運用するシステムを 識別する目的でのみ使用しています。
rustsdcmcp は、HPE Juniper Security Director Cloud(SDC)を、範囲を限定し監査可能なツールとして MCP
クライアントに提供します。SDC は SRX 環境向けの HPE Juniper SASE
ポータルであるため、このサーバーは個々のファイアウォールではなく、その管理プレーンと通信します。
rustjunosmcp が個々の SRX デバイスと NETCONF で通信するのに対し、
rustsdcmcp はそれらを管理するポータルと HTTPS REST で通信します。
この違いにより、影響範囲は大きくなります。SDC の操作ひとつで、多数の管理対象 SRX デバイスに影響が及ぶ可能性があります。そのため、厳格な承認、認証情報を安全に保つ帰属情報、範囲を限定した I/O によって、管理プレーンを保護します。単に体裁を整えるためのものではありません。
現在の状況
rustsdcmcp は 80 個の MCP ツールを公開しています(v0.4.1 と main。v0.3.1 では 78 個、v0.2.0 では 74 個を提供):範囲を限定した読み取りツールが 60 個、変更管理ツールが 20 個です。対象範囲は、SRX デバイスとそのポリシーを管理する SDC API の部分です。製品の API の残りの部分は、意図的に対象外としています。
すべての変更操作は、prepare → 独立した承認 → apply の手順を通じてのみ実行できます。ワイルドカードのトークンスコープでは書き込みツールが付与されないため、トークン発行時にそれぞれを明示的に指定する必要があります。
SDC に対する実環境での検証は、読み取り専用の範囲を大きく超えています。2026-08-07 に、ラボテナントに対して完全な prepare → approve → apply のポリシーデプロイを実行し、管理対象の vSRX に到達しました。このとき、#23 で明らかになった共同管理の動作は、SDC が所有する階層内では、SDC がインポートしたポリシーから到達できないオブジェクトがデプロイ時に削除されるというものです。インターフェイス、ルーティング、system、管理インスタンスには変更を加えていません。完全な境界と観測された差分については、docs/operations.md を参照してください。JobStatus と DeviceStatusEntry は、実際のプレビューおよびデプロイのレスポンスに照らして検証済みです。
2026-08-12 に、証明書とライセンスの読み取りツール、BulkSyncDevices、テンプレートのエンドポイントを実環境で検証しました。デバイス同期はデバイスにプッシュするのではなく、SDC にインポートしますが、インベントリのみを調整し、device_config_state: OUT_OF_BAND_CHANGED はクリアしません。
読み取りパスのセキュリティ特性は、mecmcp v0.5.0 を使用し、コミット ea81805d2b4b97df9bdd3f70423e047524896a3d に対して 2026-08-07 に実環境で最後に検証されました。その後、トランスポートとスコープの事前チェックが e28d0cc と 369f9bb で置き換えられたため、この検証結果は現在の main の状態を示すものではありません。また、再度実環境で検証するためのラボ SDC テナントを利用できませんでした。2026-10-06 には、mecmcp v0.26.0 を使用し、コミット 2036523 に対して自動統合テストスイートを再実行しました。cargo test --workspace の結果は 258 件成功、0 件失敗で、以下の内容をカバーしています。
ベアラートークンがないリクエストは拒否される
(crates/rustsdcmcp/tests/http_boundary.rs::router_requires_bearer)。
スコープ外のテナントは拒否される
(crates/rustsdcmcp/tests/http_boundary.rs::out_of_scope_tenant_is_refused)。
読み取りツールと書き込みツールを分離した、ツールとテナントの厳密なスコープ適用
(crates/rustsdcmcp/src/server.rs のスコープ単体テスト、
crates/rustsdcmcp/tests/tool_contract.rs)。
レスポンス内のシークレットキーのマスキング
(crates/rustsdcmcp-core/src/redact.rs の単体テスト)。
2026-08-07 の実環境監査で確認した残りの特性は、現在の main では再検証されていません。このテスト実行は、実際のテナントでの検証に代わるものではなく、実環境での検証を改めて確立するものでもありません。
観測されたレスポンス形式と、未解決のエンドポイントに関する疑問は、docs/sdc-api/README.md で追跡しています。
ダウンロード
現行リリースの v0.4.1 には、チェックサムで検証でき、cosign で署名された LXC インストール用 tarball(rustsdcmcp_0.4.1_amd64.tar.gz)がリリースアセットとして添付されています。ダウンロードして検証するか、以下の手順で承認済みソースからビルドしてください。
そのタグ向けに linux/amd64 コンテナーイメージが ghcr.io/mechubsec/rustsdcmcp:0.4.1 で公開されており、認証なしでパブリックにプルできます。
承認済みソースからのビルド
rust-toolchain.toml ではビルドツールチェーンとして 1.99.0 を固定しています。Cargo.toml で宣言されている MSRV は 1.89 です。オペレーターは、ビルド、テスト、パッケージ化の前に、出荷予定のコミットにチェックアウトを紐付ける必要があります。通常はリリースタグを選択します。
approved_commit=$(git rev-parse v0.4.1^{commit})
git checkout --detach "$approved_commit"
test "$(git rev-parse HEAD)" = "$approved_commit"
cargo build --release --locked
cargo test --workspace --locked
scripts/build-package.sh
cp examples/sdc.example.json /secure/operator/path/sdc.json
この設定では、credential_env に外部プロセスの変数名を指定します。認証情報そのものを JSON に含めてはいけません。ローカルでコミットを指定してパッケージ化する場合は、承認済みコミットのディレクトリで、新しくビルドしたアーカイブと、アーカイブに埋め込まれた BUILD-INFO を検証してください。チェックサムに記録されるのはアーカイブのベース名だけなので、dist/ 全体を対象にした glob は使用しないでください。
artifact_dir="dist/$approved_commit"
mapfile -t archives < <(find "$artifact_dir" -maxdepth 1 -type f -name 'rustsdcmcp_*_amd64.tar.gz' -print)
test "${#archives[@]}" -eq 1
archive="${archives[0]}"
(cd "$artifact_dir" && sha256sum -c "$(basename "$archive").sha256")
package_root=$(tar -tzf "$archive" | sed -n '1s#/.*##p')
test -n "$package_root"
tar -xOf "$archive" "$package_root/BUILD-INFO" | grep -Fx "git_commit=$approved_commit"
Docker クイックスタート
公開済みのコンテナーイメージの実行方法については、HOW-TO-SETUP-DOCKER.md を参照してください。
Debian 13 LXC クイックスタート
LXC を一から構築する方法については、HOW-TO-SETUP-LXC.md を参照してください。
前提条件:
- Debian 13 AMD64。非特権 LXC を推奨します。
- 最小構成では、1 vCPU、512 MiB RAM、512 MiB スワップ、4 GiB ディスクが必要です。
- DNS と時刻同期が機能しており、
api.sdcloud.juniperclouds.netへのアウトバウンド HTTPS 通信が可能であること。 - LXC 内での root または同等のオペレーターアクセス。
署名済みの v0.4.1 リリース tarball をダウンロードするか、承認済みソースからビルドし(上記の承認済みソースからのビルドを参照)、検証済みパッケージをインストールします。
set -euo pipefail
mapfile -t archives < <(find . -maxdepth 1 -type f -name 'rustsdcmcp_0.4.1_amd64.tar.gz' -print)
test "${#archives[@]}" -eq 1
archive="${archives[0]}"
sha256sum -c "$archive.sha256"
package_root=$(tar -tzf "$archive" | sed -n '1s#/.*##p')
test -n "$package_root"
tar -xzf "$archive"
sudo "$package_root/packaging/lxc/install.sh"
認証情報を露出させずに、設定ファイルと認証情報ファイルを作成します。
sudo install -o root -g rustsdcmcp -m 0640 \
/etc/rustsdcmcp/sdc.json.example /etc/rustsdcmcp/sdc.json
sudoedit /etc/rustsdcmcp/sdc.json
sudo install -o root -g root -m 0600 /dev/null \
/etc/rustsdcmcp/credentials.env
sudoedit /etc/rustsdcmcp/credentials.env
sdc.json では、HTTPS の SDC エンドポイントを保持し、任意のローカルテナントエイリアスを使用して、expected_tenant_id にオペレーターが取得した SDC テナント ID を設定する必要があります。認証情報ファイルには、credential_env で指定した名前を使ったシェル互換の代入文を 1 つ記述します。たとえば SDC_API_TOKEN=... です。README や JSON に実際の値を記載しないでください。
最初に、読み取り専用の正確な 14 個のツールへの許可を作成します。リダイレクト先はあらかじめモード 0600 にしておく必要があります。出力されるのは一度限りのベアラートークンです。
sudo /usr/local/bin/rustsdcmcp token add \
--tokens-file /etc/rustsdcmcp/tokens.json \
--device-mapping /etc/rustsdcmcp/sdc.json \
--name sdc-read \
--devices production \
--tools get_sdc_tenant_scope,list_sdc_devices,get_sdc_device,list_sdc_firewall_policies,get_sdc_firewall_policy,list_sdc_nat_policies,get_sdc_nat_policy,list_sdc_resources,get_sdc_resource,get_sdc_preview_status,get_sdc_deploy_status,get_sdc_preview_device_result,get_sdc_deploy_device_result,get_sdc_change_set \
--actor-type human > /secure/local/path/rustsdcmcp-sdc-read-token
サービスを起動し、認証済み SSH トンネル経由でアクセスします。
sudo systemctl enable --now rustsdcmcp.service
sudo systemctl --no-pager --full status rustsdcmcp.service
sudo ss -ltnp 'sport = :30032'
ssh -N -L 30032:127.0.0.1:30032 root@your-deployment-host
想定されるリスナーは 127.0.0.1:30032 のみです。トンネルが有効な間、ローカルの MCP クライアントは http://127.0.0.1:30032/mcp を使用します。各インストールにはそれぞれ専用の SSH ホストを使用し、サーバーが直接公開されることはありません。
セキュリティ上の取り組み
- 外部認証情報は制限的なファイルモードで管理し、JSON に保存しません。
- 起動時に、設定された ID が
expected_tenant_idと一致することを検証します。 - ベアラートークンには、ツールとテナントの正確なスコープが設定されます。
- リクエスト、レスポンス、ページのサイズには上限があります。
- 監査の帰属情報は認証情報を安全に扱い、対象値には HMAC による秘匿化を適用します。
- 変更には、2 人の異なるプリンシパルによる準備 → 承認 → 適用の変更管理が必要です。
- デプロイを直接行うツールや、認証なしで書き込みを行う経路はありません。
- ワイルドカードのトークンスコープでは、書き込みツールは付与されません。
--tools '*'で有効になるのは読み取り専用の機能のみです。トークンの発行時には、各書き込みツールを明示的に指定する必要があります。
デプロイ、復旧、監査ログの保持、書き込みワークフローに関する詳細なガイダンスは、docs/operations.md を参照してください。
--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 rustsdcmcp
ExecStart を置き換える場合は、コマンド全体を記述し直す必要があります。そのため、短縮したコマンドを書くのではなく、同梱されているコマンドをコピーしてフラグを追加してください。--audit-* 引数を省略すると、ラボモードを有効にした副作用として、HMAC のターゲット秘匿化と構造化された journald 監査が無効になります。
[Service]
# Clear the shipped ExecStart before replacing it; systemd appends otherwise.
ExecStart=
ExecStart=/usr/local/bin/rustsdcmcp \
--device-mapping /etc/rustsdcmcp/sdc.json \
--transport streamable-http \
--host 127.0.0.1 \
--port 30032 \
--tokens-file /etc/rustsdcmcp/tokens.json \
--audit-format json \
--audit-journald \
--audit-redact devices=hmac \
--audit-hmac-key-file /etc/rustsdcmcp/audit-hmac.key \
--lab-mode
適用する前に packaging/systemd/rustsdcmcp.service と照合してください。同梱されている引数が正しい情報源です。このスニペットはコピーであり、古くなる可能性があります。
sudo systemctl daemon-reload && sudo systemctl restart rustsdcmcp
設定が反映されたことを確認します。起動時の2つの記録では表記が異なります。警告では --lab-mode、解決済み設定の行では lab_mode が使われているため、両方を照合してください。また、システムユニットを確認できる十分な権限でジャーナルを読み取ります。
sudo journalctl -u rustsdcmcp -b | grep -E 'lab.mode'
{"level":"WARN","fields":{"message":"--lab-mode: two-person control is DISABLED. …"}}
{"level":"INFO","fields":{"message":"change-control configuration resolved","lab_mode":true,…}}
何も表示されなければ、無効です。権限がないために、権限のないユーザーによる journalctl が何も表示しない場合もあります。そのため、コマンドでは sudo を使用しています。
承認が免除された変更セットは、prepare_sdc_policy_deploy から直接 "state": "approved"、"approver": null、"approval_waiver": "lab-mode" を返します。apply_sdc_change_set では、別途承認を呼び出す必要はありません。
サービスではなく一時的に実行する場合も、同じ方法でコマンドラインに --lab-mode を指定します。
優先順位
--lab-mode は、--state-file および --approval-timeout-secs と同様に、mecmcp 共通の変更セット CLI 標準の一部です。他の2つのフラグについては、明示的に指定されたフラグが優先され、指定がない場合は sdc.json の値(changeset_state_file、approval_ttl_secs)が使われます。
--lab-mode は CLI 専用です。 意図的に sdc.json には対応するフィールドがありません。セキュリティ制御を緩和するには、何か月も前に編集された設定ファイルから引き継ぐのではなく、オペレーターが確認できるユニットに入力する必要があります。共通標準で製品設定へのフォールバックが許可されるかどうかは、上流で未解決の問題です(mecmcp#267)。このサーバーでは保守的な解釈を採用しています。
デプロイの成熟度
Debian 13 パッケージは、CI が ea81805d2b4b97df9bdd3f70423e047524896a3d 用にビルドしたコミット指定アーカイブからインストールされ、エンドツーエンドで実行されています。パッケージに含まれる rustsdcmcp.service ユニットのもとで、root 以外のアカウントとして起動し、ループバック専用のエンドポイントにバインドし、ベアラーによる境界を強制し、稼働中の SDC に対する起動時のテナントスコープ検査に合格します。
パッケージに関する制限をひとつ、明確にしておく必要があります。ユニットの IPAddressAllow と IPAddressDeny の行は、ホストが systemd による cgroup BPF プログラムのアタッチを許可している場合にのみ有効になります。これは実行環境によって異なります。検証済みのデプロイでは、インストーラーのプローブ結果が NOT ENFORCED だったため、ユニットの外部でエグレスを強制する必要がありました。それ以外のサンドボックスディレクティブはすべて適用されていました。自分のホストでどちらになるか決めつけず、プローブの結果に従ってください。デプロイ、復旧、監査ログの保持、および実行環境ごとのエグレス制御方式については、docs/operations.md を参照してください。
具体的なホスト、アドレス、コンテナー識別子は、意図的にここでは公開していません。各オペレーターがそれぞれの情報を用意してください。
ロードマップ
現在の対応状況、今後の拡張予定、上流 API のサポート待ちとなっている機能については、ROADMAP.md を参照してください。機能のリクエストは GitHub の Issue で受け付けています。
mecmcpとの関係
mecmcpは、mechub MCP サーバーファミリーで共有される、ベンダーに依存しないRust基盤です。このリポジトリはこれをフォークせず、利用しています。mainでは、共有される8つのクレート(mecmcp-audit、mecmcp-auth、mecmcp-changeset、mecmcp-redact、mecmcp-runtime、mecmcp-secret、mecmcp-server、mecmcp-transport)すべてをv0.27.0に固定しています。
**互換性を妨げていた問題は解消されました。**このセクションの以前の版では、一貫性のある上流リリースによって59個の一時的な互換性宣言が置き換えられるまで、リリースは保留されると記載していました。その対応は完了しています。mecmcp 0.7.2への移行時に#36でローカルのcompat/レイヤーが削除され、0.8.0への移行時に369f9bbで互換性台帳自体も削除されました。一時的な互換性シンボルは残っておらず、追跡対象となる台帳もありません。
APIの出典
APIサーフェスは、JuniperのOpenAPI 3エクスポートを基に固定しています。エクスポートはdocs/sdc-api/にベンダー管理されています。これは、サポート対象のSDC APIサーフェスと、未解決の課題を網羅した正式な一覧です。
主な参考資料:
イベントストアへの監査ログ転送
監査証跡はこのホストには残りません。このサーバーはファミリー標準に準拠しています — AUDIT-FORWARDING-STANDARD.md。
生成元のマシンにしか存在しない監査レコードは、監査証跡とは言えません。記録の対象となる当事者が運用するマシン上のログファイルにすぎません。
出力(現在有効)
--audit-format json \
--audit-log-file /var/lib/rustsdcmcp/audit.jsonl
JSONは必須です。text形式はターミナルで読むためのものであり、解析対象ではありません。ファイルは運用者向けの成果物なので、ローテーションが必要です。サーバーがファイルを切り詰めることはありません。
転送
SSDFの統合証拠契約に従い、レコードはSSDFのssdf.auditにハッシュチェーン化された行として直接書き込まれます。これにより、行の削除や編集を検出できます。この機能は実装済みです。証拠転送が設定されている場合、起動時にサーバーがEvidenceService/EvidenceHttpTransportのペアを接続します(crates/rustsdcmcp/src/main.rs)。これはmecmcp#292でSSDFの証拠パイプラインとして実装されました。
より低コストなsyslog経路も設計されましたが、採用されませんでした。動作はしますが、レコードがチェーン化されないためです。ここでの他のすべてのリンクは、設計上、改ざんを検知できます。プランのダイジェストは承認に紐付き、承認には個別のプリンシパルが記録され、token_verified_fieldsは保証された出所情報と申告された情報を区別します。最後のホップをチェーン化しなければ、監査者が最も必要とする箇所で、その保証が失われます。判断の理由は標準に記録されています。
結果の読み取り
token_verified_fieldsは、トークンが保証した出所情報のフィールドを示します。同じグループの残りのフィールドであるclient_name、model_id、session_idはクライアントが申告したものであり、何によっても認証されていません。同等のものとして扱わないでください。
request_idは、転送イベント、ハンドラーイベント、および(Junosの場合)デバイスのコミットコメントを相互に関連付けます。
ライセンス
MITの下でライセンスされています。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。