sandbox.allowNestedUserNamespacesでChromiumのsandboxを残す条件
Linuxのsandboxで「No usable sandbox!」が出たときの3つの直し方を比べます。allowNestedUserNamespacesの書き場所、手放す防御、Podmanに効かない理由をまとめます。
Chromiumが「No usable sandbox!」で落ちるのはsandboxの既定動作
LinuxとWSL2では、Claude Codeのsandbox内のコマンドは既定でuser namespaceを作れません。ChromiumやElectronは自前のsandboxを作るためにuser namespaceを使うので、ここで落ちます。
sandbox.allowNestedUserNamespacesは、この制限を外すBoolean型のキーです。Claude Code v2.1.305で追加されました。既定はfalseです。
ただし、名前から想像する「ChromiumとPodmanをsandbox内で動かす設定」とは少し違います。設定リファレンスでは、このキーが解決するのはChromium、Electron、入れ子のbubblewrap、unshareです。rootlessのPodmanとBuildahは、このキーだけでは動きません。
このキーの守備範囲
動く
Chromium・Electron自身のsandbox、入れ子のbubblewrap、
unshareが使うuser namespaceの作成です。足りない
rootlessのPodmanとBuildahです。sandboxは別の経路でも止めるため、
excludedCommandsで扱います。
症状から3つの直し方を選ぶ
sandboxのトラブルシューティングは、同じ症状に3つの直し方を並べています。どれも何かの隔離を手放します。手放すものが違うので、選ぶ基準は「何を残したいか」です。
| 直し方 | 対象 | 手放すもの |
|---|---|---|
ブラウザを--no-sandboxで起動 | 対象Chromium、Electron | 手放すものブラウザ自身のsandbox。Claude Codeのsandboxはそのまま |
sandbox.excludedCommandsに追加 | 対象rootless Podman、Buildah、ブラウザやunshareを呼ぶスクリプト | 手放すもの一致したコマンドは、sandbox外でフルアクセスになる |
sandbox.allowNestedUserNamespacesをtrue | 対象Chromium・Electron自身のsandboxを残したい場合、入れ子のbubblewrap、unshare | 手放すものsandboxの防御そのもの(次の節) |
見分けに使える失敗メッセージは、次の3つです。
- Chromiumが
No usable sandbox!で終了する unshare -U trueがunshare: unshare failed: Operation not permittedを出す。allowAllUnixSocketsが有効だと、代わりにNo space left on deviceが出ることもある- rootless Podmanが
cannot clone: Operation not permittedを出す。もっと手前で、Podman自身のフォルダについてread-only file systemと出て止まることもある
Can't mount proc on /newroot/procのようなbwrapのエラーは別の問題です。コンテナ内でsandboxが起動しないケースで、enableWeakerNestedSandboxの領分になります。Docker内でsandboxを動かす設定で扱っています。
設定は~/.claude/settings.jsonに書く
書き方はsandboxオブジェクトの中に1行足すだけです。
{
"sandbox": {
"enabled": true,
"allowNestedUserNamespaces": true
}
}大事なのは置き場所です。~/.claude/settings.jsonに書く指示になっていて、プロジェクトの.claude/settings.jsonは不可です。理由は設定リファレンスのScope欄にあります。
| 書いた場所 | trueの扱い |
|---|---|
~/.claude/settings.json | trueの扱い有効 |
--settingsで渡したJSON | trueの扱い有効 |
| 管理設定(managed settings) | trueの扱い有効 |
プロジェクトの.claude/settings.json | trueの扱い無視される |
プロジェクトの.claude/settings.local.json | trueの扱い無視される |
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1のセッション | trueの扱いどの場所のtrueも無視される |
falseは逆に、どのファイルに書いても有効です。設定の優先順位に従います。
つまり、リポジトリを開いただけで、そのリポジトリの設定ファイルから勝手にuser namespaceが解禁されることはありません。チームで共有したくなる設定ですが、共有リポジトリには置けない作りです。環境変数のscrubを使う構成との関係はCLAUDE_CODE_SUBPROCESS_ENV_SCRUBの解説にあります。そのセッションでは、ChromiumやElectronに--no-sandboxを付け、ほかのツールはClaude Codeの外で実行します。
効いたかどうかを確かめる
症状表に沿うなら、unshare -U trueが確認コマンドになります。Operation not permittedが出なくなれば、user namespaceを作れる状態です。ただしunshareで始まるコマンドは、excludedCommandsに何を書いてもsandbox内に留まります。unshareが任意のプログラムを起動できるためです。つまりこの確認コマンドは、除外設定に関係なく常にsandbox内で走ります。
設定を入れたら、新しいセッションでClaude Codeに確認を頼む形が手軽です。
sandbox内で `unshare -U true` を実行して、終了コードと出力をそのまま報告して。
成功したら、Chromiumを起動するテストコマンドも1回だけ実行して。失敗した場合は、設定ファイルの置き場所(上の表)を先に疑ってください。プロジェクト側に書いていると、値がtrueでも無視されます。
有効にすると手放す防御
このキーには強い警告が付いています。trueにすると、sandbox内のコマンドが実行したコードが、sandboxの外で動いてしまうことがあります。
落とし穴
保護パスや認証情報の隠蔽が当てにならなくなる
有効にした状態では、保護パスとcredentials.filesのエントリを含め、sandboxの制限のどれも悪意あるコマンドを止める根拠にできません。auto-allowモードでは、そのコマンドが許可の確認なしで動くこともあります。組織にセキュリティチームがあるなら、有効にする前に相談する前提の設定です。
auto-allowモードとcredentials.filesで何が変わるか
sandboxのauto-allowモードは、sandbox内で動くコマンドを許可の確認なしで通すモードです。「sandboxが囲っているから確認は要らない」という理屈で成り立っています。このキーをtrueにすると、その囲いが信用できなくなるのに、確認の省略だけは残ります。
credentials.filesは、認証情報のファイルをsandbox内のコマンドから隠すための設定です。denyなら読み取りを止め、maskならトークンの代わりに見せかけの値(sentinel)を読ませ、実際の値はプロキシが送信時に差し替えます。どちらもsandboxの境界が破れていないことが前提で、境界が破れると隠したはずの認証情報の保護も当てにできません。
そのため、認証情報をcredentials.filesで隠している環境ほど、このキーを入れる前に影響を見積もる価値があります。
なお、auto-allowモードでも、Bash(git push *)のような内容を指定したaskルールは、sandbox内のコマンドにも確認を出します。Bashのdenyルールに一致する形のコマンドも止まります。確認を残したい操作があるなら、このキーを入れる前にaskルールかdenyルールで押さえておく手があります。
変更履歴の側にも、同じ趣旨の一文があります。v2.1.305の項目は「sandboxのファイル保護を回避できる」と明記しています。リリースの全体像はv2.1.305のリリースノートにあります。
保護パスの記述自体にも、allowNestedUserNamespacesをtrueにしたときは保護パスをあてにしないという注意書きがあります。「保護パスで.gitの中身を守っているから大丈夫」という前提は、このキーを入れた時点で崩れます。
Podman・Buildahは別の道で動かす
名前の印象と違い、rootlessのPodmanとBuildahにこのキーは足りません。設定リファレンスは、これらにはexcludedCommandsを使うよう書いています。sandboxは別の方法でも両者を止めるためです。
{
"sandbox": {
"enabled": true,
"excludedCommands": ["podman *"]
}
}この書き方は、パターン例に沿った形です。注意点は3つあります。
- パターンの末尾は
*にする。podmanだけだと引数なしのpodmanしか一致しない - 一致したコマンドはsandbox外で、あなたのフルアクセスで動く。作業ディレクトリのスクリプトをClaudeが書き換えてから実行できる点にも注意
- パターンはClaudeが実行するコマンドの文字列と照合される。ブラウザなら、ブラウザそのものでなくテストコマンドに一致させる
書き方の細かい規則と既知の落とし穴は、excludedCommandsの解説にあります。
組織で止めるには
管理者の側から見ると、このキーは「開発者が自分で弱められる設定」の一つです。管理者向けの節には、enableWeakerNestedSandboxなどと並んでallowNestedUserNamespacesが載っています。管理設定がこれらを設定していなければ、開発者はユーザー設定や--settingsでtrueにできます。
使わせたくないなら、管理設定でfalseを書きます。管理設定がBoolean系のキーに値を持つと、ローカルで設定された値は無視されるからです。
{
"sandbox": {
"enabled": true,
"allowNestedUserNamespaces": false
}
}管理者向けの節は、このキーをallowAppleEventsと並べて「リポジトリからは有効にできない」と書いています。管理設定の全体像は組織管理ガイドを参照してください。
allowNestedUserNamespacesとenableWeakerNestedSandboxはどこが違うか
どちらもsandboxを弱める設定で、管理者向けの節に並んで載っています。名前が似ていますが、直す症状も、書ける場所も違います。
| 比較軸 | allowNestedUserNamespaces | enableWeakerNestedSandbox |
|---|---|---|
| 直す症状 | allowNestedUserNamespacesChromium・ElectronのNo usable sandbox!など、user namespaceが作れない | enableWeakerNestedSandbox特権のないコンテナ内でbwrapが/procをマウントできない |
| 書ける場所 | allowNestedUserNamespacesユーザー設定、--settings、管理設定。リポジトリの設定は無視 | enableWeakerNestedSandboxどのファイルでも書ける。ただし管理者が必須にしたsandboxでは、リポジトリのtrueは無視 |
| 手放す防御 | allowNestedUserNamespacessandboxの境界そのもの。保護パスやcredentials.filesも当てにできない | enableWeakerNestedSandboxコンテナの/procを見せるため、プロセス情報が隠れなくなる。外側のコンテナの隔離が前提 |
| 管理設定での止め方 | allowNestedUserNamespacesfalseを書く | enableWeakerNestedSandboxfalseを書く |
見分け方は症状です。Can't mount procならコンテナの問題で、後者です。No usable sandbox!やunshareの失敗なら、user namespaceの問題で、前者です。前者がリポジトリの設定を最初から受け付けないのに対し、後者はリポジトリからも書けるため、管理設定でfalseを置く意味が大きくなります。
WSL2でも同じ症状が出る
このキーが対象とするのはLinuxとWSL2です。WSL2はLinuxと同じbubblewrapでsandboxを作るので、ChromiumやPodmanの症状も、設定の書き方も同じになります。ネイティブWindowsではコマンドがsandboxなしで動くため、このキーの出番がありません。WSL1ではsandbox自体が起動せず、Sandboxing requires WSL2と出ます。
WSL2でbubblewrap自体が起動しない場合は、AppArmorがuser namespaceを制限していることがあります。sysctl kernel.apparmor_restrict_unprivileged_usernsが1を返すなら制限が有効です。このキーとは別の話なので、混同しないようにしてください。
どれを選ぶか
迷ったときの組み合わせを、症状別にまとめます。
| 状況 | 候補 | 補足 |
|---|---|---|
| E2Eテストで自分が管理するChromiumを動かす | 候補--no-sandbox | 補足Claude Codeのsandboxは残るが、ブラウザは無防備になる |
| ブラウザ自身のsandboxも残したい | 候補allowNestedUserNamespaces | 補足代わりにClaude Codeのsandboxの防御を当てにできない |
| rootless PodmanやBuildah | 候補excludedCommands | 補足このキーだけでは足りない |
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1のセッション | 候補ブラウザに--no-sandbox、他は手元で実行 | 補足このキーもexcludedCommandsも効かない |
| 管理下のマシン | 候補管理設定でfalse | 補足開発者の判断に任せない |
Ubuntu 24.04以降でbubblewrap自体が動かない場合は、AppArmorの設定が原因のことがあります。これはsandboxの導入手順の話なので、sandboxの有効化の解説と、全体の選び方をまとめたsandbox環境の選び方に当たってください。