Skip to main content
CC Safety Net はコマンドの意味を解析し、許可できる形式と破壊的な形式を区別します。このページにあるコマンド形式は、アナライザーが許可します。 一部の許可は安全レベルによって異なります。standard のみと記載した行は、strict または paranoid が有効になると許可されません。 このページは、許可されるコマンドのリファレンスです。ブロックされる形式はブロックされるコマンド、ガードの処理順はアーキテクチャ、分類方法は解析エンジンを参照してください。
致命的な操作に対する保護は、すべての安全レベルで適用されます。root とホームディレクトリの再帰削除、保護対象の Git メタデータ、正規の policy.json は常にブロックされます。このページに挙げた形式、allow_paths、worktree モード、ルール単位の off の override では、この保護を緩和できません。

Git コマンド

素のブランチ名が許可されるのは、パスの形をしておらず、解決後の git の作業ディレクトリに実在するエントリも指していない場合だけです。実在するファイルやディレクトリと同じ名前のブランチはブロックされ、拒否メッセージは git switch を案内します。パスの形についてはブロックされるコマンドを参照してください。

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

rm -rf は対象によって分類され、最初に一致した分類が採用されます。root やホームディレクトリの対象(/、~、$HOME)、保護対象の Git メタデータ、カレントディレクトリそのもの(rm -rf .)、カレントディレクトリがホームそのものである場合は、どのレベルでもブロックされます。カレントディレクトリの外にあるリテラルのパスも、既知の一時パスや設定済みの allow path でないかぎりブロックされます。一時パスと、カレントディレクトリ配下のパスは許可されます。この違いに注意してください。rm -rf ./subdir は許可されますが、カレントディレクトリそのものを指す rm -rf . はブロックされます。 その上で、レベルに応じた次の 2 つの調整が適用されます。
  • 動的な対象(rm -rf "$target"、バッククォート、コマンド置換)は standard では許可され、fail closed の機能が有効になるとブロックされます。standard は、敵対的な入力や動的に生成されたコマンド文字列に対してはベストエフォートです。
  • CC_SAFETY_NET_PARANOID_RM=1 を設定すると、一時パス以外への再帰的な強制削除は、カレントディレクトリ配下であってもブロックされます。そのため rm -rf ./cache は許可されなくなります。一時パスの対象と、設定済みの allow path は引き続き許可されます。

設定済みの allow path

destructive_command_protection.allow_paths に記載した絶対ディレクトリまたは ~/ で始まるディレクトリは、信頼された一時ルートとして扱われます。これはすべての安全レベルで、rm、PowerShell の Remove-Item、find -delete に適用されます。 allow path が他の範囲を広げることはありません。機密パス保護や deny path を緩和しません。ルート、ホーム、保護対象の Git メタデータを対象にはできません。リポジトリを含む allow path でも、そのリポジトリの .git に対する rm -rf はブロックされます。動的な対象が最初に分類されるため、検証できない対象には allow path が適用されません。$HOME と等しい、またはそれを含むエントリは、検証時と正規化後の両方で拒否されます。allow path から外へ出るシンボリックリンクは対象外です。

heredoc をデータとして受け取るコマンド

標準入力に対する展開されない heredoc で、読み取り側が本文を保存または公開するだけの場合、その本文はプログラムではなくデータです。そのため、本文をコマンド文字列としてスキャンすることはありません。読み取り側は、リテラルで書かれた cat、tee、git apply、git commit、gh pr create、gh issue create のいずれかである必要があります。また、その heredoc がコマンド内で唯一の入力リダイレクトであり、cat と tee については出力側のプロセス置換(>(...))につながっていないことも条件です。この許可は、strict と paranoid を含むすべてのレベルで有効です。 対象になるのは、展開されない heredoc だけです。デリミタが引用符で囲まれているもの(<<'EOF')か、引用符がなくても本文に $、バッククォート、バックスラッシュが含まれないものが該当し、どちらもシェルが展開やエスケープ処理を行う余地はありません。引用符がなく、この 3 つの文字のいずれかが本文に含まれる場合は、シェルの展開やエスケープ処理を受けるため、standard では引き続きスキャンの対象になり、fail closed が有効な場合は拒否されます。heredoc の外にあるコマンドは、これまでどおり解析されます。cat <<'EOF' && rm -rf ~ は rm によってブロックされます。cat、tee、git commit、gh pr create、gh issue create では、デリミタが引用符で囲まれた本文を、機密パスの抽出前にマスクします。そのため、シークレットのファイル名を文章の中で触れただけでコミットがブロックされることはありません。引用符のない本文は、条件を通過する場合でもマスクの対象にはならないため、その中にファイル名らしいトークンがあれば抽出されます。git apply の本文は、patch が書き込むファイル名を含むため、パス抽出からは見える状態のままにします。条件の全体と、条件を満たさない heredoc を standard がどう扱うかについては、heredoc の解析を参照してください。

