Skip to main content
ここに挙げるコマンドは、未コミットの変更、stash に退避した作業、リモートの履歴、ディスク全体を失う可能性があるため、ブロックされます。次の表は既定の組み込みルールです。カスタムルールで拡張できます。 既定では、マークのないすべての行を 3 つの安全レベルでブロックします。Strict または Paranoid と記載した行には、その安全レベルまたは機能が必要です。ポリシーは重大でない一部のルールを無効にできます。各レベルを有効にする方法については、モードを参照してください。 このページは、ブロックされる操作と、その境界の一覧です。ガードの処理順はアーキテクチャ、分類処理の詳細は解析エンジン、許可される書き方は許可されるコマンドを参照してください。

各レベルが追加するブロック

一部の重要な保護は、選択した安全レベルに依存しません。root とホームディレクトリの再帰削除、Git メタデータの保護、正規の policy.json の保護は、破壊的コマンドのマスタースイッチも、ルール単位の off の override も無視します。

Git コマンド

次の Git 操作は、未コミットの作業を破棄する、復旧に必要な履歴を壊す、共有された状態を書き換える、といった理由でブロックします。 強制フラグと、ブランチの作成・リセットのフラグを両方使ってブランチを変更する Git コマンド(git checkout -Bfgit switch -Cf --discard-changes など)は、ブランチの強制リセットとみなしてブロックします。

Git の SSH 関連の環境変数による上書き

Git は、ネットワーク操作中に任意のプログラムを実行するために GIT_SSH_COMMANDGIT_SSHGIT_SSH_VARIANT を使えます。CC Safety Net は、これらの上書きをネットワーク系のサブコマンドと組み合わせた場合にブロックします。任意のコマンドを実行できてしまうためです。

ファイルシステムコマンド

rm -rf の対象は、次の順に照合し、最初に一致した分類を採用します。
  1. 未対応の Windows UNC またはデバイス名前空間の対象
  2. root またはホーム
  3. 保護対象の Git メタデータ
  4. 一時パス
  5. 動的な対象
  6. 設定済みの allow path
  7. カレントディレクトリがホームの場合
  8. カレントディレクトリそのもの
  9. カレントディレクトリ配下
  10. カレントディレクトリ外
