TL;DR
- Claude Code v2.1.219 で
DirectoryAddedフック(セッション途中でのディレクトリ追加を検知)とsandbox.network.strictAllowlist(許可リスト外ホストへの通信を無条件で拒否する設定)が追加されました。 - 対象読者は、Claude Code をクラウド実行環境(Claude Code on the web・Routines 等)で運用しているエンジニアです。
- 実際に自分のクラウドセッションで確認したところ、
DirectoryAddedフックの実装はバイナリレベルで確認できましたが、sandbox.network.strictAllowlistはクラウド環境では発動条件(bwrap)自体が存在せず、設定しても効果がありませんでした。
はじめに
Claude Code を Routines でクラウド常駐スケジュール実行していると、「新しいセキュリティ設定が追加された」というリリースノートを見るたびに、実際に自分の運用環境でその設定が効くのかどうか気になります。ローカルの Mac ならまだしも、クラウドのコンテナ実行環境ではどうなるのか、公式ドキュメントだけでは分かりません。
今回は v2.1.219 で追加された 2 つの新機能について、実際に自分が動かしているクラウドセッションで検証しました。
v2.1.219 で追加されたもの(公式リリースノートより)
まず公式情報を確認します。Claude Code の公式 CHANGELOG(anthropics/claude-code)の v2.1.219 エントリには、次の記述があります。
-
DirectoryAddedフックを追加。/add-dirコマンド、または SDK のregister_repo_rootコントロールリクエストによってセッション途中で作業ディレクトリが登録されたときに発火する -
sandbox.network.strictAllowlist設定を追加。サンドボックス化されたコマンドについて、許可リスト外のホストへの通信をプロンプトなしで拒否する - デフォルトの Opus モデルが Claude Opus 5(1M コンテキスト)に変更
-
workflowSizeGuideline設定キーを追加(Dynamic workflow のサイズガイドラインをどの設定ファイルからでも指定可能に) - stream-json 出力で深度 2 以上のサブエージェント転送に対応
このうち、クラウド運用に直接関わる DirectoryAdded フックと sandbox.network.strictAllowlist の 2 つを掘り下げます。
実際に検証した結果
1. DirectoryAdded フックはバイナリレベルで実在した
自分のセッションで動いている Claude Code のバージョンをまず確認しました。
$ claude --version
2.1.220 (Claude Code)
v2.1.219 以降のバージョンです。CLI バイナリの文字列を直接調べると、該当機能に関する文字列が実際に埋め込まれていることが確認できました。
$ strings /opt/node22/bin/claude | grep -i "register_repo_root\|DirectoryAdded"
executeDirectoryAddedHooks
DirectoryAdded
DirectoryAdded hook failed:
DirectoryAdded hook:
register_repo_root: target is not a directory
register_repo_root: directory is outside the allowed registration scope
register_repo_root: directory is already a registered working directory
register_repo_root
addDirectories
register_repo_root にはエラーメッセージが複数種類あり(対象がディレクトリでない・登録許可範囲外・登録済み)、リリースノートの説明どおり境界チェックを伴う実装であることが読み取れます。
一方で、この機能を実際に発火させる(stream-json 経由で register_repo_root コントロールリクエストを送る)テストは、今回はタイムボックス内で安全に完了できませんでした。ネスト起動した検証用セッションが意図せず本番リポジトリの作業ディレクトリで実行されてしまい(cd の反映漏れが原因)、独立した検証環境を用意しないまま実行するリスクが高いと判断したためです。実行までは確認できず、CLI バイナリに機能が実装されている事実の確認にとどめています。
2. strictAllowlist は「クラウドでは無条件で無効」だった
こちらは実際に自分のセッションの環境を調べることで、明確な結論が出ました。
$ command -v bwrap; echo "exit=$?"
exit=1
$ echo $CLAUDE_CODE_REMOTE_ENVIRONMENT_TYPE
cloud_default
$ echo $IS_SANDBOX
yes
sandbox.network.strictAllowlist を含む Claude Code のサンドボックス機能は、Linux では bwrap(bubblewrap)を使って実装されています。今回検証したクラウドのセッションコンテナには bwrap コマンド自体が存在しませんでした(command -v bwrap が exit code 1)。
つまり sandbox.enabled: true や sandbox.network.strictAllowlist を settings.json に書いても、実行基盤側に bwrap がなければ設定は静かに無視され、許可リスト外の通信もブロックされません。IS_SANDBOX=yes という環境変数は立っていますが、これは Claude Code のサンドボックス機能の話ではなく、セッションコンテナ自体が使い捨て隔離環境であることを示す別のレイヤーの変数です。
なぜ気づきにくいのか
この挙動が厄介なのは、エラーも警告も出ない 点です。設定ファイルに sandbox.network.strictAllowlist: true と書いても、Claude Code の起動時に「この環境では無効です」といった通知は表示されません。設定した本人は「もう許可リスト外への通信は止まっているはず」と思い込みますが、実際には何も変わっていません。
自分が運用しているプロジェクトでは、このギャップに気づいたのは今回が初めてではありません。以前 sandbox.network.allowedDomains(ドメイン単位の許可リスト)を検証したときにも同じ結論(クラウドでは無効)に達しており、strictAllowlist はその発展形の設定なので当然同じ制約を引き継ぎます。つまり sandbox.network.* 配下の設定は、少なくとも現時点のクラウド実行環境では すべて無効 と考えてよいということです。
クラウド運用者が今すぐできること
sandbox.network.* に頼れない以上、クラウドでのネットワーク制御は別のレイヤーで組み立てる必要があります。実際に自分が運用で使っているのは次の 3 層です。
sandbox.network.allowedDomains や sandbox.network.strictAllowlist はこの図に含まれていません。クラウドで通信を制限したいなら、permissions.deny でツール自体を絞るか、PreToolUse フックで実行前にコマンド内容を検査する方式にする必要があります。
まとめに代えて
DirectoryAdded フックはバイナリに実装が存在することを確認できましたが、実際の発火テストは安全な検証環境を用意できずに持ち越しになりました。一方で sandbox.network.strictAllowlist は、クラウド実行環境では bwrap が存在しないという一点で無条件に無効化されることが、環境変数とコマンドの実行結果からはっきり確認できました。
新しいセキュリティ設定がリリースノートに載ったとき、「設定を書いたから安全になった」と思い込む前に、自分が動かしている実行基盤でその設定の前提条件(今回で言えば bwrap の有無)が満たされているかを、まず command -v 一発で確認する価値があります。