Claude Code をプロキシ・社内CA・mTLS で使う

Claude Code エンジニアリング 8分で読めます

社内プロキシ、TLS 検査(SSL インスペクション)、クライアント証明書による認証が必須のネットワークでも、Claude Code は環境変数だけで通せます。この記事では公式ドキュメント Enterprise network configuration をもとに、プロキシ・社内CA・mTLS の設定と、その設定が本当に読み込まれたかを確かめる方法、そして許可リストに載せる接続先までを日本語でまとめます。

前提として押さえておきたい点が2つあります。1つは、ここで扱う環境変数はすべて settings.json でも設定できること。もう1つは、シェルで export した変数は起動時に一度だけ読まれることです。実行中のセッションは、あとからシェル側を変えても追従しません。

プロキシ経由で通信させる

Claude Code は標準的なプロキシ環境変数をそのまま解釈します。特別な独自変数を覚える必要はありません。

# HTTPS プロキシ(推奨)
export HTTPS_PROXY=https://proxy.example.com:8080

# HTTP プロキシ(HTTPS が使えない場合)
export HTTP_PROXY=http://proxy.example.com:8080

# 特定の宛先だけプロキシを通さない(空白区切り)
export NO_PROXY="localhost 192.168.1.1 example.com .example.com"
# 同じくカンマ区切りでも書ける
export NO_PROXY="localhost,192.168.1.1,example.com,.example.com"
# すべての通信でプロキシを使わない
export NO_PROXY="*"

小文字の変数名も有効です。複数が設定されている場合は https_proxyHTTPS_PROXYhttp_proxyHTTP_PROXY の順に見て、最初に設定されていたものが使われます。大文字と小文字の両方を残したまま片方だけ直しても効かないことがあるので、設定は1つに寄せておくと事故が減ります。

注意点として、SOCKS プロキシには対応していません

認証が必要なプロキシ

Basic 認証のプロキシなら、資格情報を URL に含めます。

export HTTPS_PROXY=http://username:password@proxy.example.com:8080

ただしスクリプトにパスワードを直書きするのは避け、環境変数や資格情報ストアから渡してください。NTLM や Kerberos のような高度な認証方式が必要な場合、公式はその方式に対応した LLM ゲートウェイを挟むことを勧めています。Claude Code 側でこれらの認証を行う設定はありません。

バックグラウンドエージェントにはシェルの export が届かない

ここが実運用でいちばん踏みやすい落とし穴です。claude agents--bg/background で動くセッションは、起動元のターミナルの中では走りません。ユーザーごとに1つの supervisor プロセスが必要に応じて起動し、シェルより長く生き続け、そこがバックグラウンドセッションのホストになります。

この supervisor は最初に起動したシェルの環境をそのまま引き継ぎます。OS のサービスとして入っている supervisor に至っては、シェルの環境を1つも受け取りません。つまりプロキシや証明書のパスをシェルでだけ export していると、そのシェルが supervisor を最初に起こしたときだけ届き、別のシェルが起こしたときは黙って届かないという不安定な状態になります。

対策は単純で、同じ変数を ~/.claude/settings.jsonenv ブロック、または管理者が配布する managed settings に書くことです。env は「すべてのセッションとそのサブプロセスに環境変数を設定する」設定で、この記事に出てくる変数はすべてここに置けます。設定ファイルだけが、どのマシンのどのバックグラウンドセッションにも確実に届く経路です。

{
  "env": {
    "HTTPS_PROXY": "https://proxy.example.com:8080",
    "NO_PROXY": "localhost,.example.com",
    "NODE_EXTRA_CA_CERTS": "/etc/ssl/certs/corp-ca.pem"
  }
}

組織の方針で、Claude Code のプロセスを必ず社内ランチャー経由で起動させたい場合もあります。supervisor とそのワーカーは PATH を引かずに固定パスから Claude Code を起動するため、PATH の前方に置いたラッパーはバックグラウンドエージェントには効きません。この用途には processWrapper 設定(macOS と Linux 向け。scope は user または managed)を使います。同等の環境変数 CLAUDE_CODE_PROCESS_WRAPPER は両方設定されたときに優先されますが、こちらも managed settings か ~/.claude/settings.json 経由で配ってください。すでに動いている supervisor は起動時の構成を保持するので、配布後に claude daemon stop --any を実行して次回起動時から反映させます。

社内CA証明書を信頼させる

既定の Claude Code は、同梱の Mozilla CA 証明書と、OS の証明書ストアの両方を信頼します。したがって社内CAのルート証明書が OS のトラストストアに入っていれば、追加設定なしで通ることが多いです。CrowdStrike Falcon や Zscaler のような TLS 検査プロキシも、この条件を満たしていれば設定不要と明記されています。

ただし OS ストアを読むには、ランタイムが tls.getCACertificates を持っている必要があります。ネイティブインストーラ版は常に条件を満たし、npm 導入版は Node 22.15 以降が必要です。それより古い Node では同梱の証明書と後述の NODE_EXTRA_CA_CERTS だけが効きます。社内CAを入れたのに通らないときは、まず導入方法と Node のバージョンを疑ってください。

