standard モードは、敵対的な入力や動的な入力に対してはベストエフォートです。以下に挙げる項目のいくつかは、strict または paranoid モードで閉じられる緩和にあたります。該当する箇所ではその旨を明記します。
コマンド解析の制限
バイナリ内部の動作
コマンド文字列に破壊的な操作が現れていなければ、解析からその動作は読み取れません。some-tool --task destructive-cleanup は、CC Safety Net からは安全に見えます。任意のバイナリが実行時に何をするかまでは検査できません。この種の脅威にはサンドボックスを使ってください。
未設定または不透明なコマンドプロキシ
ユーザーの代わりにシェルコマンドを実行するツール(rtk git reset --hard など)は、transparent wrapper として宣言した場合にかぎり解析されます。
git reset --hard と同じように rtk git reset --hard にも適用されます。組み込みの既定値はないので、意図的に信頼するラッパーだけを設定してください。予約済みのコマンド(git、busybox、組み込みの解析対象コマンド、シェルラッパー、インタープリター)はラッパーとして登録できません。
残る制限は「すべてのプロキシ」よりも狭い範囲です。
transparent_wrappersに登録されていないプロキシは透過されません。- 見える形で子コマンドを実行せず、書き換えたり隠したりするプロキシは、設定しても透過できません。
transparent_wrappers は rule.json の中にあるため、rule.json を読み取れないスコープでは、それを直すまでそのスコープのラッパー設定が失われます。設定の復旧を参照してください。
eval と動的実行
実行時にコードを組み立てて実行するコマンドは、完全には解析できません。解析の時点では、実際に実行される文字列がコマンドテキストの中に存在しないためです。bash -c やインタープリターのコード引数を再帰的にスキャンします。しかし、コードをリモートから取得したり変数から組み立てたりする場合、破壊的な処理そのものはコマンド文字列の解析からは見えません。これは、この方式に本質的につきまとう制限です。
パーサーの制限
インタープリターの長形式フラグ
CC Safety Net は、インタープリター(python、python2、python3、node、ruby、perl)の -c や -e フラグに渡されたコードを取り出し、埋め込まれた破壊的操作をスキャンします。ただし、同等の長形式フラグ(--eval、--execute、--print、--require)や =value を付けた形式(--eval='code')は、すべての処理経路で認識されるわけではありません。長形式を使われると、再帰解析のためのコード引数を取り出せない場合があります。
自分の環境でインタープリター経由の回避が心配な場合は、paranoid interpreters モード(CC_SAFETY_NET_PARANOID_INTERPRETERS=1)を有効にしてください。内容にかかわらず、すべてのインタープリター 1 行コードをブロックします。
値を付けた短形式オプション
まとめて書かれた短いフラグ(-rf など)は、正しく { -r, -f } に分割されます。しかし、短いオプションに値を続けて書いた形式(-Cfoo で foo が -C の値である場合など)は、アナライザーによって扱いが異なります。-f のようなフラグをブロックしていると、実際には -Cfoo のようにオプション値の一部であるケースまで誤検知することがあります。
これは特に、意図どおりに動くカスタムルールを書くときに問題になります。判断できない場合は、保護を強めるために strict または paranoid モードを使ってください。
シンボリックリンクの TOCTOU リスク
rm -rf の対象分類では、そのパスが危険かどうかを判断する前に、シンボリックリンクを実体のパスへ解決します。ただし、アナライザーがパスを解決してから、シェルが実際に rm を実行するまでには、避けようのない TOCTOU(time-of-check-to-time-of-use) の時間差があります。その間にシンボリックリンクの参照先が差し替えられる可能性があります。
これは、実行前にコマンドを解析するあらゆるツールに共通する問題です。完全に塞ぐにはカーネル内で動作するかシステムコールを横取りする必要があり、hook の範囲を超えます。より積極的にブロックしたい運用者向けには、paranoid rm モード(CC_SAFETY_NET_PARANOID_RM=1)という厳しい選択肢があります。
保護の対象外
ここでは、CC Safety Net が扱わない領域を示します。その多くは、意味解析ではなく別のレイヤーによる封じ込めを必要とします。それぞれに対応するサンドボックス側の説明は、CC Safety Net が対処できない範囲を参照してください。機密パスの対象は限定され、一般的な読み取り境界ではない
CC Safety Net は機密パスを保護し、組み込みの機密情報の一覧(.env とその派生形、~/.ssh/id_*、~/.aws、~/.kube/config、コーディング CLI の資格情報ストアなど)の読み取りをブロックします。ユーザーが設定した deny path とその配下すべても同様です。この保護は、未知のツールに対するフォールバック検査を含め、対応するコマンド、パス、検索、patch の各形式に適用されます。
コーディング CLI の対象は 2 つの階層に分かれます。credential の階層(認証トークンと資格情報ストア)は既定で有効です。config の階層(エージェントが通常の作業で編集する設定ファイルと MCP 設定ファイル)は既定で無効で、使うには secret_protection.overrides に明示的な "on" の override が必要です。ここで 1 つ注意点があります。Antigravity に用意されている唯一のルール(secret.cli.antigravity)はこの任意の config 階層にあるため、Antigravity には既定で有効な credential ルールが存在しません。各ルールが保護するパスを含む階層の全一覧は、シークレット保護リファレンスを参照してください。
残る制限は、対象範囲そのものにあります。これは汎用の読み取り境界ではなく、対応する形式に向けた範囲の限られたパターン群にとどまります。
- ファイル名や拡張子がパターン一覧にないファイルに置かれた資格情報は、認識されません。
- standard モードでは、組み込みの機密パスに対するメタデータのみの単独チェック(
test -f ~/.ssh/id_rsa、find ~/.ssh -type f、ls -la ~/.ssh、stat .envなど)が許可されます。strict と paranoid では、こうした探索もブロックされます。なお、設定した deny path はどのモードでも緩和されません。 policy.jsonのsecret_protection.enabledをfalseにすると、deny path も含めてこのステージ全体が無効になります。
完全なファイルシステムの封じ込めはできない
CC Safety Net はツール呼び出しを実行前に拒否しますが、ファイルシステムのパーミッションを強制するわけではありません。ブロックメッセージはエージェントへの指示であって、ファイルシステム上の強制を保証するものではありません。致命的な操作に対する保護(root やホームディレクトリの再帰削除、保護対象の Git メタデータ、両方のスコープのpolicy.json)は常に適用されます。それでも、ベストエフォートのインターセプトでは足りず完全な保護が要る場面では、信頼できる書き込みブローカー、OS のパーミッション、サンドボックス、あるいは同等の実行時強制の仕組みを使ってください。
ネットワークの層を持たない
実行時の評価はネットワーク通信を行わず、ガードの処理経路が外向きの通信を検査・遮断することもありません。ネットワーク経由のデータ流出、通信先ドメインの許可リスト、コンテナ境界は、このプロダクトのスコープ外です。これらはサンドボックスのネットワーク制限が担う領域です。汎用の攻撃対策ではない
プロンプトインジェクションによる情報流出の遮断、ユーザー認証、コンテナ境界の強制は、いずれもスコープ外です。CC Safety Net はエージェントのコマンド文字列を信頼しませんが、任意のバイナリの内部に隠された動作までは検出しません。カスタムルールの設定に改ざん耐性はない
改ざん耐性の対象は、両方のスコープのpolicy.json です。ユーザーポリシーのファイルと、実行ディレクトリおよび設定ディレクトリから解決したプロジェクトポリシーのファイルが含まれます。rule.json と rulebook は保護対象ではありません。rulebook はいずれも、ツール呼び出しのたびにランタイムが読み直すライブファイルです。そのため、rules ディレクトリに書き込めるエージェントは、次の呼び出しから適用される内容を変えられます。
痕跡を残さない変更は、rule.json から設定元の項目を削除する操作以外にもあります。取り込み済みの rulebook.json に rule update が何を書き込んだかは、どこにも記録されていません。そのため、ファイル内のルールの match や reason を書き換えても、その痕跡は残りません。ランタイムは読み込み時に、スキーマとの整合性と name が設定元と一致することだけを確認し、そこにある内容をそのまま適用します。書き換えた内容は、次に rule update がファイルを上書きするまで有効です。rule.json を保護するかどうかは、今後の検討課題です。
プロジェクトの policy.json には、意図的な制限が 1 つあります。保護対象のディレクトリの連鎖は、自身の .cc-safety-net ディレクトリで止まります。ユーザーポリシーのファイルなら、そのディレクトリからファイルシステムのルートまで、上位ディレクトリがすべて対象になります。プロジェクト側でさらに上まで辿ると、プロジェクトディレクトリとその上位すべてを保護対象として抱え込むことになります。そこは破壊的コマンドのルールがまさに対象とするパスであり、ポリシー保護のほうが先に動くため、rm -rf . や find . -delete が本来の理由ではなく、このガードの一般的な理由を返すようになってしまいます。
Hermes Agent と OpenClaw の対象境界
Hermes Agent と OpenClaw の連携が対象とするのは、決められたツール群と実行ホストだけです。その範囲の外では、判定が行われないか、明示的にブロックされます。境界は次のとおりです。Hermes Agent が検査するツールは固定
管理対象の Hermes プラグインはpre_tool_call の hook を 1 つ登録し、patch、read_file、terminal、write_file の 4 つのツールだけを解析に渡します。それ以外の Hermes のツール呼び出しは渡されず、判定も行われません。
ユーザーが入力する !command も対象外です。この形式のシェル入力は pre_tool_call を発生させず、Hermes 自身のコマンドガードに渡されます。CC Safety Net が検査するのはモデルが生成したツール呼び出しだけで、Hermes が起動するすべての subprocess ではありません。そもそも Hermes がプラグインを読み込まなければ、何もブロックされません。存在はするが有効になっていないプラグインを報告できるのは、npx cc-safety-net doctor だけです。
OpenClaw はローカル Gateway ホストの exec だけを対象にする
OpenClaw のプラグインがbefore_tool_call を登録するのは、正規の exec ツールに対してだけです。apply_patch と、OpenClaw の読み取り・書き込み・編集系のファイルツールは保護されません。toolKind の識別子が付いた exec イベントにも判定を返しません。これは、Code Mode の JavaScript exec のように exec という名前を共有するツールを除外するためです。それらの command フィールドがシェルコマンドを表す保証はないからです。
実行ホストの扱いは 3 通りに分かれます。
hostの指定がない、あるいはhost: "auto"またはhost: "gateway"のexec呼び出しは、ローカル Gateway の呼び出しとして解析され、パスはエージェントのワークスペースを基準に解決されます。- 明示的な
host: "sandbox"とhost: "node"は解析されず、未対応としてブロックされます。これらのホストについて、正しいパスの対応関係を裏づけるテストがないためです。 - 設定ファイル側の
tools.exec.hostの既定値は、解析の挙動を変えません。プラグインが読むのは呼び出し自身のhostパラメーターだけだからです。そのため、既定値によって実際にはnodeやsandboxに振り分けられる場合でも、hostの指定がない呼び出しはローカル Gateway の呼び出しとして解析されます。
auto の場合です。サンドボックスのランタイムが有効だと、auto の呼び出しはサンドボックスのファイルシステム上で実行されますが、パスに関するルールは引き続き Gateway のワークスペースを基準に評価されます。コマンドに関するルールは影響を受けませんが、パスに関するルールは誤ったファイルシステムを基準に評価される可能性があります。
Codex ネイティブのリレーはテストされていないため、対象に含めていません。実際のエンドツーエンドのテストは OpenClaw 自身のエージェントランタイム上で動くため、Codex ネイティブのシェル、patch、MCP の呼び出しについては何も保証しません。
どちらの連携も Windows に対応しない
いずれの連携も POSIX 形式の状態ディレクトリ構成を前提としています。場所を移した状態ディレクトリは、各ホストの解決方法に従って扱われます。Hermes ではHERMES_HOME、OpenClaw では OPENCLAW_STATE_DIR、次に OPENCLAW_CONFIG_PATH のあるディレクトリを使い、いずれもなければ ~/.hermes と ~/.openclaw にフォールバックします。Windows の既定の場所には対応していません。Windows では、インストールも検出も POSIX のパスを前提に動くため、Hermes のインストーラーは Hermes が読み取らないディレクトリにプラグインを書き込みます。OpenClaw 自身の CLI は正しくインストールしますが、doctor は状態を誤って報告します。
Codex の対象境界
Codex の統合された exec 経路(macOS と Linux では既定のシェル経路)は、コマンドがセッションを開くときにはPreToolUse のペイロードを送りますが、write_stdin に対しては何も送りません。評価されるのは、セッションを開いたそのコマンドだけです。その後モデルが、すでに起動しているインタラクティブなセッションに入力したテキストは、検査も監査ログへの記録もされないままシェルに届きます。
この隙間は hook 側からは塞げません。ホストがその呼び出しに対してイベントを発行しないため、解析する対象そのものが存在しないからです。実行中のセッションへの入力が自分の環境で懸念になる場合は、封じ込めの層としてサンドボックスを使ってください。
Grok Build は fail open のホスト
Grok Build の hook は設計上 fail open であり、ホスト側にfailClosed に相当する設定はありません。ツール呼び出しをブロックできるのは、標準出力に明示的な deny を返した場合だけです。hook がクラッシュした場合、タイムアウトした場合、不正な出力を返した場合は、その呼び出しはそのまま実行されます。
アダプター自身が fail closed とするケース(ツール入力の切り詰めや、作業ディレクトリを利用できない場合)には、それでも明示的に deny を出力します。このホストでは、アダプターが出力を一切返せなくなる失敗が起きた場合、その呼び出しをブロックできません。この残るリスクが自分の環境で問題になる場合は、封じ込めの層としてサンドボックスを使ってください。
連携のキャッシュが古い場合の対処
OpenCode のキャッシュが古い場合
新しいリリースを公開した後も、OpenCode のプラグインインストーラーが古いキャッシュ版のcc-safety-net を使い続けることがあります。更新が反映されない場合は、キャッシュを消去してから再インストールしてください。手順は OpenCode のインストールにあります。検出されたプラグインのバージョンは、npx cc-safety-net doctor で確認できます。
npx のキャッシュが古い場合(Antigravity CLI、Cursor、Grok Build、Hermes Agent、Kimi Code)
Antigravity CLI、Cursor、Grok Build、Kimi Code の hook と Hermes Agent のプラグインは、いずれもnpx -y cc-safety-net を使います。そのため、npx 自身のキャッシュが古いリリースを返すことがあります。この 5 つのいずれかを対象にインストールすると、まず cc-safety-net を含む npx キャッシュの項目(_npx/*/node_modules/cc-safety-net)をすべて削除します。そのため、通常どおり再インストールするだけで新しいリリースを取得でき、手動でキャッシュを消す必要はありません。他の対象のインストールでは、このキャッシュには手を加えません。
bunx のキャッシュが古い場合
bunx はパッケージごとのキャッシュを OS の一時ディレクトリに置くため、bunx cc-safety-net でも古いリリースが使われることがあります。cc-safety-net update は実行のたびに、自分の cc-safety-net のキャッシュ項目を削除します。連携が 1 つもインストールされていない場合も同じです。残る項目はちょうど 1 つです。bunx から起動した update は、自分自身が実行中の項目を削除しません。使用中のファイルの削除は Windows で失敗するためです。この項目は、bun 自身のマニフェスト TTL に従って再解決されます。
破壊的コマンドが通過した場合
まず、それが文書化された境界なのか、予期しない動作なのかを確認します。explain コマンドは、CC Safety Net がそのコマンドをどう評価したかを段階ごとにすべて表示し、あわせて実際に適用されている安全レベルも示します。これにより、文書化された standard モードの緩和なのか、本当に未対応なのかを区別できます。症状別の詳しい手順は、トラブルシューティングを参照してください。
そのうえで、適切な経路に報告してください。
- ルールがまだブロックしないコマンド形式は、対応漏れであり公開のバグとして扱います。そのまま貼り付けて悪用できる攻撃コードではなく、コマンドの形式を説明した GitHub Issue を作成してください。
- シークレットの漏えい、意図したディレクトリの外への書き込み、サプライチェーンやパッケージの完全性に関わる問題は、非公開の開示経路を使ってください。