一時パスはすべてのレベルで許可します。カレントディレクトリ配下のパスは、paranoid の rm が有効でないかぎり許可します。安全な書き方は、許可されるコマンドを参照してください。 破壊的コマンドをシェル関数に隠しても結果は変わりません。関数を呼び出した位置で、呼び出し側のカレントディレクトリを使って本体を解析します。呼び出しは、引用符付きの形式('cleanup')、time! を前置した形式、eval 経由でも解決します。bash のキーワード形式 function cleanup { ... }function cleanup() { ... } も定義として解釈するため、cleanup() { ... } と同じ扱いになります。呼び出されない定義は何も実行しません。呼び出しの解決とスコープについては、POSIX シェル関数を参照してください。
動的な rm -rf の対象は、standard では一律にブロックされません。rm -rf "$target" は standard では許可され、strict または paranoid で fail closed の機能が有効になったときにだけブロックされます。standard は、敵対的な入力や動的に生成されたコマンド文字列に対してはベストエフォートです。コマンドがプロンプトインジェクションなど信頼できない経路から来る可能性がある場合は、strict または paranoid を使ってください。
引用符のない glob は、この照合を行う前にカレントディレクトリを基準に展開されます。カレントディレクトリがホームディレクトリの場合、rm -rf *rm -rf ./* はどちらもホームを対象とする分類になり、すべてのレベルで rm.recursive-force-root-or-home としてブロックされます。一方、引用符付きの rm -rf '*' は glob ではなく、* という名前のファイル 1 つを指します。ホームではこれも rm.recursive-force-home-cwd によってブロックされ、それ以外の場所では通常のリテラル対象として扱われます。 Git メタデータと動的な対象は、設定済みの allow path より先に分類されます。そのため、destructive_command_protection.allow_paths の項目によって Git メタデータの保護が緩和されることはなく、検証できない対象にも適用されません。

デバイスとディスクの破壊

CC Safety Net は、どの安全レベルでも ddmkfsshred を解析します。これらは致命的な操作のルールではないため、破壊的コマンドのマスタースイッチやルール単位の off の override を適用できます。 dd のルールが働くのは、デバイスへの書き込みだけです。デバイスからファイルへの読み出し(dd if=/dev/sda of=./backup.img)や、ファイルとして存在するイメージに対する mkfs.ext4 disk.img は許可します。この 3 つのルールは、ラッパーや他のコマンド経由の実行にも適用されます。bash -c "dd if=/dev/zero of=/dev/sda"sudo mkfs.ext4 /dev/sdaenv dd of=/dev/sda if=/dev/zeroeval "shred secret" は、いずれもブロックされます。

Git メタデータ

最も近い祖先 .git エントリを解決する対象は、実行ディレクトリと、プロジェクトのルール設定を決める設定ディレクトリの 2 つです。それぞれについて、そのエントリ、解決後の Git ディレクトリ、hooks サブツリーを保護します。両者は通常同じディレクトリですが、エージェントがプロジェクトの外でコマンドを実行する場合(Amp の shell_command.dir や OpenCode の workdir)は異なります。そのときは両方の Git 管理領域を保護します。この確認は設定読み込み前に実行するため、無効化できません。 シンボリックリンクになっている .git ディレクトリと hooks ディレクトリは、表記上のパスと正規化後のパスのどちらでも保護します。存在しない Git ディレクトリを指す .git の参照ファイルもブロックします。POSIX シェルの末尾の * glob はドットで始まるエントリに一致しないため、リポジトリルートでの rm -rf ./*.git を対象にしません。ただし、rm -rf .git/worktrees/* と PowerShell のワイルドカードは対象になります。
範囲の目安:このガードが対象とするのは、実行ディレクトリと設定ディレクトリから見て、それぞれ最も近い上位の Git 管理領域です。どちらかのディレクトリの下に入れ子になった別のリポジトリや、解決された対象に含まれない Git 内部のパスは対象外です。

保護対象の policy.json

保護対象のポリシーファイルを変更・削除する操作は、常にブロックします。保護対象は 2 つです。1 つはユーザーポリシーのファイル(~/.cc-safety-net/policy.json、または変数が設定されている場合は $CC_SAFETY_NET_HOME/policy.json)、もう 1 つは実行ディレクトリと設定ディレクトリのそれぞれから解決したプロジェクトポリシーのファイル(.cc-safety-net/policy.json)です。このチェックは設定を読み込むに実行されるため、保護対象のポリシー側からは無効にできません。この拒否には安全レベルも設定の状態も付きません。理由の文字列は次のとおりです。
照合の対象は 2 つのファイルと、スコープごとに異なるディレクトリの集合です。ユーザーポリシーのファイルでは、そのディレクトリとすべての上位ディレクトリが対象になります。プロジェクトポリシーのファイルでは、自身の .cc-safety-net ディレクトリまでで、それより上は対象外です。そのため、プロジェクトルートでの rm -rf . は、このガードではなく破壊的コマンドのルール本来の理由を返します。形式は次のとおりです。
  • 直接の書き込み、編集、patch の対象。
  • シェルのオペランドとしての完全一致、および書き込みリダイレクト。
  • 対応する環境変数による指定、相対パス、既存のシンボリックリンク経由の別名。
  • 保護対象のディレクトリに対する再帰的な rm
  • 保護対象のファイルまたはディレクトリを移動元とする mv
読み取り専用の [, cat, file, grep, head, jq, less, ls, more, rg, sed, stat, tail, test, wc は許可します。
これは意図的に最小限にとどめた、パス完全一致のガードであり、コマンドの動作を模倣するものではありません。代入のみのシェル変数と明示的な cd は追跡しますが、glob やブレース展開は行わず、計算されたインタープリターのパスを推測せず、インタープリターの本体も検査せず、アーカイブの中身も推測せず、find のアクションを模倣せず、転送後の最終的なファイル名も推測しません。rule.json、rulebook、同じディレクトリ内の他のファイル、ポリシーディレクトリの一覧取得は、このガードの対象外です。改ざんに耐えるのは policy.json だけで、これは両方のスコープで保護されます。

エージェントによる cc-safety-net policy apply

policy apply はこのガードが保護するファイルを書き換えるため、同じ段階が設定を読み込む前に、hard_stop の intent で拒否します。提案を適用できるのはユーザーだけで、これを解除するフラグはありません。理由の文字列は次のとおりです。
この判定は意図的に広めに一致します。対象は、cc-safety-netccsn の直接実行、npxbunxpnpxpnpm dlxyarn dlxnpm execpnpm execyarn execcc-safety-net@latest のようなバージョン指定、bunnode による src/cli/cc-safety-net.ts または dist/bin/cc-safety-net.js の実行です。実行対象の前にランナーのオプションを置いても回避できず、-g--global は位置に関係なく読み飛ばされます。policy check とその他のサブコマンドは許可されたままです。

PowerShell Remove-Item

PowerShell への対応は限定的なサブセットです。対象は、Remove-Item とその別名、ファイル系コマンドレットの Get-ContentSet-ContentAdd-ContentCopy-ItemMove-Item と別名 gccattypecpmv、および既存のシェル共通ルールです。汎用の PowerShell パーサーではありません。以下の削除ルールは powershellauto のシェルモードで適用されます。posix モードでは意図的に適用しませんが、git.reset-hardrm.recursive-force-root-or-home のようなシェル共通のルールは引き続き適用されます。機密パスの保護は、$HOME$env:USERPROFILE$env:HOME~ のいずれかの先頭部分に、どちらのパス区切りでリテラルの末尾部分を連結した形式を解決します。そのため Get-Content $HOME\.ssh\id_rsa はブロックされます。それ以外の方法で組み立てたパス、たとえば文字列連結、部分式、Join-Path を使ったものは評価しません。 別名と省略されたパラメーターも解決するため、ri . -r -fo もブロックします。呼び出し演算子を使った形式(& Remove-Item ...& { ... }. { ... })、リテラル文字列を渡す iex / Invoke-Expression$(...) の部分式も解析します。行コメント(#)とブロックコメント(入れ子を含む <# ... #>)は無視しますが、その後ろにある実際のコマンドは引き続きブロックします。形式が不正なブロックコメントや部分式、深さの上限を超えたものは fail closed になります。
-WhatIf を付けた場合、PowerShell は実際には何も削除しないため、ブロックの対象から外れます。-WhatIf-WhatIf:$true、省略形の -wi を付ければ、通常はブロックされる Remove-Item . -Recurse -Force も許可されます。明示的に -WhatIf:$false を指定した場合は、再びブロックされます。なお、上の strict 限定の行には例外が 1 つあります。Remove-Item $HOME -Recurse -Force は動的な対象ではなく root/ホームの対象として分類されるため、standard でもブロックされます。

機密パス

機密パスの保護は、コマンド解析より前に実行される別のガードステージです。対応する コマンドパス検索(grep/glob)、patch の各形式に適用され、未知のツールについても、その任意のテキストをシェルコマンドとして扱うことなく検査します。 書き込みだけでなく、組み込みの機密ファイル群の読み取りもブロックします。cat .envenv cat .envsudo command cat .envstrings id_rsaxxd .envbase64 .envdd if=.envcat ~/.ssh/id_rsabash -c "cat .env"node -e 'require("child_process").execSync("cat .env")' は、いずれもブロックされます。 コマンドの形の抽出は、上限を設けたうえで構造的に行います。シェル構文の構造的な上限を超えた場合は fail closed になり、パースが不正な場合は例外になります。設定済みの deny path は組み込みルールより先に照合され、standard モードの緩和によって外れることはありません。 すべてのルール ID とその分類、保護対象のパス、Coding CLI の 2 つの階層、照合の順序、除外条件は、シークレット保護リファレンスを参照してください。機能全体は secret_protection.enabled: false で無効にでき、個別のルールは secret_protection.overrides で有効・無効を切り替えられます。ポリシーを参照してください。

シェルラッパーとインタープリターの 1 行コード

bash -csh -c のようなシェルのインタープリターで包まれたコマンドもブロックします。入れ子になったラッパーは最大 10 階層まで再帰的に解析し、その深さを超えるコマンドは通さずに拒否します。 インタープリターの 1 行コードに埋め込まれた破壊的なコードは、既定で検出してブロックします。CC Safety Net は、インタープリターの -c-e フラグに渡されたコードを取り出し、埋め込まれた破壊的操作をスキャンします。そのため、エージェントが Python や Node の呼び出しに os.system("rm -rf /") を紛れ込ませても、hook はすり抜けられません。 解析対象のインタープリターは、pythonpython2python3noderubyperl です。ブロックの原因になるのは埋め込まれた破壊的コマンドであり、1 行コードという形式そのものは既定では許可されます。

生成されたコマンドの eval と source

eval "$(CMD)"source <(CMD). <(CMD) は、CMD が実行時に出力した内容をそのままシェルに渡します。strict と paranoid では、この種の動的なシェルの実行元をすべて拒否します。standard が許可するのは、完全にリテラルなローカルの生成コマンド 1 つという狭い形だけで、それ以外はブロックします。この形についてはstandard のみの許可を参照してください。 生成コマンドの本体は他のコマンドと同じように解析します。そのため eval "$(rm -rf /)"rm でブロックし、source <(git reset --hard) は reset でブロックします。

インタープリターの 1 行コードをすべてブロックする

内容にかかわらずインタープリターの 1 行コードをブロックしたい場合は、CC_SAFETY_NET_PARANOID_INTERPRETERS=1 を設定します。危険なコードが含まれていなくても、python -cnode -eruby -eperl -e のすべての 1 行コードがブロックされます。python -c "print(1)" は standard と strict では許可されますが、ここではブロックされます。モードを参照してください。

strictparanoid の heredoc

fail closed の機能が有効な場合、heredoc を含むコマンドは、次の条件をすべて満たすときにだけ許可されます。
  • コマンドに含まれる heredoc が 1 つだけであること。
  • その heredoc が標準入力に接続されていること。
  • 展開されない heredoc であること。デリミタが引用符で囲まれているか、引用符がなくても本文に $、バッククォート、バックスラッシュが含まれないことを指します。
  • 他に入力リダイレクトがないこと。
  • 読み取り側が、リテラルで書かれた catteegit applygit commitgh pr creategh issue create のいずれかであること。
fail closed の機能は、strictparanoid で有効になります。デリミタに引用符がなく、本文に $、バッククォート、バックスラッシュのいずれかが含まれる場合は、次の理由で拒否されます。
それ以外の未対応の形式や読み取り側の場合は、次の理由で拒否されます。
standard モードでの heredoc 本文の扱いを含む詳細な仕様は、解析エンジンにあります。

解析できないコマンドテキスト

シェルのパーサーがコマンドをトークンに分割できない場合(引用符が閉じていない場合など)、その後の挙動は安全レベルによって変わります。 ヒューリスティックなスキャンが確認するのは、rm -rfgit reset --hardgit reset --mergegit clean -fgit checkout --forcegit checkout --git push --forcegit push --deletegit branch -Dgit tag -dgit stash dropgit stash clear--staged を伴わない git restorefind -deletedd of=/dev/mkfs /dev/shred <arg> です。一致した場合は、ルール raw-text.dangerous-command で拒否します。テキストが echo または rg で始まる場合、findddmkfsshred のパターンは対象外になるため、これらの文字列を echo や ripgrep の引数として引用符で囲んでもスキャンには引っかかりません。 スキャンはさらに、シェルへパイプしたダウンロード、つまりリモートインストールのワンライナーを探します。リモート取得コマンド(curlwgetfetcharia2chttphttpsxhxhsncncatnetcat)を shbashzshdashksh のいずれかにパイプしていれば、raw-text.dangerous-command で拒否します。シェル名にパスが付いていても(| /bin/sh)、sudoenvcommandbuiltin のラッパーを挟んでいても(| sudo sh| env VAR=1 sh)同じです。コマンドの途中やパイプの前後にバックスラッシュ改行を入れても隠せません。このパターンも、テキストが echo または rg で始まる場合は対象外になるため、echo で表示するインストール行はデータのままです。同じパイプラインが実際のコマンドとして解析できる場合は、代わりに構造から「shell execution source cannot be verified safely」の理由で拒否します。テキストスキャンは、heredoc の本文のようにパーサーが中まで降りないテキストで、これを捕捉します。
リソース枯渇を防ぐための上限は、レベルの仕組みとは独立しており、standard を含むすべてのモードで拒否につながります。宣言されたコマンドの再帰上限や、構造的な検証の上限を超えた場合は、常に拒否され、通過することはありません。
explain コマンドを使うと、CC Safety Net が特定のコマンドをブロックまたは許可した理由を正確にたどれます。指定できるフラグは CLI コマンド、JSON のスキーマは explain トレースを参照してください。
最終更新日 2026年9月3日