tenantguard について
TenantGuardは、セルフホスト型のマルチテナントAIエージェント基盤を監査するCLIツールです。16件のフェイルクローズ型テナント分離ルールで設定を検査し、運用担当者やセキュリティレビュー向けにターミナル、JSON、SARIF形式で結果を出力します。
主な機能
- 0116ルールによる設定監査
- 02テナント境界とネットワーク露出の検査
- 03ターミナル・JSON・SARIFレポート
- 04同梱デモ環境のスキャン
- 05暫定的なHIPAA引用の追加
活用シーン
- 01セルフホスト型エージェント基盤の監査
- 02コードスキャン用SARIFの生成
- 03スクリプトやエージェントへの構造化結果の提供
- 04同梱デモを使ったスキャナーのテスト
MCP 対応
TenantGuardは標準入出力でMCPサーバーとして動作し、スキャンエンジンをAIエージェント向けのツールとして公開します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
TenantGuard
インストール • クイックスタート • 機能 • CLI リファレンス • MCP サーバー • 比較 • FAQ
監査担当者や攻撃者に見つかる前に、セルフホスト可能なマルチテナント AI エージェントプラットフォームのテナント分離の不備を見つけましょう。

インストール
npm install -g tenantguard-cli
こちらが推奨されるインストール方法です。tenantguard-cli npm パッケージ(現在のバージョンは 0.2.0。非推奨の旧名称 tenantguard から変更されました)は、対応するプラットフォーム用バイナリを npm の optionalDependency として取得します(公開時に cosign で検証済みのため、個別の検証作業は不要です)。また、PATH に tenantguard コマンドを追加します。
対応プラットフォーム:Intel および Apple Silicon 搭載の macOS、x64 および arm64 の Linux、x64 および arm64 の Windows。
go install github.com/RudrenduPaul/TenantGuard/cmd/[email protected]
go install は Go がサポートするすべてのプラットフォームで動作し、レジストリへの公開状況にも依存しないため、上記に対応プラットフォームがない場合の代替手段になります。
トップレベルパッケージを使わず、単一のプラットフォーム用バイナリパッケージを直接インストールすることもできます。
npm install tenantguard-darwin-arm64 # swap for your platform: darwin-x64, linux-x64, linux-arm64, win32-x64, win32-arm64
./node_modules/tenantguard-darwin-arm64/bin/tenantguard scan --demo
Python(pip / uvx)
pip install tenantguard-cli
uvx --from tenantguard-cli tenantguard scan --demo
PyPI パッケージ tenantguard-cli は、このリポジトリの python/ にあり、CI でビルドおよびテストされています。現在のバージョンは 0.1.6 です。npm パッケージと同じ GitHub Releases バイナリの v0.2.0 ビルドをダウンロードして実行し、初回実行時にリリースの SHA-256 checksums.txt を検証します(そのファイル内のダイジェストを信頼する前に、ファイル自体も Sigstore 署名で検証されます)。その後、検証済みのバイナリをローカルにキャッシュします。これは、公開時に cosign で検証済みのバイナリを埋め込み、実行時のダウンロードが一切不要な npm パッケージとは、信頼境界が異なります。PyPI ラッパーのチェックサム検証は、エンドユーザーのマシン上でバイナリを取得する必要がある方式に対する、同等の保証となります。
PyPI の 0.1.2 以下のバージョンには不具合があり、pip install tenantguard-cli は成功するものの、初回実行時に tenantguard scan --demo が could not parse checksums.txt.pem as a PEM certificate というエラーで失敗していました(ラッパーが、cosign によって生成された証明書と署名のリリースアセットを解析前に base64 デコードしていませんでした)。この問題は tenantguard-cli 0.1.3 で修正され、2026-08-03 に PyPI で公開されました。現在は pip install tenantguard-cli を実行するだけで、追加の手順なく動作するツールをインストールできます。
クイックスタート
tenantguard scan --demo
実際に取得された出力:
TenantGuard: Tenant-Isolation Audit
Target: /var/folders/m0/5tzdd47n6znb166d4w3m2q0c0000gn/T/tenantguard-demo-488625596
[FAIL] TA01 sandbox/workspace mount path is not scoped per-tenant (no ${TENANT_ID} placeholder and no explicit scoped_per_tenant declaration)
.../deployment.yaml:12
Maps to: goclaw#1163 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[FAIL] TA02 MCP tool URL targets a private/loopback/reserved address (via real CIDR containment on a literal or DNS-resolved IP) without a verified, IP-pinned SSRF validator or an explicit host allowlist entry. CAVEAT: a PASS trusts the deployment's own pins_resolved_ip/validates_private declaration -- TenantGuard cannot verify the real validator actually pins the resolved IP for the connection itself, so DNS-rebinding/TOCTOU risk persists if that declaration is inaccurate
.../deployment.yaml:22
Maps to: goclaw#1070 | HIPAA Sec164.312(e)(1) Transmission Security (provisional)
[FAIL] TA03 cron binding's target agent does not belong to the declaring tenant
.../deployment.yaml:35
Maps to: goclaw#1217 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[FAIL] TA04 exec tool denies direct env dump but not indirect env reads (e.g. jq $ENV), or allows credential-chain leakage via allow_chain_exec (goclaw#1033)
.../deployment.yaml:25
Maps to: goclaw#1227 | HIPAA Sec164.312(a)(2)(iv) Encryption/Decryption (provisional)
[FAIL] TA05 exec-approval allow-always entry is keyed on basename only, not a full path scope
.../deployment.yaml:30
Maps to: goclaw#1216 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[FAIL] TA09 sandbox fail-closed posture not declared (sandbox.on_unavailable must be "fail_closed")
.../tenantguard-demo-488625596:0
Maps to: goclaw#246 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[FAIL] TA10 agent does not explicitly declare a per-agent config override (workspace restriction or sandbox config), risking silent inheritance of an undeclared global default
.../deployment.yaml:40
Maps to: goclaw#145 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[FAIL] TA13 MCP/CLI bridge does not declare HMAC-signed context headers (bridge.hmac_enabled and bridge.context_headers_signed)
.../tenantguard-demo-488625596:0
Maps to: goclaw#91 | HIPAA Sec164.312(e)(1) Transmission Security (provisional)
[FAIL] TA06 cron binding does not declare that its store layer captures/replays the human creator's sender identity at fire time
.../deployment.yaml:35
Maps to: goclaw#1129 | HIPAA Sec164.312(b) Audit Controls (provisional)
[FAIL] TA07 sandbox container privilege is not hardened (root user by default, full host-env passthrough, tmpfs missing noexec/nosuid/nodev, or a dangerous Linux capability added)
.../deployment.yaml:12
Maps to: goclaw#1014 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[FAIL] TA11 channel/session device identity is shared across channel_instances declaring different tenants
.../deployment.yaml:54
Maps to: goclaw#1064 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[FAIL] TA11 channel/session device identity is shared across channel_instances declaring different tenants
.../deployment.yaml:57
Maps to: goclaw#1064 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[FAIL] TA15 channel_instances entry does not declare reload_strategy: differential, so any single create/update/delete on that entry triggers a full stop/restart of every running channel instance across all tenants (no per-instance fingerprint/diff step). CAVEAT: a PASS trusts the deployment's own reload_strategy declaration -- TenantGuard cannot verify the real InstanceLoader actually performs a differential (fingerprint-diffed) reload rather than the destructive full rebuild, so a mismatched declaration would still scan clean
.../deployment.yaml:54
Maps to: goclaw#1147 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[FAIL] TA15 channel_instances entry does not declare reload_strategy: differential, so any single create/update/delete on that entry triggers a full stop/restart of every running channel instance across all tenants (no per-instance fingerprint/diff step). CAVEAT: a PASS trusts the deployment's own reload_strategy declaration -- TenantGuard cannot verify the real InstanceLoader actually performs a differential (fingerprint-diffed) reload rather than the destructive full rebuild, so a mismatched declaration would still scan clean
.../deployment.yaml:57
Maps to: goclaw#1147 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[PASS] 1 check(s) clear
Summary: 14 FAIL, 1 PASS
Findings map to confirmed open goclaw issues where applicable. HIPAA citations are provisional, see README.
同梱のフィクスチャには、意図的にノイズが含まれています。これは、ほぼすべてのルールを一度に検証するためのものです。TA08(認証情報ストレージの暗号化)とTA14(エージェントごとのリソースプロファイルの分離)は、スキャン対象の設定内にある providers と resource_profiles の各エントリーに対してのみ実行されるチェックです。このフィクスチャには、どちらの種類のエントリーも存在しないため、両ルールは評価対象がなく、検出結果は一切出力されません。PASS も FAIL も出力されません。TA16(プロバイダー接続の SSRF)も、providers エントリーに対する同種のチェックのため、このフィクスチャでは何も出力されません。合格として表示されている「1 check(s) clear」は、TA12(所有者/システム管理者による復旧)です。このフィクスチャでは、owner_ids と has_recovery_command の値を意図的に条件を満たすよう設定しています。検出結果があるため、終了コードは 1 です。終了コードの仕様については、CLI リファレンスを参照してください。
実際のデプロイをスキャンし、コードスキャン用の SARIF を出力するには、次のようにします。
tenantguard scan --target ./deployment --format sarif --sarif-out tenantguard-report.sarif

