Claude Media
Claude Codeのdevcontainerで承認なしに回す条件

Claude Codeのdevcontainerで承認なしに回す条件

devcontainerで承認なしに回す前に確かめる条件を整理しました。非rootのremoteUser、ホストに直結するワークスペース、外向き通信の制限、auto modeとの使い分けまでを扱います。

devcontainerの中でClaude Codeを --dangerously-skip-permissions 付きで回すと、承認プロンプトなしで無人運転できます。ただし、この組み合わせが安全側に倒れるのは4つの条件がそろったときだけです。作業ユーザーが非root、ワークスペースがホストに直結していると理解している、外向き通信を絞っている、信頼できるリポジトリである。この記事では、4つを順に確かめ、1つでも欠けるときの代替(auto mode)までを扱います。

非rootでないとフラグそのものが拒否される

LinuxとmacOSでは、rootまたは sudo 配下で bypassPermissions を起動すると、Claude Codeは次のメッセージを出して始まりません。

--dangerously-skip-permissions cannot be used with root/sudo privileges for security reasons

イメージの既定ユーザーがrootだと、ここが最初のつまずきです。devcontainer.json の remoteUser を非rootのアカウントにします。ドキュメントは、コンテナが非rootでClaude Codeを動かし、コマンド実行をコンテナ内に閉じ込めるからこそ、このフラグを無人運転に使えると説明しています。

{
  "image": "mcr.microsoft.com/devcontainers/base:ubuntu",
  "features": {
    "ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {}
  },
  "remoteUser": "vscode"
}

vscode はMicrosoftのbaseイメージが用意する非rootユーザーの例です。自前のDockerfileなら、そこで作ったユーザー名に置き換えます。id -u で確かめ、0 が返るならrootのままです。

認識された隔離環境の中では、このrootチェック自体が自動でスキップされます。とはいえ、devcontainerがその対象に入るかは、devcontainerのページに書かれていません。devcontainerでは「非rootにして使う」前提で組むのが、文書どおりの経路です。

ワークスペースの変更はホストにそのまま出る

コンテナに閉じ込められるのは「コマンドの実行」です。ファイルは閉じ込められません。ワークスペースはホストのリポジトリをバインドマウントしているため、Claudeがコンテナ内で消したファイルは、ホストのリポジトリからも消えます。

くらべる

承認を外したとき、コンテナが守るものと守らないもの

守られる

コンテナが隔てるもの

ホストのOSへ直接及ぶコマンド実行、コンテナ外のプロセス、マウントしていないホストのファイルです。

守られない

コンテナが隔てないもの

バインドマウントしたワークスペースの全ファイル、コンテナ内に置いた認証情報(~/.claude を含む)、ネットワーク規則が許す宛先です。

この線引きから、準備が3つ決まります。

  • 作業前にブランチを切るかコミットしておき、git diff と git restore で戻せる状態にする
  • ホストの ~/.ssh やクラウドの認証情報ファイルをマウントしない。必要なら、リポジトリ単位や短期のトークンを使う
  • 重要なファイルはバインドマウントの外に置く

3つめは、ワークスペースをコンテナ内の名前付きボリュームにクローンする構成で実現できます。ホストに反映される経路自体がなくなるため、承認を外した作業の影響範囲が小さくなります。

外向き通信を絞らないと持ち出しを防げない

ドキュメントの警告ははっきりしています。--dangerously-skip-permissions で動かすと、悪意あるプロジェクトはコンテナ内でアクセスできるすべてのものを外へ持ち出せます。そこには ~/.claude に保存されたClaude Codeの認証情報も入ります。

承認の関門を外した以上、残る防御線はネットワークです。ドキュメントも、このフラグはネットワークの外向き制限と組み合わせるよう案内しています。参照構成の init-firewall.sh は、許可した宛先だけに外向き通信を絞ります。実行にはcapabilityの追加が必要です。

"runArgs": [
  "--cap-add=NET_ADMIN",
  "--cap-add=NET_RAW"
]

スクリプトの中身、許可先の調べ方、起動時に止まったときの切り分けは、devcontainerのinit-firewall.shにまとめています。ファイアウォールを使わず自前のネットワーク制御に任せる選択も、ドキュメントは認めています。その場合も「外向きを絞らずに承認を外す」組み合わせにはしないのが、この節の要点です。

起動してから確かめる

条件がそろったら、コンテナ内のターミナルで次を実行します。

id -u
claude --dangerously-skip-permissions

id -u が 0 以外であることを確かめてから起動します。起動後は、ステータスバーに bypass permissions on と出ているかを見ます。無人実行(-p)で走らせるなら、次の形です。

claude -p "テストが通るまで src/ の失敗を直して" \
  --dangerously-skip-permissions

-p の実行では、bypassPermissions でも確認が残る少数の操作は、プロンプトを出さずに拒否されます。

承認を外しても残る確認がある

bypassPermissions は「何でも通す」モードではありません。次のものは、どのモードでも自動承認されません。

  • 明示したaskルールに合致するツール
  • 認識された rm や rmdir による重要パスの削除
  • ユーザーとの対話を要するツール(AskUserQuestion など)

