← 記事一覧
Guide

auto modeとロックダウンした権限で、dev container内でClaude Codeを安全に動かす

A secure developer workstation scene: a laptop connected to an isolated container box, outbound network arrows passing t

Anthropicは、Claude Codeをヘビーに使う人なら誰もがすでに肌で感じている問題に、はっきり数字を出した。ユーザーは権限プロンプトの約93%を承認しており、プロンプトが積み重なるほど注意力は落ちる、と同社は言っている(Anthropic)。これは承認疲れだ。そして「human in the loop」は「Enterを押し続ける人間」に変わってしまう。

間違った対応は、自分のノートPCで--dangerously-skip-permissionsを付けて実行し、モデルが行儀よく振る舞うことを祈ることだ。正しい対応は、退屈なセキュリティエンジニアリングである。Claude Codeをdev containerに入れ、渡すのはリポジトリだけにし、外向き通信を制限し、ポリシーでbypass modeを無効化し、auto modeは本当にサポートされている場所でだけ使う。

このガイドでは、今日そのままリポジトリに入れられる実行可能なセットアップを示す。あわせて、今コミュニティで起きている議論にも触れる。開発者はエージェントにもっと自律的に動いてほしい。一方で、見えないガードレールやブラックボックスなファイル探索は望んでいない。現実的な答えは「Claudeをもっと信じろ」ではない。「自律性を受け入れられるくらい、爆発半径を小さくしろ」だ。

ホストエディタ、dev container、非rootユーザーとして動くClaude Code、管理された設定を示すカバー風アーキテクチャスケッチ

この議論の本質は、観測可能性と爆発半径にある

「Anthropic tries to hide Claude’s AI actions」をめぐるHacker Newsのスレッドは、単なる愚痴大会ではない。あるコメントは、開発者の不安をうまく要約していた。エージェントが古い設定ファイルを開き始めたり、関係ないファイルを這い回り始めたりしたら、操作者はそれを止められるだけの速さで知る必要がある(Hacker News)。Claude Codeを「危険に」動かす話題の別スレッドでも、結論は同じ実践パターンに収束していた。エージェントには自由に動かせ。ただし、ファイルとネットワークのアクセスを制限したサンドボックスの中だけで、というものだ(Hacker News)。

Anthropic自身のエンジニアリング記事も、同じ地点に着地している。防御を環境、モデル、外部コンテンツに分けている。そのうち環境は、あなたが決定論的にできる部分だ。認証情報がサンドボックスに入らなければ、原因がプロンプトインジェクションであれ、モデルの行き過ぎであれ、悪いユーザー指示であれ、Claudeはそれを外に持ち出せない(Anthropic)。

auto modeはここに収まる。ただし魔法ではない。Anthropicによれば、auto modeは実行前に別の分類器でアクションをレビューする。ドキュメントでも、これは研究プレビューであり、センシティブな操作に対するレビューの代替ではないとされている(Claude Code docs)。この違いは重要だ。auto modeはプロンプトを減らす。コンテナは結果を小さくする。

チームには、次の方針をすすめる。

Mode使う場面使わない場面
plan不慣れなリポジトリ、リスクの高い変更長時間の無人編集
acceptEdits通常の機能開発デプロイ、シークレット、インフラ変更
auto外向き通信を制御した隔離済みdev container本番システムや未知のリポジトリ
bypassPermissions使い捨てVMのみ開発者のノートPC

Anthropicのドキュメントによると、auto modeにはClaude Code v2.1.83以降が必要だ。Anthropic APIでは、対応モデルにClaude Opus 4.6以降とSonnet 4.6が含まれる。Bedrock、Vertex AI、Microsoft Foundryでは、ドキュメント上、auto mode対応はOpus 4.7とOpus 4.8のみとされている(Claude Code docs)。

Dev Containerを作る

リポジトリに3つのファイルを作る。

.devcontainer/
  devcontainer.json
  Dockerfile
  managed-settings.json

まずは.devcontainer/devcontainer.jsonから。

{
  "name": "claude-code-safe",
  "build": {
    "dockerfile": "Dockerfile"
  },
  "remoteUser": "node",
  "mounts": [
    "source=claude-code-config-${devcontainerId},target=/home/node/.claude,type=volume"
  ],
  "runArgs": [
    "--cap-add=NET_ADMIN",
    "--cap-add=NET_RAW"
  ],
  "containerEnv": {
    "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1",
    "DISABLE_AUTOUPDATER": "1",
    "ANTHROPIC_BASE_URL": "https://api.onehop.ai/anthropic",
    "ANTHROPIC_API_KEY": "${localEnv:ONEHOP_API_KEY}"
  },
  "postCreateCommand": "sudo /usr/local/bin/init-firewall.sh"
}