standard のみの許可

次の形式は standard では許可され、strict または paranoid を有効にすると拒否されます。これは見落としではなく、意図的なトレードオフです。standard は、敵対的な入力や動的な入力に対してはベストエフォートという位置づけだからです。 引用符付きの代入に対する判定の先送りは、適用範囲が狭く限定されています。代入自体は何も実行せず、引用符付きの展開は 1 つの argv の語のままなので、コマンドとフラグに分割されないためです。データとしての利用だとアナライザーが確認できない参照については、代入の時点でのブロックが維持されます。引用符なしの展開(env $W)、コマンド位置でのあらゆる展開(引用符付きを含む)、コマンド置換の中での参照、引用符なしの heredoc 本文での参照が該当します。値をシェルに渡す操作は、その後の段階で検出されます。eval "$W"、bash -c "$W"、echo "$W" | sh は、いずれもシェルの実行元を検証できないため拒否されます。 生成コマンドの許可は、コマンドの形を見て判定するものであり、誰が書いたかは見ません。信頼できる生成コマンドの一覧はありません。eval "$(CMD)" と source <(CMD) / . <(CMD) を許可するのは、CMD が次の条件をすべて満たす場合だけです。
  • 単純コマンドが 1 つだけで、リダイレクトも入れ子のコマンドもない
  • 語がすべてリテラルで、先頭に環境変数代入がない
  • 先頭のベース名が、リモート取得コマンド(curl、wget、fetch、aria2c、http、https、xh、xhs、nc、ncat、netcat)でも、シェルでも、sudo や env のような標準的なコマンドラッパーでもない
CMD 自体は引き続き解析するため、eval "$(rm -rf /)" はブロックします。検証しないのは CMD が出力するシェルです。つまり standard は、リテラルなローカルコマンドでありさえすれば、その出力を信頼します。eval "$(cat somefile)" のような形も含まれます。ブロックされたままの形については、生成されたコマンドの eval と sourceを参照してください。
リソース枯渇を防ぐための上限は、このトレードオフには含まれません。パーサーの再帰上限や構造的な検証の上限を超えるコマンドは、standard を含むすべてのレベルで拒否されます。

デバイスコマンド

dd、mkfs、shred はすべてのレベルで解析されますが、実際に破壊的な形式のみがブロックされます。

PowerShell コマンド

シェルモードに posix を選ぶと、PowerShell の削除ルールは意図的にすべて無効になります。一方、git.reset-hard や rm.recursive-force-root-or-home などのクロスシェルルールは維持されます。auto モードでは、明示的な Remove-Item が検出されます。これは、;、改行、&&、|| の後にある場合も同じです。Get-Content、Set-Content、Add-Content、Copy-Item、Move-Item も同様に検出され、gc や cp のような別名も引数が PowerShell のパス式で書かれていれば検出されます。

機密パスに関する許可

機密パス保護は、サポート対象の形式に対する範囲が限定されたパターンセットです。そのため、機密ファイル名を含む一部の形式は引き続き許可されます。 この許可には、注意すべき境界が 2 つあります。
  • env テンプレート。 正確なベース名 .env.example、.env.sample、.env.template、.env.defaults と、.env.example. または .env.sample. で始まるすべての名前(.env.example.local など)は、ほかのすべての機密パスルールより先に除外されます。そのため、保護対象のホームディレクトリ内でも読み書きできます。この接頭辞形式は、残りの 2 つのテンプレートには拡張されません。.env.template.local は、ほかのすべての .env.* 名と同様に secret.pattern.env-variant でブロックされます。
  • ベンダー管理ディレクトリ。 パスセグメントが node_modules または __pycache__ の場合、または隣接する組み合わせ vendor/bundle または vendor/cache がある場合(単独の vendor セグメントは対象外)、正確に 2 つのルールグループが抑制されます。拡張子ルール(.pem、.p12、.key など)と、拡張子なしの広範なキーベース名ルール secret.pattern.ssh-key-basename(*_rsa、*_dsa、*_ed25519、*_ecdsa)です。それ以外のルールはすべて引き続き適用されます。node_modules/x/.env と node_modules/x/id_rsa は通常どおりブロックされます。.git は除外セットに含まれません。そのため、.git ツリー内のキーマテリアル(.git/hooks/deploy_key_rsa など)は、ほかの場所と同様にルールに一致します。