さらに、denyルールは bypassPermissions でも効きます。反対にallowルールはこのモードでは効果を持ちません。つまり「触らせたくない領域」は、承認を外す前にdenyルールで書いておけます。

落とし穴

settings.json に書いても bypassPermissions で始まらない

defaultMode: "bypassPermissions" を .claude/settings.json や .claude/settings.local.json に書いても有効になりません。セッションはManualで始まります。リポジトリにコミットした設定で、他人のセッションが承認なしに始まらないための仕組みです。起動時にフラグで指定するか、ユーザー設定・--settings・managed settingsに書きます。

初回の警告ダイアログとVS Code拡張の切り替え

このモードで対話セッションを初めて始めると、Claude Codeは「承認なしの操作の責任を受け入れるか」を尋ねる警告ダイアログを出します。拒否すると終了します。受け入れると、~/.claude/settings.json に skipDangerousModePermissionPrompt: true が書かれ、以降のセッションでは出なくなります。-p の非対話実行にはダイアログがありません。

devcontainerでは、これが再構築のたびに戻ってくる点に注意が要ります。ホームディレクトリは再構築で捨てられるため、~/.claude を名前付きボリュームに載せていないと、受け入れた記録も消えます。--bg で始めるバックグラウンドセッションは、ユーザー設定かmanaged settingsに受け入れが記録されていないと拒否されます。設定の永続化は、承認を外す運用の前提にもなります。

VS Code拡張のパネルから使う場合は、別の条件があります。拡張の設定にあるAllow dangerously skip permissionsを有効にしないと、モード表示にBypass permissionsが出ません。bypassPermissions を指定していても、会話はManualで始まります。ターミナルで claude --dangerously-skip-permissions と打つ経路とは条件が違うので、拡張側で承認なしを使うなら、このトグルを先に確かめます。

承認は外したくないときの代替

「プロンプトは減らしたいが、安全確認まで消したくない」なら、auto modeが選択肢です。分類器が実行前に操作を審査します。ドキュメントはdevcontainerのページでもpermission modesのページでも、bypassよりauto modeを先に検討するよう案内しています。auto modeには対応モデルなどの利用条件があり、組織側で無効化もできます。条件はdisableAutoMode設定の記事に、独自ルールの足し方はautoModeの独自ルールの記事にあります。

使い分けは、次のように考えられます。

状況向く選択理由
無人で長時間回す、外向き通信も絞った向く選択--dangerously-skip-permissions理由承認を待たずに進められ、持ち出しはネットワーク側で止められる
人が見ているが、確認回数は減らしたい向く選択auto mode理由分類器が審査するので、安全確認が残る
信頼できないリポジトリを扱う向く選択どちらも避ける理由外向き通信を絞っても、ワークスペースは破壊されうる

チームでフラグ自体を使わせないとき

チームの運用では、フラグを許すより禁止する側の設定が先に要る場合があります。permissions.disableBypassPermissionsMode を "disable" にすると、bypassPermissions を使えなくできます。リポジトリの設定でも書けますが、書き換えられないのは管理者配布のmanaged settingsに置いたときです。devcontainerのDockerfileで /etc/claude-code/managed-settings.json を置く方法もありますが、リポジトリに書ける人は消せます。確実に縛るなら、サーバー管理の設定かMDMを使います。

{
  "permissions": {
    "disableBypassPermissionsMode": "disable"
  }
}

フラグ単体の挙動と、planモードから切り替える --allow-dangerously-skip-permissions の違いは、別の記事で扱っています。承認を外した状態でdevcontainerを使う実例は、脆弱性診断の報告書を再現する手順にあります。

承認モードと隔離は別々に決める

permission modesのページは、2つを別の軸として説明しています。承認モードは「実行前に聞くか」を決め、Bashサンドボックスと外側の隔離境界は「実行された操作が何に届くか」を決めます。bypassPermissions を「コンテナ、VM、サンドボックスランタイムの中でのみ」とする表の注記は、前者を外す代わりに後者を必須にするという意味です。

devcontainerはこの外側の隔離にあたります。承認を外すかどうかとは別に、コンテナの形(非root、マウント、ネットワーク)を先に決めてください。順序を逆にして、承認を外してから隔離を考えると、上で見た4つの条件のどれかが抜けやすくなります。なお、クラウドセッションは設定ファイルの bypassPermissions を無視するため、同じ運用をそちらへそのまま持ち込めません。

まとめ

承認なしの運転は、フラグ1つで始められます。そのぶん、非rootの remoteUser、ワークスペースの扱い、外向き通信の制限が、フラグの代わりに安全を受け持ちます。ホストにマウントしたリポジトリは壊れうると割り切り、戻せる状態を先に作っておけば、無人実行の失敗はgit restoreで済む範囲に収まります。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. code.claude.com/docs/en/devcontainer
  2. code.claude.com/docs/en/permission-modes
  3. code.claude.com/docs/en/cli-reference
この記事を共有:XはてブLinkedIn