0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude Code 2.1.305入門、userns許可とMCP許可リスト変更の判断軸

0
Posted at

はじめに

Claude Code の sandbox を有効にした Linux 環境で、Chromium が No usable sandbox! で止まったり、rootless Podman が起動しなかったりした経験はないでしょうか。2026-10-20 付けの Claude Code 2.1.305 で、この問題に向けた設定 sandbox.allowNestedUserNamespaces が入りました。ところが同じリリースには、組織で配っている MCP サーバーの読み込み条件を変える変更も含まれています。片方は「オンにすると守りが一段外れる設定」、もう片方は「何もしなくてもアップグレードだけで挙動が変わる変更」です。どちらも、手を入れる前に判断が要ります。

対象読者は、Linux / WSL2 で Claude Code の sandbox を使っている開発者と、managed-mcp.json や allowedMcpServers で MCP サーバーを管理している管理者です。

この記事の内容は、公式の changelog・sandboxing・managed-mcp の各ページに基づく解説です。後半の「執筆環境で確かめられた範囲」で、カーネル側の前提だけを別に扱います。

TL;DR

この記事を読むと、次の 3 点を判断できるようになります。

  • sandbox.allowNestedUserNamespaces を true にすべきか、--no-sandbox や excludedCommands で済ませるべきか
  • 2.1.305 へのアップグレードで、自組織の managed-mcp.json のサーバーが意図せず読み込まれ始めるか
  • 読み込まれ始める場合に、アップグレード前に deniedMcpServers とグループ別配布のどちらで止めるか

2.1.305 で変わった 2 点

公式の changelog(code.claude.com/docs/en/changelog)では、2.1.305 は October 20, 2026 の見出しで掲載されています。今回扱うのは次の 2 項目です。

区分 項目 changelog の記述(要旨) 影響を受ける人
Added sandbox.allowNestedUserNamespaces Linux の sandbox 内のコマンドが user namespace を作れるようにする(Chromium・rootless podman 向け)。sandbox のファイル保護を回避できてしまう Linux / WSL2 で sandbox を使う開発者
Changed allowedMcpServers env の中でだけ ${VAR} を使う managed-mcp.json の stdio サーバーを、allowlist で除外しなくなった。allowlist で外していたサーバーはアップグレードで読み込まれ始める。止めたいなら deniedMcpServers を使う MCP サーバーを組織配布している管理者

user namespace は Linux カーネルの機能で、一般ユーザーのプロセスが「自分専用の root」を持つ隔離空間を作れます。Chromium は自前のサンドボックスに、rootless Podman はコンテナの実行に、この仕組みを使います。

手順1: allowNestedUserNamespaces を設定するか決める

何が失敗していたのか

sandboxing ページのトラブルシューティング(Chromium or rootless podman fails inside the sandbox on Linux)によると、Linux と WSL2 では sandbox 内のコマンドは既定で user namespace を作れません。そのため user namespace に頼るツールが失敗し、例として次の 2 つの症状が挙げられています。

  • Chromium が No usable sandbox! で起動しない
  • unshare -U true が Operation not permitted で失敗する

allowNestedUserNamespaces は、この制限を外すための設定です。

判断フロー

設定を入れる前に、次の順で考えると迷いにくくなります。

true にする前に「代替手段で足りるか」と「何を失うか」を確かめる順番にしてあります。この順番にした理由は、続く 3 つの小節に書いた公式の注意事項です。

設定する場合の書き方

公式によると、設定先は ユーザー設定の ~/.claude/settings.json で、プロジェクトの .claude/settings.json ではありません。また Claude Code v2.1.305 以上が必要です。

公式の記述(sandbox.allowNestedUserNamespaces を true にする)を settings.json の入れ子で書くと、次の形になります。

{
  "sandbox": {
    "allowNestedUserNamespaces": true
  }
}

settings-reference の索引では、このキーの Scope は "User or managed"、説明は "Let sandboxed commands create user namespaces on Linux and WSL2" です。リポジトリに置くプロジェクト設定からは有効化できない作りになっています。

settings-reference の詳細エントリによると、型は Boolean、既定値は false です。true が有効になるのは、~/.claude/settings.json、--settings で渡した JSON、managed settings のいずれかに書いた場合で、プロジェクトの .claude/settings.json と .claude/settings.local.json に書いた true は無視されます。

true にすると何を失うか

sandboxing ページは、この設定に 2 か所で WARNING を付けています。

  1. トラブルシューティング節: true にするとセキュリティ境界を 1 つ外すことになり、sandbox 内のコマンドから出たコードが sandbox の外で動く可能性がある
  2. Protected paths 節: Linux / WSL2 で true にしたなら protected paths に頼らないこと