信頼する証明書ストアを選ぶ

CLAUDE_CODE_CERT_STORE にカンマ区切りで指定します。認識される値は同梱の Mozilla CA セットを指す bundled と、OS のトラストストアを指す system の2つで、既定は bundled,system です。

# 同梱の Mozilla CA セットだけを信頼する
export CLAUDE_CODE_CERT_STORE=bundled

# OS の証明書ストアだけを信頼する
export CLAUDE_CODE_CERT_STORE=system

この変数には settings.json の専用スキーマキーがありません。設定ファイルから渡す場合は ~/.claude/settings.jsonenv ブロックに書くか、プロセスの環境変数として直接設定します。

証明書ファイルを直接指定する

OS ストアに入れられない、あるいは特定のCAだけを足したい場合は、PEM ファイルのパスを渡します。

export NODE_EXTRA_CA_CERTS=/path/to/ca-cert.pem

mTLS のクライアント証明書を渡す

クライアント証明書認証(mTLS)が必要な環境では、証明書と秘密鍵のパスを次の3つで渡します。

# 認証に使うクライアント証明書
export CLAUDE_CODE_CLIENT_CERT=/path/to/client-cert.pem

# クライアント秘密鍵
export CLAUDE_CODE_CLIENT_KEY=/path/to/client-key.pem

# 任意: 秘密鍵が暗号化されている場合のパスフレーズ
export CLAUDE_CODE_CLIENT_KEY_PASSPHRASE="your-passphrase"

Claude Code は起動時にこれらのファイルを読み、さらに設定を適用するたびに読み直します(組織が managed settings の env ブロックをセッション中に変更したとき、など)。

証明書のローテーション

入れ替えは同じパスにファイルを置き換えるだけで、動作中のセッションを再起動する必要はありません。API リクエストが接続レベルのエラー(接続リセットや TLS ハンドシェイクエラー)で失敗すると、Claude Code は両方のファイルを読み直し、新しいペアでリクエストを再試行します。なお v2.1.232 より前は接続エラーでの読み直しを行わず、次に設定を適用するか再起動するまで古いペアを保持していました。

重要なのは、ファイルを監視しているのではなく、失敗を契機に読み直しているという点です。挙動は次のようになります。

ローテーションを拾えたかどうかは、後述のデバッグログに Stale connection — reloaded rotated mTLS client material が出るかで確認できます。ただし設定適用の側で拾ったときはこの行が出ないため、行が無いことだけを根拠に失敗と判断しないでください。また、次回起動時に期限切れのペアを読み込まないよう、現行の証明書が切れる前に置き換えておきます。

設定が無視される2つの場面

実行環境によっては、これらの変数が意図的に無視されます。仕様を知らないと「設定したのに効かない」と見えるところです。

1つ目はクラウドセッションです。ホスティング環境が API への接続を管理するため、設定ファイルの env ブロック由来の CLAUDE_CODE_CLIENT_CERTCLAUDE_CODE_CLIENT_KEYCLAUDE_CODE_CLIENT_KEY_PASSPHRASENODE_EXTRA_CA_CERTSNODE_TLS_REJECT_UNAUTHORIZEDCLAUDE_CODE_OAUTH_SCOPES は無視されます。無視したキーはセッションのデバッグログに記録されます。

2つ目は Claude Desktop がプロバイダ接続を管理するセッション(サードパーティプロバイダ上の Code タブや Cowork セッションなど)です。ここでは上記の変数とプロキシ変数 HTTP_PROXYHTTPS_PROXYNO_PROXY を、managed settings と ~/.claude/settings.json からのみ読みます。リポジトリ側の設定ファイルからは読みません。チェックアウトしたリポジトリが、アプリ由来の資格情報を持つセッションの TLS 経路やプロキシ経路を書き換えられないようにするためです。claude.ai でサインインしたローカル / SSH / WSL の Code タブセッションではアプリが接続を管理しないため、通常のターミナルセッションと同じくすべてのスコープから読まれます。なお v2.1.217 より前は、アプリが接続を管理する場合にこれらの変数をすべての設定ファイルで無視していました。

設定が読み込まれたかを確認する

Claude Code はこれらの設定のほとんどを読み込み時に検証しません。プロキシのアドレス間違いや証明書パスの誤りは、あとのリクエストで接続エラーや証明書エラーとして表面化します。唯一の例外がプロキシ URL で、http:// のようなスキームを欠いてパースできない値だと、直すべき変数名を示して起動を中断します

リクエストを送る前に設定の読み込みを確かめたいときは、デバッグログを有効にして起動します。

claude --debug

デバッグ出力はターミナルではなく ~/.claude/debug/<session-id>.txt に書かれます(--debug-file <path> で変更可)。ログの中に、各ファイルが読み込まれたことを示す次のような行があるかを見ます。

CA certs: Appended extra certificates from NODE_EXTRA_CA_CERTS (/etc/ssl/certs/corp-ca.pem)
mTLS: Loaded client certificate from CLAUDE_CODE_CLIENT_CERT
mTLS: Loaded client key from CLAUDE_CODE_CLIENT_KEY

