Claude Codeのサンドボックス機能を設定する(Mac編)
前回の記事では、sandbox-execコマンドを使用してClaude Codeをサンドボックス上で動かす方法を紹介しました:
その後、Claude Code標準のサンドボックス機能が提供されたため、この知識は不要になったかと思いきや…… 安全性を高めようとすると結局似たような設定をする必要があるやんけ! ということが判明したのでその話をします。なお、設定の詳細については公式ドキュメントを参考にしてください。
絶対サンドボックス上でコマンドを実行したい
Claudeのサンドボックス機構はBashツールに対して作用します。たとえばClaudeくんがBash(rm -rf ~/)というコマンドを発行した場合も、rm -rf ~/はサンドボックス内で実行されるためエラーになって安全というわけですね。
しかし、デフォルトの挙動(sandbox.allowUnsandboxedCommands: true)だと、
- サンドボックス上でコマンドを実行する
- 1がエラーになった場合、AIの判断によってはサンドボックスを無効化して再実行する
という挙動になっています。おそらく、一度考え直すステップを入れることでAIがうっかりミスに気づけるという設計思想なのだと思われるが…… 怖い人はオフにしておきましょう。
{
"sandbox": {
"enabled": true,
"allowUnsandboxedCommands": false
}
}
サンドボックスからアクセス可能なファイルを設定する
これは一般的な権限設定と共通(permissions.(allow|deny))で、Edit(path)およびRead(path)によって指定します:
{
"permissions": {
"allow": [ // 書き込めるディレクトリの設定
"Edit(~/.npm/**)",
"Edit(~/.cache/**)",
"Edit(//tmp/**)"
]
}
}
絶対パスを指定したい場合は//から始めることに注意。
サンドボックスからアクセス可能なドメインを設定する
こちらもファイル同様、一般的な権限設定と共通。WebFetch(domain:xxx)で指定します:
{
"permissions": {
"allow": [
"WebFetch(domain:registry.npmjs.org)",
"WebFetch(domain:npmjs.com)",
"WebFetch(domain:github.com)",
]
}
}
localhostポートへのバインドを許可する
sandbox.network.allowLocalBinding: true
{
"sandbox": {
"network": {
"allowLocalBinding": true
}
}
}
特定のコマンドだけサンドボックス外で実行したい
sandbox.excludedCommands にコマンドを指定(引数込みで指定可能です)。
sandbox-execには、サンドボックス内でサンドボックスを使えないという仕様があります。Chromiumもsandbox-execを使用しているため、Chromiumを使ったE2Eテストをするときにはサンドボックス外でやるしかない。
{
"sandbox": {
"excludedCommands": [
"pnpm test",
"pnpm check"
]
}
}
サンドボックスでエラーになった理由を知りたい
以下のコマンドでサンドボックス関係のログをリアルタイムで見られます。エラーになったときのログを見ればどのパスでwrite失敗したか等書いてある。
$ sudo log stream --predicate 'sender == "Sandbox"' | grep deny
エージェントにサンドボックスの存在を教える
サンドボックスのエラーが発生した際にエージェントが混乱することがあるので、CLAUDE.mdにこういう指示を書いたら改善しました。
## ツール実行時の注意事項
Bash toolはサンドボックス上で実行されるため、ファイルアクセスやネットワーク接続がエラーになることがある。
そのような状況では、ユーザに指示を仰ぐこと。
まとめ
allowUnsandboxedCommands: trueにしたほうが楽だし、実用上もこれで十分安全なんじゃないかという説もあります。エージェントに全部賭けろ。
Discussion