スクリプトやエージェントで SARIF ドキュメントではなくフラットな検出結果の配列を解析したい場合は、プレーン JSON を出力することもできます。
tenantguard scan --target ./deployment --format json

機能
TenantGuard は、セルフホスト型のマルチテナント AI エージェントのデプロイ設定を、実際に確認されたテナント分離の障害モードに基づく16個のルールでスキャンします。すべてのルールはフェイルクローズ方式です。設定が宣言されていない、または曖昧な場合は、黙って合格とせず違反として扱います。
テナント分離境界
| ルール | 検出する内容 |
|---|---|
| TA01 | サンドボックス/ワークスペースのマウントは、そのパスに ${TENANT_ID} スコープ指定プレースホルダーが含まれているか、scoped_per_tenant が明示的に true と宣言されていない限り、違反となります。goclaw#1163 に対応します。 |
| TA03 | cron バインディングの target_agent は、そのバインディングを宣言したテナントに属している必要があります。参照先が存在しない場合や、別テナントへの参照はフェイルクローズ方式で失敗します。goclaw#1217 に対応します。 |
| TA11 | 同じ device_session_id を共有しながら、異なるテナントを宣言している2つの channel_instances エントリー(例:共有 WhatsApp デバイスの行)を検出します。goclaw#1064/#1065 に対応します。 |
| TA14 | エージェントごとのリソースプロファイル(ブラウザー/コンテナー)は、そのパスに ${TENANT_ID} プレースホルダーが含まれていない限り、違反となります。goclaw#778 に対応します。 |
| TA15 | reload_strategy: differential が明示的に宣言されていない channel_instances エントリーを検出します。値が宣言されていない場合も full の場合も、そのエントリーで作成/更新/削除のいずれかが1件発生すると、すべてのテナントにわたって実行中のすべてのチャネルインスタンスが破壊的な完全停止/再起動を起こすことを意味します。デプロイ側の宣言を信頼します(TenantGuard は、実際のローダーがフィンガープリントによる差分更新を行うかどうかを検証できません)。goclaw#1147 に対応します。 |
ネットワークと認証情報の露出
| ルール | 検出対象 |
|---|---|
| TA02 | 保存された MCP ツールの URL が、プライベート/ループバック/予約済みアドレスを指定している場合に検出します。文字列照合ではなく、リテラルまたは DNS で解決した IP に対する実際の net.cidr_contains を使用します。ただし、デプロイメントで validates_private と pins_resolved_ip の両方が宣言されている場合、またはホストが明示的に許可リストに登録されている場合を除きます。DNS リバインディング/TOCTOU の制約についても明示的に記載します。goclaw#1070 に対応します。 |
| TA04 | exec ツールが環境変数の直接的なダンプ読み取りを拒否しても、間接的な読み取り(例:jq $ENV)は拒否していない場合に検出します。また、シェル演算子チェーン内のすべてのコマンドに認証情報の環境変数が漏えいするため、allow_chain_exec: true を設定したツールも個別に検出します。goclaw#1227 および goclaw#1033 に対応します。 |
| TA08 | 保存された OAuth/認証情報トークンに対して、認識済みの強力な暗号化アルゴリズム(現在は aes-256-gcm のみ)を宣言していないプロバイダー設定は、違反とみなされます。goclaw#65 に対応します。 |
| TA16 | プロバイダー(例:litellm、bifrost)の接続 URL が、プライベート/ループバック/予約済みアドレスを指定している場合に検出します。MCP ツールに TA02 が適用するものと同じ net.cidr_contains ベースのロジックを使用します。ただし、デプロイメントで validates_private と pins_resolved_ip の両方が宣言されている場合、またはホストが明示的に許可リストに登録されている場合を除きます。goclaw#1430 に対応します。 |
実行と承認の強化
| ルール | 検出対象 |
|---|---|
| TA05 | フルパスではなくベース名だけをキーにした「常に許可」の exec 承認は、同じベース名を持つ別の実行ファイルに対して再利用できるため、違反とみなされます。goclaw#1216 に対応します。 |
| TA07 | デフォルトでの root 実行、ホスト環境全体の引き継ぎ、noexec/nosuid/nodev が設定されていない tmpfs マウント、または追加された危険な Linux ケイパビリティ(SETUID、SETGID、CHOWN、SYS_ADMIN、DAC_OVERRIDE、NET_ADMIN、SYS_PTRACE)を検出します。goclaw#1014、#1015、#524 に対応します。 |
| TA09 | デプロイメントでは sandbox.on_unavailable: fail_closed を明示的に宣言する必要があります。宣言がない値は、見逃しとして扱わず、違反とみなします。goclaw#246 に対応します。 |
アイデンティティ、監査、復旧
| ルール | 検出する問題 |
|---|---|
| TA06 | captures_creator_identity が設定に宣言されていない cron バインディングは違反です。これがないと、グループコンテキストのジョブは実際の作成者である人間ではなく、system アイデンティティで実行されます。goclaw#1129 に対応します。 |
| TA12 | デプロイメントレベルのチェックです。owner_ids が空、または復旧/リセットコマンドが宣言されていない場合は、オペレーターが恒久的にロックアウトされるおそれがあるため違反です。goclaw#954 に対応します。 |
| TA13 | デプロイメントレベルのチェックです。bridge_hmac_enabled または bridge_context_headers_signed が true と宣言されていない場合は違反です。宣言がない場合はデフォルトで署名なしとなり、違反になります。黙って合格することはありません。goclaw#91 に対応します。 |
| TA10 | ベストエフォートの静的設定プロキシです。エージェントのエントリーに has_workspace_restriction_override または has_sandbox_config_override が明示的に宣言されていない場合に警告します。goclaw#145 に対応します。 |
その他に確認済みの機能:
- SARIF 2.1.0 出力(
--format sarif)。スキーマに準拠し、実際のバイト/行位置とメッセージを含みます。github/codeql-action/upload-sarifや GitHub コードスキャンですぐに使用できます。 - プレーンな JSON 出力(
--format json)。スクリプトや、SARIF のツール/実行/ルール/分類のオブジェクトモデルを必要とせず、生のrule_id/status/file/lineの結果だけを必要とするエージェント向けの、SARIF より軽量なスキーマの代替形式です。FAIL のみを「結果」として報告する SARIF とは異なり、JSON モードではすべての PASS も含まれ、summary.fail/summary.passの件数も出力されます。v0.2.0 以降で利用できます。CLI リファレンスの注記を参照してください。 - すべての検出結果に対する暫定的な HIPAA 引用(
--control hipaa)。ルールごとに対応付けられ、暫定として示されます(FAQを参照)。 - セットアップ不要のデモモード(
--demo)。バンドルされた合成デプロイメントをスキャンするため、対象の設定は不要です。 - GitHub Action(
action/action.yml)。固定されたバージョンをgo installでインストールし、SARIF レポートを自動でアップロードします。 - MCP サーバーモード(
tenantguard mcp)。同じスキャンエンジンを、tenantguard scanと人間が入力する方法だけでなく、AI エージェントが stdio 経由で直接呼び出せるツールとして公開します。v0.2.0 以降で利用できます。以下のMCP サーバー(エージェントネイティブな使用方法)を参照してください。
CLI リファレンス
TenantGuard には、scan(監査そのもの)と mcp(同じスキャンエンジンを stdio 経由で MCP サーバーとして実行します。MCP サーバー(エージェントネイティブな使用方法)を参照)の 2 つのサブコマンドがあります。トップレベルの --help または --version フラグはありません。引数なしで tenantguard を実行した場合、tenantguard --help を実行した場合、または最初の引数が scan でも mcp でもない場合は、以下の使用方法が stderr に出力され、終了コード 2 で終了します。
メモ
バージョンに関する注記: 以下に示す
--format jsonとmcpサブコマンドは v0.2.0 以降に含まれます。これはnpm install -g tenantguard-cli(0.2.0)、pip install tenantguard-cli(0.1.6。v0.2.0 のバイナリをダウンロードします)、およびgo install .../cmd/[email protected]でインストールされるバージョンです。それ以前のバージョン(0.1.x の npm パッケージおよびv0.1.1の Go タグ)にはこれらの機能はありません。--format jsonは無視され、mcpはサブコマンドとして認識されません。
usage: tenantguard scan [--target DIR | --demo] [--format terminal|sarif|json] [--control hipaa]
tenantguard mcp
tenantguard scan --help の出力:
Usage of scan:
-control string
compliance framework to cite (hipaa)
-demo
scan a bundled synthetic deployment instead of --target (zero setup)
-format string
output format: terminal, sarif, or json (default "terminal")
-sarif-out string
file to write SARIF output to when --format=sarif (default "tenantguard-report.sarif")
-target string
path to the deployment config directory to scan
終了コード(cmd/tenantguard/main.go で定義):
| コード | 意味 |
|---|---|
0 | スキャンに問題はなく、検出結果もありません |
1 | スキャンは正常に実行されましたが、検出結果があります |
2 | スキャンまたは使用方法のエラー |
MCP サーバー(エージェントネイティブな使い方)
メモ
v0.2.0 以降で利用できます。
mcpサブコマンドは、インストールに記載されている npm、PyPI、go installのリリースに含まれています。v0.2.0 より前のバージョンには含まれておらず、実行しようとすると使用方法エラーが表示されます。
ここまではすべて、人がターミナルで tenantguard scan と入力することを前提としていました。TenantGuard は MCP サーバーとしても動作するため、AI エージェント(コーディングアシスタント、運用エージェント、Model Context Protocol に対応したあらゆるもの)は、CLI をシェル経由で実行してテキストを解析する代わりに、ツール呼び出しとしてスキャンエンジンを直接呼び出せます。
tenantguard mcp
これは stdio 上で MCP サーバーを起動し、クライアントが切断されるまでブロックします。これは、ほかの stdio ベースの MCP サーバーがクライアントのプロセス管理下で動作するのと同じです。フラグや位置引数は必要ありません。内部では、CLI の scan サブコマンドが実行するのとまったく同じ internal/collector -> internal/policy -> internal/compliance -> internal/report パイプラインを、薄いプロトコルアダプター(internal/mcpserver)で包んでいます。同期を保つ必要のある個別のルール評価ロジックはありません。
3 つの引数を持つ単一のツール scan を公開しており、各引数は CLI のフラグに対応しています。
| 引数 | 対応する項目 | 備考 |
|---|---|---|
target | --target | 必須です。スキャン対象のデプロイ設定ディレクトリのパスです。 |
format | --format | 任意です。json、sarif、terminal のいずれかです。MCP ではデフォルトで json です(CLI 自体のデフォルトは terminal です)。呼び出し元のエージェントは、人間向けに整形されたレポートよりも構造化出力を必要とすることがほとんどだからです。 |
control | --control | 任意です。現在認識されるのは hipaa のみです。空の値も CLI と同様に hipaa がデフォルトになります。 |
json と sarif の出力では、結果はテキストと MCP の StructuredContent の両方で返されます。そのため、フィールド(rule_id、status、file、line)を直接読み取りたいクライアントは、テキストブロック自体を再解析する必要がありません。ツールレベルの失敗(不正なターゲットパス、ポリシーの読み込みエラーなど)は、プロトコルレベルの失敗ではなく、通常の MCP エラー結果として返されます。そのため、呼び出し元のエージェントは「スキャン失敗」をほかのツール呼び出しの失敗と同じように処理できます。
TenantGuard を Claude Desktop などの MCP 互換クライアントに登録するには、クライアントのサーバー設定に追加します。
{
"mcpServers": {
"tenantguard": {
"command": "tenantguard",
"args": ["mcp"]
}
}
}
この設定では、tenantguard がすでに PATH に含まれていることを前提としています(インストールを参照)。別の場所にインストールした場合は、"command" をバイナリのフルパスに置き換えてください。
この機能が提供される前は、人が CLI を直接実行する方法でしかスキャンできませんでした。tenantguard mcp を使えば、エージェントはツールとして scan を呼び出し、構造化された検出結果を受け取り、同じセッション内でそれに対応できます。人がターミナルの出力を読んで次のコマンドを手入力する必要はありません。
TenantGuard の比較
| ツール | 対象 | マルチテナントの AI エージェントに対応 | SARIF 出力 | ルール数 | プロジェクトの成熟度 |
|---|---|---|---|---|---|
| TenantGuard | セルフホスト型マルチエージェントプラットフォームのテナント分離設定の監査 | はい。この用途に特化して構築されています | はい。検証済み(SARIF 2.1.0) | 16。すべてテナント分離に特化 | npm/PyPI で公開中(上記のバッジを参照)。GitHub タグ付きリリースが 3 件(v0.1.0、v0.1.1、v0.2.0) |
| Checkov | 汎用 IaC/クラウド設定ミススキャナー(Terraform、CloudFormation、Kubernetes、Dockerfile など) | いいえ。README ではマルチテナントの AI エージェントプラットフォームにも、テナント分離チェックにも言及していません | はい。検証済み(-o sarif) | 1,000 以上。汎用クラウド/IaC ポリシー | GitHub スター 8.9k、長年の実績があり、活発にメンテナンスされています |
| Conftest | 構造化設定データ(18 種類以上の入力形式)を対象とする、OPA/Rego ポリシーテストツールの代表例 | いいえ。他のツールがポリシーパックの構築に利用する汎用 Rego テストハーネスであり、組み込みのテナント分離機能や AI エージェント用ルールパックはありません | はい。検証済み(-o sarif、SARIF 2.1.0) | 組み込みルールは 0(ルールパックではなく、ポリシーテストエンジンです) | OPA の代表的なプロジェクトとして長年の実績があり、活発にメンテナンスされています |
| PolicyGuard | Terraform/OpenTofu の AWS/Azure 設定ミススキャナー(Go + OPA/Rego、Cobra CLI、サンドボックス化された OPA エンジン) | いいえ。Terraform/OpenTofu の AWS/Azure リソースに対象を限定しており、マルチテナントシステムや AI エージェントプラットフォームへの言及はありません | はい。検証済み(安定したフィンガープリントと CWE タグを含む SARIF 2.1.0) | AWS/Azure リソースのチェックが 15 件以上 | スター 1、フォーク 2、リリース 4 件(v0.3.1) |
| AgentShield | AI エージェントのセキュリティスキャナー(シークレット、権限、フック、MCP サーバーのセキュリティ、エージェント設定のレビュー) | いいえ。単一の Claude Code ユーザーのローカルな .claude/ ディレクトリ(単一ユーザー/チームの開発環境)を明示的に対象としており、マルチテナント SaaS の分離は対象外です | はい。検証済み(--format sarif、SARIF 2.1.0) | 5 つのカテゴリにわたって 102 件 | GitHub スター 1,000 以上、活発にメンテナンスされています(2026 年 2 月のハッカソンで開発が始まりました) |
TenantGuard は広さより深さを重視しています。16 個のルールは Checkov の 1,000 以上と比べればごく一部であり、TenantGuard のタグ付きリリースは 3 回に対して、Checkov、Conftest、PolicyGuard にははるかに長い実績があります。ほかのツールにはない TenantGuard の特徴は、セルフホスト型 AI エージェントのデプロイにおけるテナント間の分離に特化したルールパックを備えていることです。これは汎用 IaC スキャナーでは対象外であり、最も近い分野の AgentShield でさえ対象としていません。AgentShield が監査するのは開発者 1 人のローカル設定であり、セルフホスト型のマルチテナントデプロイにおけるテナント間の分離ではありません。TenantGuard が狙うのは、意図的に対象を絞ったこの領域です。
ラベル付きフィクスチャを用いた TenantGuard 独自のルールセットの適合率/再現率ベンチマークは、まだ公開されていません。上記の競合製品が数値(例:PolicyGuard の適合率/再現率)を示している場合、その数値は当プロジェクトで独自に再検証したものではなく、各プロジェクトの README から引用しています。
TenantGuard とは何か、なぜ存在するのか
TenantGuard は、Go で記述され、OPA/Rego を基盤とする、コマンドラインのポリシー・アズ・コードスキャナーです。セルフホスト型のマルチテナント AI エージェントプラットフォームの設定を監査し、テナント分離の不備、つまり、あるテナントのエージェント、サンドボックス、cron ジョブ、または認証情報が別のテナントにアクセスしたり、影響を及ぼしたりできる種類のバグを検出します。
TenantGuard が存在するのは、実在が確認されたマルチテナント AI エージェントプラットフォーム(goclaw)で、まさにこのカテゴリに属する未解決の課題が複数公開されているためです。これには、テナントごとにスコープされていないサンドボックスマウント、エージェント間の認可の欠落、間接的な経路でシークレットを漏えいする exec ツール、実際のパススコープではなくファイル名を基準にした承認の回避、保存済みツール URL および LLM プロバイダー接続における SSRF 検証の不一致が含まれます。既存の汎用 IaC スキャナー(Checkov、Conftest、PolicyGuard)にも、AI エージェント向けセキュリティスキャナー(AgentShield)にも、セルフホスト型のマルチエージェントデプロイメントにおけるテナント間分離という、この特定の障害カテゴリをチェックするものはありません。TenantGuard は、実在する引用付きの課題にそれぞれ追跡可能な、フェイルクローズ方式の 16 個のルールでこのギャップを埋めます。
TenantGuard は汎用の Terraform/Kubernetes スキャナーではなく、一般的なクラウドインフラストラクチャの設定ミスに対する Checkov や Conftest の代替でもありません。セルフホスト型のマルチテナントエージェントデプロイメントにおけるテナント分離の領域に特化しています。
よくある質問
TenantGuard は Checkov や Conftest のような汎用 IaC スキャナーとどう違いますか? Checkov と Conftest は、一般的なインフラストラクチャ・アズ・コード(Terraform、Kubernetes、CloudFormation など)をスキャンし、幅広いカテゴリの設定ミスを検出します。どちらにも、マルチテナント AI エージェントデプロイメント向けのルールパックは付属していません。TenantGuard の 16 個のルールは、この領域に特化して作られています。サンドボックスマウント、cron/エージェントのバインディング、MCP ツールの登録、LLM プロバイダー接続、exec の承認、チャネル/セッションの ID を対象とし、それぞれ実在する引用付きの不備に基づいています。
TenantGuard は OPA や Conftest の代わりになりますか? いいえ。TenantGuard のルールは Rego で記述されており、TenantGuard は独自の評価経路をバンドルしています。これは特定の用途に合わせたポリシーパックおよび CLI であり、汎用の Rego テストハーネスではありません。任意の構造化設定を任意の Rego ポリシーに照らしてテストする必要がある場合は、汎用ツールとして Conftest が適しています。マルチエージェントデプロイメントのテナント分離チェックには、TenantGuard が適しています。
各検出結果に記載された HIPAA の引用は何を意味しますか? すべての検出結果には、技術的な検出結果を、レビュー担当者がすでに追跡している可能性のあるコンプライアンス管理策に対応付けるため、関連する HIPAA セキュリティルールの引用(例:Sec164.312(a)(1) アクセス制御)が付記されています。これらの引用は暫定的なものです。技術的な管理策と引用された HIPAA の条項との妥当と思われる対応関係を示すものであり、法的な判断や監査済みのコンプライアンス判定を示すものではありません。自社のコンプライアンスレビューの出発点として扱い、その代わりとして使用しないでください。
TA02(SSRF)が PASS なら、MCP ツールの URL は DNS リバインディングから完全に安全だという意味ですか?
完全に安全という意味ではありません。TA02 は文字列照合ではなく、リテラルまたは DNS 解決済み IP に対する実際の CIDR 包含判定を使用しますが、PASS はデプロイメントの pins_resolved_ip/validates_private 宣言を信頼します。TenantGuard は、実際のバリデーターが実際の接続に対して解決済み IP を固定することを独立して検証できないため、その宣言が不正確な場合は、DNS リバインディング/TOCTOU のリスクが残ります。この制限は TA02 ルールに直接記載されています。
同梱のデモではなく、実際のデプロイメントをスキャンできますか?
はい。tenantguard scan --target <path-to-deployment-config-dir> を実行してください。実際の設定を指定する前に、セットアップなしでツールを実行できるように、--demo が用意されています。
TenantGuard は CI パイプラインや GitHub コードスキャンで利用できる出力を生成しますか?
はい。--format sarif --sarif-out <file> を指定すると、実際の結果位置とメッセージを含む、スキーマに準拠した SARIF 2.1.0 ドキュメントを生成します。同梱の GitHub Action(action/action.yml)は、スキャンを実行し、github/codeql-action/upload-sarif を使って SARIF レポートを 1 ステップでアップロードします。
TenantGuard に --format sarif と --format json の両方があるのはなぜですか?SARIF も構造化出力ではありませんか?
はい。SARIF は実際に標準化された機械解析可能な形式であり、CI/コードスキャンとの連携に適しています。--format json は、別の用途向けに用意されています。これは、SARIF のツール/実行/ルール/タクソノミーのオブジェクトモデルを先にたどらずに、rule_id/status/file/line を直接解析したいスクリプトやエージェント向けです。また、すべての PASS と FAIL を出力します。SARIF では意図的にそうしていません(SARIF の結果は見つかった問題を表し、チェック項目の完全な一覧ではないためです)。そのため、呼び出し側は 1 つのドキュメントから「何をチェックしたか」だけでなく、「何を問題として指摘したか」も確認できます。注:--format json は v0.2.0 以降で利用できます。CLI リファレンスの注記を参照してください。
CLI の終了コードは何を意味しますか?
0 は問題が見つからなかった正常なスキャン、1 はスキャンが正常に実行され、違反が見つかったことを意味します。2 はスキャンまたは使用方法のエラーです(サブコマンドを指定せずに tenantguard を実行した場合や、scan または mcp 以外のサブコマンドを実行した場合を含みます)。
npm パッケージはありますか?
はい。npm install -g tenantguard-cli は公開済み(現在のバージョンは 0.2.0)で、推奨されるインストール方法です(非推奨となった従来の tenantguard から名前が変更されました)。npm の optionalDependency として、対応するプラットフォームバイナリパッケージに依存しています。6 種類すべてのプラットフォームパッケージが公開済みです(macOS x64/arm64、Linux x64/arm64、Windows x64/arm64)。上記のインストールを参照してください。
PyPI パッケージはありますか?
はい。tenantguard-cli は PyPI で公開済みです(現在のバージョンは 0.1.6 で、v0.2.0 のバイナリをダウンロードします。ソースは python/ にあり、CI でビルドとテストを実施しています)。0.1.2 以下には初回実行時のバグがありましたが、0.1.3 で修正されています(上記のインストールを参照してください)。現在は pip install tenantguard-cli ですぐに使用できます。
AI エージェントは、人が CLI コマンドを入力しなくても TenantGuard を直接実行できますか?
はい。tenantguard mcp を使うと、スキャンエンジンを scan ツールとして公開する MCP サーバーが stdio 上で起動します。正確なクライアント設定とツールの引数、および対応するバージョンについては、上記のMCP サーバー(エージェントネイティブな使用方法)を参照してください。
TenantGuard は、自分の Go プログラムにインポートできるライブラリですか?
いいえ。現時点ではできません。cmd/tenantguard 以外のすべての機能(コレクター、コンプライアンスマッピング、デモ用フィクスチャ、ポリシーエンジン、レポートの書式設定)は internal/ にあります。Go のツールでは、これらをこのモジュールの外からインポートできません。TenantGuard は CLI バイナリと GitHub Action として配布されており、インポート可能な Go パッケージではありません。
商用またはクローズドソースの製品で TenantGuard を使用できますか? はい。TenantGuard は Apache License 2.0 のもとでライセンスされており、商用利用、改変、非公開での使用、再配布が認められています。ライセンスに定められた通常の通知および帰属表示の条件(著作権表示とライセンスのコピーの保持、改変したファイルへの明記)に従えば、プロプライエタリ製品や SaaS 製品に組み込んで使用することもできます。ライセンスに記載のとおり、保証はありません。正式な条件の全文については、LICENSEを参照してください。
コントリビューション
コントリビューションを歓迎します。新しいルールの追加方法については、CONTRIBUTING.mdを参照してください。すべてのルールには、リリース前に脆弱なフィクスチャとクリーンなフィクスチャの両方が必要です。
ライセンス
Apache License 2.0。LICENSEを参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。