ファイルを読めなかった場合は、代わりに Failed to read または Failed to load の行が理由付きで出ます。

対話セッションでは /status を見る

対話セッション中なら /status でも確認できます。関係するのは次の3行です。

許可が必要な接続先を洗い出す

コンテナや制限付きネットワークで動かす場合は、プロキシとファイアウォールの許可リストに次のホストを入れます。主なものを用途とともに挙げます。

ホスト用途
api.anthropic.comClaude API へのリクエスト。WebFetch のドメイン安全性チェック、機能フラグの取得、テレメトリのイベント記録を含む
claude.aiclaude.ai アカウントの認証
claude.comサインイン時にブラウザで開くページ(claude.ai へリダイレクトする)。CLI からの事前承認済み WebFetch もこのホストに到達する
platform.claude.comAnthropic Console アカウントの認証。OAuth トークンの交換・更新・失効もここを通るため、claude.ai サインインでも必要
mcp-proxy.anthropic.comclaude.ai の MCP コネクタ。claude.ai 認証のユーザーでは既定で有効
downloads.claude.aiプラグインの実行ファイル取得、ネイティブインストーラと自動更新、更新バージョンの確認
storage.googleapis.com/plugin に表示されるインストール数とメタデータ
registry.npmjs.orgnpm 由来のプラグイン取得、npx 起動の MCP サーバー、npm / bun 導入版の Claude Code 自体のパッケージレジストリ
bridge.claudeusercontent.comClaude in Chrome 拡張の WebSocket ブリッジ
*.frame.claudeusercontent.comArtifact のコンテンツ読み込み
raw.githubusercontent.com/release-notes と更新後に表示されるリリースノートの取得
formulae.brew.shHomebrew 導入版の更新チェック(他の導入方法では使わない)
code.claude.comドキュメント参照。塞いでも影響はドキュメント参照だけにとどまる

このほか、運用テレメトリとエラーレポートを送る Datadog の2ホスト(http-intake.logs.us5.datadoghq.combrowser-intake-us5-datadoghq.com)があります。どちらも任意で、CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC を設定すれば両方止まります。これらは CLI が Anthropic API を直接使う場合にだけ送られ、サードパーティプロバイダ上のセッションからは送られません。

導入方法によって不要になるものもあります。npm 導入や自前配布のバイナリを使う場合、ネイティブインストーラと自動更新のための downloads.claude.ai は不要ですが、npm / bun 導入版はパッケージレジストリ registry.npmjs.org が必要です(社内ミラーがあればそちらで代替できます)。

別プロバイダやゲートウェイを使う場合の例外

Amazon Bedrock、Google Cloud の Agent Platform、Microsoft Foundry、サインイン済みの Claude apps gateway を使う場合、モデルの通信と認証は api.anthropic.com ではなくプロバイダ側へ向かいます。ただしWebFetch ツールはドメイン安全性チェックのために api.anthropic.com を呼び続けます(設定で skipWebFetchPreflight: true にした場合を除く)。

同じ性質の例外がもう1つあります。ANTHROPIC_BASE_URL で LLM ゲートウェイへ流している場合でも、fast mode の可用性チェックはゲートウェイではなく api.anthropic.com を呼びます。このチェックは設定済みの HTTP プロキシを尊重するので、ネットワーク遮断が原因のときはプロキシ側の許可リストに api.anthropic.com を足すのが直し方です。一方、ゲートウェイ発行の資格情報を Anthropic 側が拒否している場合も同じ接続エラーとして見えますが、こちらは何も塞がれていないので許可リストでは直りません。

Desktop とブラウザ版は追加のホストが要る

上の表は単体の CLI が対象です。Claude Desktop アプリとブラウザ版 claude.ai は、assets-proxy.anthropic.com をはじめとする Anthropic の CDN ホストや、artifact を配信する *.claudeusercontent.com のオリジンからアプリのコードとユーザーコンテンツを読み込みます。claude.ai だけ許可してこれらを塞ぐと、エラーではなく白紙のページになります。原因が分かりにくい形で出るので、許可リストを詰める前に把握しておく価値があります。

沈黙した接続を切るタイマー

ネットワーク機器がコネクションを黙って落とす環境では、応答待ちのまま固まらないための仕組みも関係します。Claude Code はストリーミング応答を監視する独立した3つのタイマーを持ち、既定値はイベント単位の監視が 300 秒、バイト単位の監視が直接 Anthropic API で 180 秒・それ以外で 300 秒、ボディのアイドルタイムアウトが 5 分です。CLAUDE_STREAM_IDLE_TIMEOUT_MS は両方の監視のタイムアウトを設定し(5分未満の値は5分に引き上げ、バイト単位の監視は最大30分で頭打ち)、CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS はバイト単位の監視だけを 10 秒から 30 分の範囲で設定して前者より優先されます。API_FORCE_IDLE_TIMEOUT0 にするとボディのアイドルタイムアウトが無効になりますが、2つの監視はこれとは独立に動くため、長い沈黙を許したいときはそちらも合わせて緩める必要があります。それぞれの正確な定義と対応バージョンは環境変数リファレンスにまとまっています。