どの安全レベルを使えばよいですか?
人が見ているセッションでは、既定のstandard レベルを使います。ただし、敵対的な入力や動的な入力を確実に防げるわけではありません。プロンプトインジェクションなど信頼できない文脈からコマンドが来る可能性があるなら、strict を使います。プロジェクト内の rm -rf と、すべての python -c や node -e のワンライナーも止めたいなら paranoid を選びます。
各レベルは、3 つの機能の組み合わせを表すプリセットです。
レベルは、
policy.json の safety.level または環境変数 CC_SAFETY_NET_LEVEL で設定します。2 つのうち高い方が適用されます。このページで紹介する各トグルは、そのレベルの上に機能を 1 つずつ追加します。どのプリセットにも一致しない組み合わせは custom として報告されます。
Git のリンクされたワークツリーでは、ワークツリーモードを有効にすると git reset --hard などのローカル破棄を許可できます。信頼できないコードの実行やネットワークの制御には、サンドボックスを併用してください。
変数の一覧とポリシー・環境変数の優先順位は環境変数を、safety.overrides はポリシーを参照してください。影響を受けるコマンドは各安全レベルで追加されるブロックに一覧があります。
既定モード
既定モードはstandard 安全レベルです。環境変数を設定しなくても、組み込みの破壊的な Git 操作とファイルシステム操作、およびシークレットファイルへのアクセスをブロックします。
standard を含むどのレベルでも、不正なフック入力、アナライザーのエラー、解析できないほど大きいコマンドや入れ子が深すぎるコマンドはブロックします。フェイルクローズによる強制を参照してください。
standard と strict の違いは、解析や検証ができない入力の扱いです。
- 引用符が閉じていないなどの理由でトークンに分割できないコマンドは、テキストを既知の危険なパターンと照合して判定します。
echo 'unterminatedは実行され、git reset --hard 'unterminatedはブロックされます。standard がコマンドを検証できない場合を参照してください。 rm -rf "$target"のように削除対象が動的な再帰削除は、ホームディレクトリで実行する場合を除いて許可されます。strict ではどこで実行してもブロックされます。
eval "$(ssh-agent -s)" のようにリテラルなローカルの生成コマンド 1 つに対する eval や source も許可します。
standard は、test -f .env や ls ~/.ssh のように、中身を読まずにシークレットファイルの存在を確かめる操作を許可します。strict と paranoid はこれをブロックします。該当する形はすべてstandard モードが読み取りと見なさないものに一覧があります。シークレットファイルの内容の読み取り、設定した拒否パス、致命的なルールは、どのレベルでも緩和されません。
standard がコマンドを検証できない場合
standard レベルの拒否のうち次の 2 つは、「危険」ではなく「検証できなかった」ことを意味します。- パースできないテキストが破壊的なパターンに一致した場合
bash -c "$CMD"のように、CC Safety Net がシェルコマンドの実行元を解決できない場合
Strict モード(CC_SAFETY_NET_STRICT=1)
strict は fail_closed 機能を有効にします。珍しい構文では、ときどき誤検知が出ます。次のものをブロックします。
- 解析できないコマンド。 テキストスキャンで危険なものが見つからなくてもブロックします。理由は「Command could not be safely analyzed (strict mode)」です。
echo 'unterminatedは standard では許可され、strict ではブロックされます。 - 一部の対応形式を除く heredoc。
git commit -F - <<'EOF'と単純なcat <<'EOF'は通りますが、python3 - <<'PY'は拒否します。heredoc を参照してください。 - 検証できない破壊的な対象。
rm -rf "$target"などです。 - リモートへのアップロード。 本文やファイルを送る
curlやwgetのリクエストをブロックします。ただし、すべての URL がループバックなら許可されます。ネットワークコマンドを参照してください。 - シークレットファイルの存在確認。
test -f ~/.ssh/id_rsaやfind ~/.ssh -type fなどです。 - インタープリターのコード内にあるシークレットのパス。
python -c "x = '.env'"のように、standard ではデータとして扱うものです。
fail_closed が有効なときにだけ動作します。
strict は、レベルで有効にするか、同じ機能を有効にする以前からのトグルで有効にします。
上の表のルールは、policy.json の
destructive_command_protection.overrides で個別に無効にできます。"on" を指定すれば、standard でも個別に有効にできます。解析できないコマンド、未対応の heredoc、シークレットファイルの確認には無効にできるルールがないため、strict が有効なあいだはブロックされたままです。Paranoid モード(CC_SAFETY_NET_PARANOID=1)
paranoid レベルは、strict に paranoid_rm と paranoid_interpreters の 2 つの機能を加えたものです。通常のワークフローを妨げることがあるため、明示的に有効にしたときだけ動作します。レベル全体を選ぶことも、機能を 1 つだけ有効にすることもできます。片方だけを有効にした場合、レベルは custom と報告されます。
rm チェック(CC_SAFETY_NET_PARANOID_RM=1)
既定では、カレントディレクトリ配下の rm -rf と find -delete は許可されます。paranoid の rm チェックを有効にすると、そこでも一時パス以外への再帰削除をブロックします。
一時パスと
destructive_command_protection.allow_paths に指定したディレクトリは許可されたままです。
インタープリターのワンライナー(CC_SAFETY_NET_PARANOID_INTERPRETERS=1)
paranoid 未満のレベルでは、本体に危険なコマンドを含むワンライナーだけをルール interpreter.dangerous-command でブロックします。このチェックを有効にすると、内容にかかわらずすべてのワンライナーを interpreter.one-liner-paranoid でブロックします。
python -c '...'(python3とpython2も含む)node -e '...'ruby -e '...'perl -e '...'
python -c "print(1)" は、standard と strict では許可され、このチェックではブロックされます。
paranoid チェックを有効にする
CC_SAFETY_NET_PARANOID=1 では fail_closed は有効になりません。プリセット全体を適用するには、CC_SAFETY_NET_LEVEL=paranoid か safety.level: "paranoid" を使ってください。
ワークツリーモード(CC_SAFETY_NET_WORKTREE=1)
Git のリンクされたワークツリーは独立した作業環境なので、ワークツリーモードではそこでの一部のローカル破棄ルールを緩和します。適用されるのは、カレントディレクトリがリンクされたワークツリーの中にあると CC Safety Net が確認できた場合だけです。
ワークツリーモードを有効にする
workflow.worktree_mode: true を設定することもできます。どちらか一方を設定すればワークツリーモードが有効になります。
リンクされたワークツリーで許可されるコマンド
ワークツリーモードは、作業ディレクトリがリンクされたワークツリーだと確認できた場合に、次のコマンドを許可します。git restore <file>とgit restore --worktree <file>git checkout -- <file>、git checkout <path>、git checkout <ref> -- <file>、git checkout --force、および位置引数が複数あって判別できないgit checkoutの形式git reset --hardとgit reset --mergegit clean -f(-fdのように組み合わせた短いフラグも含む)git switch --discard-changesとgit switch -f / --force
リンクされたワークツリーでもブロックされるコマンド
次のコマンドは共有された ref や他のワークツリーに影響するため、ワークツリーモードでも緩和されません。git push --force:リモートに影響するgit branch -D:ワークツリー間で共有されるブランチを強制削除するgit stash drop/git stash clear:ワークツリー間で共有されるスタッシュを変更するgit worktree remove --force:別のワークツリーを削除しかねない
/tmp などの一時ディレクトリ配下のワークツリーなら、ワークツリーモードがなくても git worktree remove --force が通ることがあります。一時リポジトリでの Git コマンドを参照してください。
ワークツリーモードが適用されない場合
作業ディレクトリがリンクされたワークツリーだと確認できない場合は、既定のルールがそのまま適用されます。メインワークツリーとサブモジュールは、ワークツリーモードでも緩和されません。ワークツリーモードが無効になるその他の条件
ワークツリーモードが無効になるその他の条件
- コマンドに
--git-dirまたは--work-treeが渡されている場合や、環境変数にGIT_DIR、GIT_WORK_TREE、GIT_COMMON_DIR、GIT_INDEX_FILEのいずれかが設定されている場合 - コマンドが
git -cまたはGIT_CONFIG_*でcore.worktreeを設定している場合や、ワークツリーのconfig.worktreeまたは共有のリポジトリ設定にworktreeキーがある場合 - ワークツリーの Git ディレクトリにシンボリックリンクまたは FIFO がある場合
git -C <path>の対象を解決できない場合- 引数に
$、*、?、[を含む動的な値がある場合 - コマンドが
--recurse-submodulesまたはサブモジュールを再帰的に扱う設定を使う場合 - ブランチを強制リセットするコマンド(
-fまたは--discard-changesを伴うgit checkout -Bやgit switch -C)の場合や、-fを複数指定したgit cleanの場合