standard であっても、機密情報の内容へのアクセスや、設定済みの deny path が緩和されることはありません。cat ~/.ssh/id_rsa、find ~/.ssh -type f -exec cat {} +、find ~/.ssh -type f -fprint .env、test -f ~/.ssh/id_rsa && cat ~/.ssh/id_rsa、test -f "$(cat ~/.ssh/id_rsa)" は、いずれも standard でもブロックされます。deny path とその配下は組み込みルールより先に照合され、standard 限定の 2 つの緩和の対象外です。

worktree モードの例外

CC_SAFETY_NET_WORKTREE=1 を設定すると、CC Safety Net は Git の linked worktree であることを確認したうえで、一部のローカル破棄コマンドを許可します。確認できなかった場合、そのコマンドはブロックされたままです。 worktree モードが有効なとき、リンクされた worktree 内で次のコマンドが許可されます。
  • git restore <file> と git restore --worktree <file>
  • git checkout -- <file>、git checkout <path>、git checkout <ref> -- <file>、git checkout --force、位置引数が複数あって判別しにくい checkout の形式
  • git switch --discard-changes と git switch -f / --force
  • git reset --hard と git reset --merge
  • git clean -f(-fd などの結合フラグも含む)
  • git rm --force / -f
次のコマンドはローカルの作業ツリーを越えて影響するため、リンクされた worktree 内でも引き続きブロックされます。
  • git push --force:リモートに影響する
  • git branch -D:共有された ref に影響する
  • git stash drop / git stash clear:stash は worktree 間で共有される
  • git worktree remove --force:別の worktree を削除しかねない
後述の一時ルートの緩和はこれとは別の経路です。オペランド自体が信頼された一時ルート配下の使い捨て worktree ディレクトリであれば、git worktree remove --force が許可されることがあります。 worktree モードが緩和するのは、Git のローカル破棄ルールだけです。ファイルシステム、デバイス、PowerShell のルールには影響せず、Git メタデータの保護が緩和されることもありません。linked worktree の中でも、rm .git、rm -rf <resolved gitDir>、rm -rf <commonDir>、> .git へのリダイレクトは、いずれも即座にブロックされます。参照ファイルが指す先の Git ディレクトリも保護対象だからです。

一時ルートの緩和

信頼された一時ルート配下にある使い捨てリポジトリで git を実行した場合も、Git のルールは緩和されます。これは worktree モードとは独立していて、CC_SAFETY_NET_WORKTREE=1 は必要ありません。 git.push-* を除くすべての Git ルールが、この経路で緩和され得ます。git.ssh-env と git.alias-config は緩和の判定より前に結論が出るため、やはり緩和されません。対象となるリポジトリは、解決後の git の作業ディレクトリから最も近い、.git エントリを持つ祖先ディレクトリです。このリポジトリのルートは、信頼された一時ルートの配下にあり、一時ルートそのものではなく、ワークスペース(元のカレントディレクトリ)の祖先でも配下でもない必要があります。さらに .git が実在するディレクトリでなければならず、.git が存在しない場合やシンボリックリンクの場合はルールがそのまま適用されます。 一時ルート配下の linked worktree は、代わりに .git がファイルです。ここで緩和され得るのはローカル破棄のルールだけで、worktree の情報を確認できること、および worktree モードが挙げるものと同じ「緩和できないローカル破棄」に該当しないことが条件です。branch、stash、tag の操作は引き続きブロックされ、git reset --hard <ref> は共有された状態であるため、ここでも緩和されません。 コマンドラインに --git-dir や --work-tree がある場合、GIT_DIR 系の環境変数による上書きがある場合、コマンドがコマンドラインの git エイリアスを展開したものである場合、この緩和は適用されません。 git worktree remove --force だけは、リポジトリではなくオペランドで判定します。remove の後ろにあるリテラルのオペランドがちょうど 1 つで、絶対パスであり、空白、$、バッククォート、glob 文字を含まず、シンボリックリンクではない実在のディレクトリを指し、その実パスが信頼された一時ルートの配下にあり、一時ルートそのものではなく、ワークスペースとも無関係である必要があります。展開されるのは、パーサーが変数展開と判断した語だけです。 設定した allow_paths によって、この緩和が広がることはありません。allow_paths を読むのは rm の対象分類だけなので、そこにパスを追加しても、その配下のリポジトリが Git ルールにとって使い捨て扱いになるわけではありません。 詳しい条件は解析エンジンを参照してください。
安全だと考えるコマンドを CC Safety Net がブロックする場合は、npx cc-safety-net explain "<command>" を実行して解析全体を確認し、理由を把握してください。フラグについては CLI コマンドを、より広い診断フローについてはトラブルシューティングを参照してください。
最終更新日 2026年9月21日