Anthropicのdev containerドキュメントでは、コマンドがホストから離れた場所で実行されつつ、編集内容はマウントされたリポジトリに反映されるよう、Claude Codeをコンテナ内で動かすことを推奨している(Claude Code docs)。同時に、~/.sshやクラウド認証情報ファイルのようなホスト側のシークレットをマウントしないよう警告している。その助言に従おう。ClaudeにリポジトリスコープのGitHubトークンが必要なら、短命のものを環境変数経由で渡す。便利だからといって、ホームディレクトリ全体をbind mountしてはいけない。

次にDockerfile。

FROM mcr.microsoft.com/devcontainers/javascript-node:22

RUN npm install -g @anthropic-ai/claude-code@latest

COPY managed-settings.json /etc/claude-code/managed-settings.json
COPY init-firewall.sh /usr/local/bin/init-firewall.sh

RUN chmod +x /usr/local/bin/init-firewall.sh

AnthropicのドキュメントにはDev Container Featureも用意されているが、Dockerfile経由でインストールしたほうが、チームリポジトリ内でポリシーとバージョンを把握しやすい。再現性がほしいなら、@anthropic-ai/claude-codeを特定バージョンに固定し、DISABLE_AUTOUPDATER=1を維持する。

Auto Modeを有効にする前に権限をロックダウンする

.devcontainer/managed-settings.jsonを作る。

{
  "permissions": {
    "defaultMode": "auto",
    "disableBypassPermissionsMode": "disable",
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)",
      "Read(./config/credentials.json)",
      "Bash(curl *)",
      "Bash(wget *)",
      "Bash(git push *)",
      "Bash(kubectl *)",
      "Bash(terraform apply *)",
      "WebFetch(domain:169.254.169.254)"
    ],
    "ask": [
      "Bash(npm publish *)",
      "Bash(docker push *)",
      "Bash(gh release *)"
    ],
    "allow": [
      "Bash(npm install)",
      "Bash(npm test *)",
      "Bash(npm run lint *)",
      "Bash(git diff *)",
      "Bash(git status *)"
    ]
  },
  "autoMode": {
    "environment": {
      "trustedDomains": [
        "registry.npmjs.org",
        "github.com"
      ]
    }
  }
}

ここでは2つの細部が本当に効いている。

1つ目は、disableBypassPermissionsModebypassPermissionsをブロックし、managed settingsで強制されている場合に--dangerously-skip-permissionsフラグを無効化することだ。Anthropicはこの制御を設定リファレンスで明確に説明している(Claude Code docs)。

2つ目は、auto modeでもdenyルールが重要だということ。Anthropicは、auto modeがリクエストの範囲を超えるアクション、認識されていないインフラを対象にするアクション、敵対的なコンテンツに誘導されているように見えるアクションをブロックすると説明している。だが、チームのポリシーを分類器に丸投げすべきではない。エージェントセッションから誰もterraform applyを実行すべきでないなら、それはdenyルールとしてエンコードする。

注意点が1つある。リポジトリ管理のポリシーは、リポジトリを編集できる人なら誰でも変更できる。Anthropicのドキュメントでは、Linux内の/etc/claude-code/managed-settings.jsonは高い優先順位を持つとされている。ただし、開発者がリポジトリファイルを編集して回避できないポリシーにしたいなら、server-managed settingsかMDMを使うべきだ(Claude Code docs)。スタートアップチームなら、チェックインされたポリシーでも良いベースラインになる。エンタープライズ展開なら、そこで止めてはいけない。

左右比較パネル。左はホストのノートPC上でホームディレクトリ、SSHキーなどにアクセスできるClaude Codeを示す

小さな許可リストで外向き通信を制限する

.devcontainer/init-firewall.shを追加する。

#!/usr/bin/env bash
set -euo pipefail

ALLOWED_HOSTS=(
  api.onehop.ai
  api.anthropic.com
  claude.ai
  platform.claude.com
  registry.npmjs.org
  github.com
  raw.githubusercontent.com
)

iptables -P OUTPUT DROP
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

for host in "${ALLOWED_HOSTS[@]}"; do
  for ip in $(getent ahostsv4 "$host" | awk '{print $1}' | sort -u); do
    iptables -A OUTPUT -p tcp -d "$ip" --dport 443 -j ACCEPT
  done
done

iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT

これは意図的にシンプルにしている。起動時に許可されたホスト名を解決し、そのIPへのTCP 443を許可する。プロダクション級の制御にするなら、コンテナをプロキシの背後に置き、すべてのリクエストをログに残すべきだ。それでも、この基本的なデフォルト拒否ルールだけで、自律的なコーディングエージェントをインターネット全体に話せる状態にしておくよりはずっといい。

Anthropicのネットワークドキュメントには、インストール経路や認証経路に応じて、api.anthropic.comclaude.aiplatform.claude.comdownloads.claude.aistorage.googleapis.comraw.githubusercontent.comなどの必要ドメインが挙げられている(Claude Code docs)。npm経由でインストールし、自動更新を無効にするなら、実行時にダウンロード用ドメインは不要かもしれない。リストは絞り、ビルドが明確な理由で失敗したときだけドメインを追加する。

実行する。

export ONEHOP_API_KEY=oh_your_key_here
code .
# VS Code: Dev Containers: Rebuild and Reopen in Container
claude --permission-mode auto

コンテナ内で確認する。

whoami
claude --version
curl -I https://api.onehop.ai
curl -I https://example.com

OneHopへのリクエストは成功するはずだ。example.comへのリクエストは、追加していない限り失敗するはずである。

Claude Fable 5をOneHop経由で使う

Anthropicは2026年6月9日にClaude Fable 5とClaude Mythos 5をリリースした。Fable 5の価格は入力100万トークンあたり10ドル、出力100万トークンあたり50ドルで、Mythos Previewの半額未満だ(Anthropic)。OneHopはClaude Fable 5をanthropic/claude-fable-5として掲載しており、公式価格は入力$10/M、出力$50/M、OneHop価格は入力$3/M、出力$15/Mと表示されている。さらに、新規ユーザーにはカード不要で10ドルの無料クレジットが付く(OneHop)。

現時点の運用メモとして、OneHopのFable 5ページでは、モデルは掲載されたまま一時的に利用不可とされている。設定は残しておいてよいが、自分のアカウントとリージョンでアクセス可能になってから使う前提にしておく。

OneHop経由でAnthropic Messagesを直接呼ぶなら、このモデル向けにOneHopが公開しているAnthropic互換エンドポイントを使う。

from anthropic import Anthropic

client = Anthropic(
    base_url="https://api.onehop.ai/anthropic",
    api_key="oh_your_key_here",
)

message = client.messages.create(
    model="anthropic/claude-fable-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Summarize this repo's test strategy."}],
)

print(message.content[0].text)

すでにアプリがOneHopのOpenAI互換ゲートウェイを使っているなら、base URLの1行変更はこうなる。

client = OpenAI(base_url="https://api.onehop.ai/v1", api_key="oh_your_key_here")

Claude Codeについては、ANTHROPIC_BASE_URLにAnthropic互換のbase URLを使う。Claude CodeはAnthropic Messages APIを話すからだ。OneHopのFable 5モデルページでは現在、このモデルでAnthropic Messagesがhttps://api.onehop.ai/anthropicで利用可能とされている一方、OpenAI Chat Completionsは非対応と表示されている(OneHop)。

モデルごとに3本のバーを持つコンパクトな価格比較チャート。Fable 5のAnthropic表示価格は入力$10、出力$50

運用モデル:信頼を減らし、出荷を速くする

最高のClaude Codeセットアップは、最も寛容なセットアップではない。ミスが安く済むセットアップだ。

Claudeが新しいコードベースを探索するときはplan modeを使う。タスクの範囲が絞れたあとでだけautoに切り替える。bypassPermissionsはポリシーで無効にしておく。シークレットの読み取りを拒否する。デプロイ、保護ブランチへのpush、クラウドの変更、メタデータエンドポイントへのアクセスを拒否する。エージェントは非rootのdev containerに入れる。外向き通信はデフォルトでブロックする。マージ前にdiffをレビューする。

それはYOLO modeより遅く聞こえるかもしれない。実際には速い。40個の些末なプロンプトを見張る必要も、いま承認した操作でモデルがトークンを外に持ち出したのではないかと不安になる必要もないからだ。Anthropic自身の隔離に関する記事では、参照用dev containerはClaude Codeがアクションごとの承認なしに無人で動けるようにするためのものだと述べられている(Anthropic)。足りないピースはチームポリシーだ。

プロバイダースタックを作り直さずにFableクラスのコーディング作業を試す最短ルートがほしいなら、Claude Fable 5 on OneHop経由でルーティングすればいい。新規アカウントは10ドル無料で始められる。base URLの変更は簡単な部分だ。本当の価値は、それを自律性を使える程度に安全にするコンテナと組み合わせるところにある。