公式は、credentials.files にも頼れなくなること、auto-allow の運用では悪意あるコマンドが承認なしで走りうることにも触れています。changelog の「sandbox のファイル保護を回避できてしまう」という一文は、この意味です。

つまり、sandbox を「設定ファイルや認証情報を守る壁」として使っている環境ほど、true の代償が大きくなります。

この設定だけでは足りないケース

公式は、次の 2 点も明記しています。

  • rootless Podman と Buildah は、この設定だけでは動きません。 sandbox がほかの方法でも止めているためです。
  • unshare で始まるコマンドは、excludedCommands にどんなパターンを書いても sandbox 内に残ります。 unshare は任意の別プログラムを起動できるため、除外の対象にならない設計です。

Podman を sandbox 内で使いたいという動機だけで true にすると、守りを外したのに目的は果たせない、という結果になりえます。

設定しない場合の代替

公式は、ツール別に次の代替も挙げています。Chromium や Electron には --no-sandbox、rootless Podman や Buildah には excludedCommands(パターンの例は podman *)です。

手段 何をするか 注意点
Chromium の --no-sandbox Chromium 側のサンドボックスを使わずに起動する Chromium 自身の隔離がなくなる
excludedCommands 特定のコマンド(podman * など)を Claude Code の sandbox の外で実行する unshare で始まるコマンドには効かない。公式によると、一致したコマンドは sandbox の外で動き、実行前に作業ディレクトリのスクリプトを Claude が書き換えうる
allowNestedUserNamespaces: true sandbox 内で user namespace を作れるようにする protected paths・credentials.files に頼れなくなる

どれも何かを手放す選択で、無償の手段はありません。違いは「手放す範囲」です。--no-sandbox や excludedCommands は特定のツール・コマンドに範囲を絞れますが(excludedCommands に一致したコマンドは sandbox の外で動く点は前述のとおりです)、allowNestedUserNamespaces は sandbox 内のコマンド全体に効きます。

管理者の場合

sandboxing ページの「Keep developers from widening the policy」節によると、allowNestedUserNamespaces はリポジトリ側からは有効化できない設定の 1 つで、managed settings で false にできます。開発者個人の ~/.claude/settings.json で true にされたくない組織は、managed settings 側で固定しておくのが確実です。

手順2: allowedMcpServers の変更がチームに影響するか確かめる

変わった範囲を正確に押さえる

ここは誤読しやすい箇所です。「managed-mcp.json の全サーバーが allowlist の対象外になった」わけではありません。

managed-mcp ページ(code.claude.com/docs/en/managed-mcp.md)の説明を整理すると次のとおりです。

managed-mcp.json のサーバーの書き方 2.1.305 より前 2.1.305 以降
${VAR} 展開を使わない allowlist のエントリ不要(v2.1.259 以降) allowlist のエントリ不要
${VAR} を env の中でだけ使う allowlist でチェックされた チェックされない(allowlist のエントリ不要)
${VAR} を env の外(command・args・URL・headers)で使う allowlist でチェックされた 従来どおりチェックされる

公式の表現では、managed-mcp.json のサーバーは allowedMcpServers のエントリを必要とせず、例外は ${VAR} 展開を env の外で使う場合だけです。2.1.305 より前は、env の中でだけ使う場合もチェックしていました。今回の変更は、表の 2 行目だけが動いたものです。なお公式によると、v2.1.259 より前は allowlist を設定している間、managed-mcp.json のすべてのサーバーがチェックされていました。表の「2.1.305 より前」は v2.1.259 以降を指します。

サーバーが評価される順番

managed-mcp ページの「How a server is evaluated」をもとに、managed-mcp.json のサーバーが読み込まれるまでの流れを図にします。

denylist は allowlist より先に評価され、denylist に一致したサーバーはどの設定でも上書きされずにブロックされます。公式は "Nothing overrides a denylist match." と書いています。

影響を受ける運用

影響が出るのは、次の条件がそろう組織です。

  1. managed-mcp.json で stdio サーバーを配っている
  2. そのサーバーは ${VAR} を env の中でだけ使っている(例: API キーを環境変数から渡す)
  3. allowedMcpServers からそのサーバーをあえて外すことで、特定のユーザーやグループでは読み込ませないようにしていた

managed-mcp ページによると、このようなサーバーは、チェックしないバージョンを各ユーザーが初めて起動した時点で読み込まれ始めます。プロンプトも通知もありません。ユーザーから見ると、ある日から MCP サーバーが増えているだけです。

対処: アップグレード前に止める

公式が示している対処は 2 つで、どちらも ユーザーがアップグレードする前に 済ませる必要があります。

  • deniedMcpServers にそのサーバーを追加する。 denylist は最優先なので、allowlist の扱いが変わっても確実に止まります。
  • グループごとに別の managed-mcp.json を配る。 「全員に配って allowlist で絞る」構成をやめ、そもそも読み込ませたくないグループにはそのサーバーを含めない形にします。

照合キーは serverUrl・serverCommand・serverName の 3 種類です。値の具体的な書式は managed-mcp ページの例に合わせてください。

serverName はセキュリティ制御ではない

managed-mcp ページは "A serverName entry, in either list, is not a security control." と明記しています。serverName はユーザーが付けるラベルにすぎないため、名前を変えれば一致しなくなります。denylist で確実に止めたいなら、serverUrl か serverCommand で指定します。allowlist 側も同様です。

アップグレード前チェックリスト

2.1.305 以上へ上げる前に、次を確認しておくと安全です。

sandbox(開発者・管理者)

  • sandbox 内で user namespace が必要なツールはどれか(Chromium / Podman / Buildah)を洗い出した
  • Chromium だけなら、--no-sandbox か excludedCommands で足りるか検討した
  • Podman / Buildah は allowNestedUserNamespaces だけでは動かないことを共有した
  • unshare で始まるコマンドは excludedCommands で外に出せないことを共有した
  • protected paths・credentials.files に頼った運用がないか確認した(あるなら true にしない)
  • 組織として許可しないなら、managed settings で false に固定した

MCP(管理者)

  • managed-mcp.json のサーバーのうち、${VAR} を env の中でだけ使うものを一覧にした
  • そのうち、allowedMcpServers から外すことで止めていたものがあるか確認した
  • 該当するサーバーを deniedMcpServers に追加したか、グループ別の managed-mcp.json に切り替えた
  • denylist・allowlist の指定を serverName ではなく serverUrl / serverCommand で書いた

執筆環境で確かめられた範囲と、筆者の判断

この記事を書いたクラウドのコンテナで確かめたのは、カーネル側の前提だけです。結果は次のとおりでした。

確認項目 コマンド 結果
Claude Code のバージョン claude --version 2.1.310(2.1.305 以上)
カーネル uname -r 6.18.44-fc-v153
user namespace の上限 cat /proc/sys/user/max_user_namespaces 64280(機能は有効)
user namespace の作成 unshare -U -r id uid=0(root)、終了コード 0
ネストした作成 unshare -U -r unshare -U -r id uid=0(root)、終了コード 0

注意点として、これは Claude Code の sandbox の外にある、通常の root シェルでの結果 です。公式が書いている「sandbox 内では unshare -U true が Operation not permitted になる」という条件とは別物で、この結果からその挙動の再現も否定もできません。読み取れるのは「このカーネルでは user namespace 自体は作れる。sandbox 内で失敗するなら、原因はカーネルではなく sandbox 側の制限だ」という切り分けの材料までです。sandbox を有効にした状態での true / false の挙動差、managed-mcp.json の ${VAR} の挙動、2.1.305 より前との比較は確かめていません。

そのうえで、ここからは筆者の意見です。

1 つ目に、allowNestedUserNamespaces は「困ったら入れる設定」ではなく「代替を検討し尽くしてから入れる設定」だと考えます。公式自身が 2 か所で WARNING を付け、Podman / Buildah にはこれだけでは足りないとも書いているからです。Chromium だけが目的なら、excludedCommands で対象を絞るほうが失うものを見積もりやすいはずです。

2 つ目に、2.1.305 の本当の注意点は MCP 側だと考えます。sandbox の設定は自分で true にしない限り何も変わりませんが、allowedMcpServers の変更はアップグレードしただけで効きます。しかも公式の表現どおり「プロンプトも通知もなく」効くため、ユーザー側のアップグレードが管理者のチェックより先に起きると気づく機会がありません。allowlist から外すことで止める運用は、denylist で止める運用に置き換えておくのが堅い選択だと思います。

3 つ目に、${VAR} を env の外で使うサーバーが従来どおりチェックされる点は、設定の書き方で挙動が分かれることを意味します。同じ API キーでも、env で渡すか args に埋め込むかで allowlist の扱いが変わります。サーバーごとの書き方を一覧にしてから判断するのが、遠回りに見えて確実です。

関連記事

参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?