メインコンテンツへスキップ
まずゲートウェイのネットワークを計画してください。 サインイン時、Claude Code は、ホスト名がパブリック IP アドレスに解決される Claude apps gateway を拒否します。インターネットから到達できないアドレスであっても同様です。Claude apps gateway は、シェルコマンドを実行するフックを含む設定をユーザーのマシンにプッシュできます。このチェックは、ユーザーがパブリックインターネット上の悪意のあるゲートウェイに誤ってサインインするのを防ぐのに役立ちます。自社のゲートウェイもインターネットから切り離しておいてください。ゲートウェイを実行する場所を選ぶ前に、ゲートウェイのアドレスを選んでください。通常は、ユーザーが内部ネットワーク上または VPN 経由でアクセスするプライベートアドレスです。内部ネットワークがパブリック IPv4 範囲を使用している場合は、ゲートウェイとユーザーのマシンの両方を含む範囲を 1 つ指定できます。Claude Code は、その一致をゲートウェイが内部ネットワーク上にあることを示すものとみなします。ゲートウェイのアドレスを選択する を参照してください。どちらもネットワークに合わない場合は、Anthropic のアカウントチームにお問い合わせください。
このページでは、Claude apps gateway の運用側について説明します。ID プロバイダー(IdP)で OAuth クライアントを登録し、ゲートウェイをコンテナとしてデプロイし、日々運用します。ゲートウェイが起動時に読み込む gateway.yaml ファイルのすべてのオプションについては、設定リファレンス を参照してください。 本番環境のデプロイメントは順序立てた 4 つのステップに従い、以下のセクションがそれに対応しています。最初の 2 つは選択を行う場所です。後の 2 つは、実行中に参照するリファレンス資料です。
  1. ID プロバイダーをセットアップする:OAuth クライアントを登録し、Okta、Entra、Google の IdP 固有の注記を確認します
  2. ゲートウェイをデプロイする:ピン留めされたコンテナイメージをビルドし、Kubernetes、Cloud Run、または独自のプラットフォームで実行します。このセクションではコスト、バイパス、複数ゲートウェイ、サーバーレスの決定についても説明します
  3. 運用をセットアップする:ログ、ヘルスプローブ、障害時の動作、シークレットローテーション、アップグレード。監視とランブックを配線するときに参照するリファレンス
  4. セキュリティ体制を確認する:データがどこを流れるか、脅威モデル、コンプライアンスの回答。セキュリティレビュー用のリファレンス
サインインまたはブート中に失敗が発生した場合は、トラブルシューティング に直接進んでください。これは表示されるエラーに基づいてキー付けされています。

ID プロバイダーのセットアップ

単一のリダイレクト URI https://<gateway>/oauth/callback を持つ機密 OAuth/OpenID Connect(OIDC)ウェブアプリケーションを ID プロバイダーに登録し、ゲートウェイアクセスを持つべきユーザーまたはグループに割り当てます。ゲートウェイは、登録のクライアントシークレットを使用して IdP に対して認証します。IdP が代わりに証明書認証情報を使用する場合は、登録にアップロードした証明書を使用して認証します。 任意の OIDC 準拠 IdP が機能します:Okta、Microsoft Entra ID、Google Workspace、Keycloak、Dex、PingFederate など。IdP は 3 つの要件を満たす必要があります:
  • /.well-known/openid-configuration を提供します。本番環境では HTTPS 経由です。ゲートウェイは http:// issuer を受け入れ、ループバック issuer は追加で CLAUDE_GATEWAY_ALLOW_LOOPBACK=1 が必要です
  • 認可コードフローをサポートします。PKCE(Proof Key for Code Exchange)はデフォルトで有効です。サポートしない IdP の場合は oidc.use_pkce: false で無効にします
  • id_token で email と必要に応じて groups を返すか、oidc.userinfo_fallback: true で userinfo エンドポイントから提供します
プライベート PKI の場合は、oidc.ca_cert_pem を設定します。 いくつかのプロバイダーはメールとグループクレームを異なる方法で処理します:
  • Okta:https://example.okta.com の org 認可サーバーは、email と groups を省略した薄い id_token を返すため、issuer として使用する場合は常に oidc.userinfo_fallback: true を設定します。https://example.okta.com/oauth2/default などのカスタム認可サーバーは、id_token に email と必要に応じて groups を含め、直接発行し、フォールバックは不要です。Okta は oidc.scopes で groups スコープがリクエストされ、アプリのグループクレームフィルターが許可する場合にのみ groups を発行します。userinfo_fallback は IdP がリクエストされなかったクレームを埋めることはできません。
  • Microsoft Entra ID:issuer = https://login.microsoftonline.com/<tenant-id>/v2.0。Entra はグループ名ではなくグループオブジェクト ID を発行するため、managed.policies.match.groups で GUID を使用するか、人間が読める名前のためにアプリロールを使用します。テナントが groups の代わりに roles の下でロールを発行する場合は、oidc.groups_claim: roles を設定します。
  • Google Workspace:issuer = https://accounts.google.com。Google の id_token はグループを含みません。Google を IdP として、グループベースの allowed_groups または managed.policies を使用するには、oidc.google_groups を設定します。これは、ドメイン全体の委任を持つサービスアカウントを使用して Admin SDK Directory API を通じて各ユーザーのグループを検索します。これなしで、メンバーシップゲーティングに oidc.allowed_email_domains を使用し、ポリシー割り当てに managed.policies.match.email_domain を使用します。Google は標準の offline_access スコープも無視します。リフレッシュトークンの場合は、oidc.scopes: [openid, profile, email] と oidc.extra_auth_params: { access_type: offline, prompt: consent } を設定します。
リフレッシュトークンにより、ゲートウェイは開発者のセッションをサイレントに更新でき、開発者をブラウザに戻す必要がありません。また、IdP がユーザーを無効にすると、次のリフレッシュが失敗し、セッションは ttl_hours 内に終了するため、プロビジョニング解除を駆動します。ゲートウェイはデフォルトでリフレッシュトークンを取得するために offline_access をリクエストします。IdP がオフラインアクセスに明示的な同意を必要とする場合は、OAuth クライアントを設定してそれを許可します。IdP がリフレッシュトークンをまったく発行できない場合、ゲートウェイは引き続き機能しますが、サイレント更新がないため、開発者はセッションの有効期限が切れるとブラウザログインを再実行します。これが 1 時間ごとに発生するのを防ぐには、session.ttl_hours を 8 または 12 に上げます。トレードオフはプロビジョニング解除の遅延です。リフレッシュトークンなしでは、無効にされたユーザーはより長い TTL が経過するまでアクセスを保持します。

デプロイ

ゲートウェイは単一のステートレス Linux バイナリで、Postgres を通じて調整されるため、環境内で他のステートレスサービスをデプロイするのと同じ方法でデプロイします。ゲートウェイはネットワーク内に置き、開発者が HTTPS 経由で到達でき、ゲートウェイから IdP に到達できるようにします。また、本番認証情報を保持する他のサービスと同様に扱います。 デプロイメントを実行する場所を超えて形作るいくつかの決定があります:
  • コスト:ゲートウェイの個別ライセンスまたはシートごとの料金はありません。ゲートウェイは claude バイナリの一部であるため、既存のコミットメントを通じて推論に対して支払い、実行するコンピュートに対して支払います。
  • バイパス:ゲートウェイは、モデルへの唯一のルートがそれを通過することを強制しません。独自の認証情報を持つ開発者は引き続きプロバイダーを直接呼び出すことができるため、そのパスを閉じることはネットワークポリシーの決定です。例えば、api.anthropic.com へのエグレスをゲートウェイ以外からブロックします。そのエグレスをブロックすると、各開発者のマシンから api.anthropic.com を呼び出す WebFetch ドメインセーフティチェック も破壊されます。管理ポリシーで skipWebFetchPreflight: true を設定して無効にします。
  • 複数ゲートウェイ:各ゲートウェイは独自の設定を持つ個別のデプロイメントで、CLI はゲートウェイホスト名ごとに信頼と認証情報を保存するため、チームは競合なしに異なるゲートウェイを使用できます。複数の OIDC issuer を提供するには、個別のインスタンスを実行します。
  • サーバーレス:Cloud Run は機能します。min-instances: 1 を設定して、コールド OIDC ディスカバリーを回避します。Lambda と Cloud Functions は機能しません。ゲートウェイは長時間実行 HTTP サーバーであるためです。
ここのすべての本番トポロジーは、L7 プロキシ(Ingress、Cloud Run のフロントエンド、ALB など)をプレーン HTTP レプリカの前に配置します。listen.trusted_proxies をプロキシのソース範囲に設定して、ゲートウェイが X-Forwarded-For からクライアント IP を読み込みます。ゲートウェイは TCP ピアが信頼されている場合にのみヘッダーを尊重します。Google Cloud と AWS の実装例には、トポロジーごとに具体的な値があります。信頼されたプロキシなしでは、すべてのリクエストはプロキシの IP から来ているように見え、IP ごとのレート制限を 1 つの共有バケットに折りたたみ、監査イベントにプロキシの IP を記録します。 ゲートウェイのデバイス認可とトークンエンドポイントへのリクエストをリダイレクトしないでください。例えば、HTTP から HTTPS へのリダイレクトやホスト正規化の書き換えなどです。Claude Code はこれらのリクエストでリダイレクトに従わないため、ingress ルールがそれらをリダイレクトするとサインインとトークン更新が破壊されます。 プロキシに、ゲートウェイのキープアライブ間隔より長いアイドルタイムアウトを与えます。これは上流に依存します:
  • provider: anthropic 以外のすべての上流では、ゲートウェイはストリームが約 15 秒間サイレント状態になった後、SSE ping を 1 回書き込みます。
  • provider: anthropic では、ゲートウェイは Anthropic API 独自の ping を含む応答をそのまま渡します。
ALB の 60 秒などのデフォルトは、静かなストリームを開いたままにするのに十分です。AWS の実装例 はとにかくそれを 1 時間に引き上げ、トラブルシューティング行は v2.1.229 より古いゲートウェイをカバーしており、現在 ping を取得する上流でサイレント期間中に何も送信しませんでした。

ゲートウェイのアドレスを選択する

Claude Code は、次の 2 つの方法のいずれかでゲートウェイのアドレスを受け付けます:
  • プライベートアドレス:ゲートウェイを内部ロードバランサーまたは VPN の背後に配置し、RFC 1918 や CGNAT 100.64.0.0/10 などのプライベートアドレスにのみ解決されるホスト名を使用します。ユーザーのマシンはどのアドレスでもかまいません。プライベートネットワークの前提条件 に、受け付けられる範囲が記載されています。
  • 宣言済みブロック:内部ネットワークが組織所有のパブリック IPv4 空間を使用している場合は、そのブロックを gatewayInternalNetworks 管理設定に記載します。ゲートウェイとユーザーのマシンの両方がそのブロック内にある必要があります。所有するパブリックアドレス空間上のゲートウェイを許可する を参照してください。
両方を含む単一のブロックがない場合は、代わりにゲートウェイにプライベートアドレスを割り当ててください。

コンテナイメージ

標準 Claude Code リリースのネイティブ claude バイナリの周りに独自のイメージをビルドします:
  1. ピン留めされたリリースからイメージアーキテクチャの Linux ビルドをダウンロードします。ダウンロード URL については、特定のバージョンをインストールする を参照してください。
  2. バイナリの整合性とコード署名 で説明されているように、リリースの GPG 署名付き manifest.json に対して検証します。
  3. ビルドコンテキストにコピーします。
ビルドがリリースホストに到達できない場合は、リリースを内部レジストリにミラーリングし、フロートが実行するバージョンをピン留めします。 バイナリを超えて、イメージは以下が必要です:
  • glibc ベースのイメージ:glibc ビルドの唯一の動的依存関係は glibc ライブラリです。Musl ベースのイメージには linux-x64-musl または linux-arm64-musl ビルドが必要で、その唯一の動的依存関係は musl です。
  • 書き込み可能な状態ディレクトリ:ゲートウェイは任意のユーザーとして実行されますが、最小限のイメージには書き込み可能なホームがありません。CLAUDE_CONFIG_DIR を /tmp/.claude などの書き込み可能なパスに設定します。
  • コンテナコマンド:claude gateway --config /etc/claude/gateway.yaml。設定ファイルは読み取り専用でマウントされ、シークレットは環境変数として提供されます。ゲートウェイは listen.port でリッスンします。デフォルトは 8080 です。

Kubernetes

ゲートウェイをデプロイメントとして実行します。他のステートレスサービスと同様です:
  • ConfigMap から設定をマウントし、Secret からシークレットをマウントします。YAML で ${file:/path/to/secret} または環境変数を通じてシークレットを参照します
  • Ingress で TLS を終了し、listen.public_url を Ingress ホスト名に設定します
  • readiness プローブを GET /readyz に、liveness プローブを GET /healthz に指定します
AWS での完全な実装例(ECS Fargate または EKS、Amazon RDS、AWS Secrets Manager をカバー)については、AWS にデプロイする を参照してください。 静的キーよりもプラットフォームのワークロードアイデンティティを優先します。upstreams リファレンス にはプラットフォームごとのセットアップ詳細があります。クロスクラウドペアリング(例えば GKE 上の Amazon Bedrock 上流)の場合は、上流の auth ブロックで明示的な認証情報を設定します。

Cloud Run

サービスを以下のように設定します:
  • listen.port をデフォルトの 8080 のままにします。これは Cloud Run のデフォルト PORT と一致するか、port: ${PORT} を設定します
  • public_url を外部到達可能なオリジンに設定します。本番環境では、これは通常、内部ロードバランサーのホスト名です。/login は パブリックアドレスを拒否 し、*.run.app URL はそれに解決するため、Cloud Run URL だけは curl またはブラウザスモークテストにのみ機能します。例外は、*.run.app が Private Service Connect と Cloud DNS プライベートゾーンを通じてプライベートに解決するネットワークです。そのトポロジーでは、Cloud Run URL は有効な public_url です。Google Cloud の実装例 は両方をカバーしています。
  • シークレットボリュームとして設定をマウントします
  • min-instances: 1 を設定して、最初のリクエストでコールド OIDC ディスカバリーを回避します
Google Cloud での完全な実装例(Cloud Run または GKE、Cloud SQL、Secret Manager をカバー)については、Google Cloud にデプロイする を参照してください。

ゲートウェイ URL を開発者マシンにプッシュする

ゲートウェイが稼働したら、MDM を通じて、または OS ごとの managed-settings.json を直接書き込むことで、管理設定を通じて各開発者のマシンに forceLoginMethod、forceLoginGatewayUrl、および parentSettingsBehavior: "merge" をプッシュします。 キーをデプロイしたら、Claude Code はマシン上の残存する API キーまたは claude.ai ログインの使用を停止するため、サインイン指示と一緒にプッシュを計画します。Administrator policy requires a Cloud gateway sign-in は開発者が見るメッセージについて説明しています。 各メカニズムがポリシーを保存する場所については where each mechanism stores the policy を参照し、Claude Desktop bootstrapUrl 相当については Client-side managed settings を参照してください。

大規模なロールアウト

サインインはクライアント IP アドレスごとにレート制限されており、デフォルトは小規模なチームに適しています。各アドレスは 10 分ごとに 30 回のサインイン開始と 10 回のコード送信を取得します。数千人の開発者へのロールアウトは、次の 2 つの理由のいずれかで、最初の朝にこれらの制限に達する可能性があります:
  • ゲートウェイがロードバランサーの向こう側を見ることができません。 listen.trusted_proxies がない場合、すべての開発者はロードバランサーのアドレスから来ているように見え、1 つの制限を共有します。ゲートウェイは、X-Forwarded-For ヘッダーを初めて無視したときに警告をログに記録します。ロードバランサーが listen.trusted_proxies に含めるべきもの である場合は、他の何かを変更する前にそれを記載してください。それでも開発者が 1 つのアドレスを共有している場合は、rate_limits を引き上げます。
  • 多くの開発者が少数の NAT または VPN エグレスアドレスを共有しています。 trusted_proxies が正しい場合でも、それらのアドレスの制限を共有します。rate_limits を引き上げて適合させます。
max のサイズを決定するには、開発者をそれらが共有するエグレスアドレスで割ります。1 つの window_seconds 期間内にそれらのうち何人がサインインするかを推定します。デフォルトは 10 分です。その後、リトライと Claude Code と Claude Desktop の両方にサインインする開発者をカバーするために 2 倍にします。 例えば、10,000 人の開発者が 4 つのエグレスアドレスの背後にあり、1 時間にわたって均等にサインインします。これは、アドレスごとに 2,500 人の開発者で、各 10 分ごとに約 420 人です。これを 2 倍にして 1,000 に切り上げます。以下の例は両方の制限を 1,000 に設定します:
device_verify は、別の開発者のサインインコードを推測するのを防ぐものであるため、推定が必要な限りだけそれを引き上げます。これらの制限でも、コードは 20 文字のアルファベットから 8 文字で、10 分後に期限切れになるため、推測は実用的なままです。User-code brute-force resistance を参照してください。 IdP がリフレッシュトークンを発行する場合、Claude Code はセッションをサイレントに更新するため、ロールアウト後に制限を戻すことができます。リフレッシュトークンがない場合、開発者は session.ttl_hours ごとに再度サインインします。その定常状態レートの両方の制限のサイズを決定し、それらを引き上げたままにします。 制限に達すると、Claude Code v2.1.274 以降は The gateway is limiting sign-in attempts right now を表示します。v2.1.274 以降のゲートウェイは、検証ページに Too many attempts came from your network address を表示し、確認する設定を表示します。また、変更する設定に名前を付ける sign-in refused ログ行も書き込みます。

運用

ゲートウェイがトラフィックを処理するようになると、日々の運用はログの確認、ヘルスチェック、そして自社のスケジュールに沿ったシークレットのローテーションになります。以下の各サブセクションでは、それぞれの作業に加え、Postgres に保存される内容と、アップグレードおよびロールバック時の挙動について説明します。

ログ

ゲートウェイは 2 種類のストリームを stderr に書き出します。どちらも JSON で扱いやすい形式です。
  • 監査イベント: セキュリティに関わるイベントごとに 1 行の JSON を出力します。stderr をログアグリゲーターにパイプしてください。 出力されるイベントは config.load、session.mint、session.refresh、device.authorize、device.verify、device.callback、auth.denied、access.denied、access.public_client、inference、managed.serve、desktop_bootstrap.serve、desktop_bootstrap.denied、spend.blocked、admin.denied、admin.limit.upsert、admin.limit.delete です。フィールドはイベントによって異なります。
    • 成功した mint および refresh イベントには sub、email、client_ip、および結果が含まれます
    • auth.denied と access.denied には理由とクライアント IP が含まれ、auth.denied にはさらにリクエストパスが含まれます。これらの拒否の時点ではユーザー ID が存在しないためです。access.denied の理由のうち 2 つは、イベントに含まれる内容を変えます。
      • xff_unparseable: 読み取れなかった X-Forwarded-For のエントリもイベントに含まれます
      • client_ip_unknown: access_control リストが設定されている状態で接続にピアアドレスがなかったため、イベントにクライアント IP は含まれません
    • access.public_client には、access_control.allow_cidrs が空の状態でパブリックアドレスから届いた、プロセスごとの最初のリクエストのクライアント IP が含まれます。ゲートウェイはそのリクエストを通常どおり処理します。このイベントは、ゲートウェイがパブリックインターネットから到達可能である可能性を示します。何がパブリックとみなされるか、および推奨される許可リストについては、access_control リファレンスを参照してください。
    • inference には、どのアップストリームがリクエストを処理したかと、レスポンスのステータスが記録されます
    • desktop_bootstrap.denied には、拒否された Claude Desktop のブートストラップ取得が、理由(not_configured、policy_not_opted_in、または no_policy_matched)およびユーザーの ID とともに記録されます
    • guardrail.trace には、どのフィルターが発動したかが記録されます。一致したテキストは記録されません
    • admin.denied には、拒否された管理 API の認証試行が、クライアント IP、メソッド、パス、理由とともに記録されます。提示された鍵情報は記録されません。理由は、x-api-key が提示されたもののどの設定済みキーとも一致しなかった場合は invalid_key、Authorization ヘッダーのみが提示され、それが admin.admin_groups のゲートウェイセッションとして検証されなかった場合は bearer_rejected、どちらのヘッダーも提示されなかった場合は no_credentials です
  • 運用ログ: 起動、警告、アップストリームのエラーについて、[gateway] というプレフィックスの付いた人間が読める形式の行を出力します。詳細度は CLAUDE_GATEWAY_LOG_LEVEL 環境変数で制御し、debug、info、warn、error のいずれかを指定できます。デフォルトは info です。debug では、サインインとリフレッシュのたびに id_token に含まれるクレームの名前(値ではありません)もログに記録され、userinfo_fallback が何らかのクレームを提供した場合は userinfo クレームの名前も記録されます。これにより、PII をログに残さずに email_claim と groups_claim の設定を診断できます。この設定は監査イベントには影響せず、監査イベントは常に出力されます。

運用ログを JSON として書き出す

ログコレクターが各行のレベルを JSON フィールドから読み取る場合は、ゲートウェイの環境で CLAUDE_GATEWAY_LOG_FORMAT=json を設定します。ゲートウェイサーバーで Claude Code v2.1.319 以降が必要です。 これにより、各運用ログ行は severity、time、message を持つ 1 つのオブジェクトになります。
severity は大文字で表したログレベルで、warn は WARNING と書かれます。起動の失敗は ERROR の行になります。 同じく stderr に出力される監査イベントは変わりません。監査イベントには ts と evt が含まれ、severity は含まれません。

ヘルスチェック

ゲートウェイは、liveness プローブとして GET /healthz を、readiness プローブとして GET /readyz を提供します。/readyz はストアに到達可能かどうかを検証します。store.readiness_grace_seconds を設定した場合、ストアが応答しなくなってからその秒数が経過するまで、/readyz は ready を報告し続けます。 どちらのエンドポイントも access_control.allow_cidrs の対象外であるため、アクセスを制限したリスナーでもプローブは動作し続けます。 /.well-known/oauth-authorization-server の OAuth ディスカバリードキュメントも、設定の読み込み、OIDC ディスカバリー、アップストリームクライアントの構築、Postgres のマイグレーションがすべて成功した後にのみ 200 を返すため、エンドツーエンドの起動チェックとしても使えます。

アップストリームへの同時リクエスト

デフォルトでは、各ゲートウェイレプリカがアップストリームに同時に送信するリクエストは最大 256 件です。ストリーミングレスポンスは、ストリームが終了するまでこの上限にカウントされます。 レプリカが上限に達している間に届いたリクエストは、ゲートウェイ内で空きスロットを待ちます。開発者からは、レスポンスの開始が遅い、またはハングしているように見えます。provider: anthropic のアップストリームでは、timeouts.upstream_ttfb_ms より長く待ったリクエストはそのアップストリームをあきらめ、後続のアップストリームがそれを処理しない場合は 502 で失敗します。 upstream requests: を含む起動時のログ行に、有効な上限が表示されます。レプリカで開いているリクエストが上限を超えている間は、client requests are open を含む警告も最大で 1 分に 1 回ログに記録されます。 より多くのリクエストを同時に処理するには、2 つの方法があります。
  • レプリカを追加する。
  • 各レプリカの上限を引き上げる。ゲートウェイコンテナで BUN_CONFIG_MAX_HTTP_REQUESTS 環境変数を 1 から 65535 までの整数に設定し、コンテナを再起動します。
レプリカが上限に達するリクエストレートは、おおよそ上限をリクエストが開いている平均秒数で割った値です。たとえば、リクエストが平均 10 秒間開いている場合、デフォルトの上限 256 のレプリカは毎秒約 26 件のリクエストで上限に達します。 CPU に基づいてオートスケールしている場合、上限に達したレプリカはスケールアウトをトリガーせずにリクエストをキューに入れるため、レプリカが client requests are open の警告をログに記録するときの CPU レベルよりも低い値をターゲットに設定してください。
開いているリクエストはすべて、ストリーミング中および空きスロットの待機中に、ゲートウェイプロセスのメモリを保持します。上限を 256 のままにしていても、待機中のリクエストはリクエストボディを保持するため、過負荷のレプリカのメモリは増え続けます。ピーク時に開いているリクエスト数に合わせてコンテナのメモリを見積もり、上限を変更する際はメモリを監視してください。メモリ不足になったレプリカは強制終了され、保持しているすべてのストリームが切断されます。
load_test_mode を使用した負荷テストでは、リクエストはこの上限で待機しませんが、レプリカは引き続き client requests are open の警告をログに記録します。

API_TIMEOUT_MS をゲートウェイの最初のバイトまでの時間より大きく保つ

応答のないリクエストをより早く再試行するために API_TIMEOUT_MS を下げる場合は、ゲートウェイがストリーミングレスポンスの最初のバイトを送信するまでにかかる時間より大きい値を保ってください。それより長く待つリクエストはタイムアウトし、同じだけ待つ再試行もそれぞれタイムアウトして、最初のバイトの期限によって終了しない限り、最終的にターンが Request timed out で終了します。
  • provider: anthropic: アップストリームが最初のイベントを送信するまでにかかる最長時間より大きい値を API_TIMEOUT_MS に設定します。
  • その他すべてのアップストリーム: アップストリームがレスポンスヘッダーを返すまでにかかる最長時間より 20 秒以上大きい値を設定します。ゲートウェイは、アップストリームの最初のイベントがそれより早く届かない限り、それらのヘッダーの約 15 秒後に最初の keepalive ping を送信します。v2.1.229 より古いゲートウェイは ping を送信しないため、その場合は provider: anthropic のルールを使用してください。
その時間に加えて、空きスロットの待機と、フェイルオーバー前のダウンしたアップストリームでの待機を考慮してください。また、最も長い非ストリーミングリクエストよりも大きい値を保ってください。

最初のバイトの期限で応答のないリクエストをより早く再試行する

Claude Code が応答のないストリーミングリクエストをより早く再試行するようにするには、開発者のマシンで CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS を設定して、最初のバイトの期限を与えます。この期限は、最初の試行がレスポンスヘッダーを待つ時間を制限します。期限がない場合、その試行は 5〜6 分待つことがあります。開発者のマシンで Claude Code v2.1.307 以降が必要です。 この変数には、ミリ秒単位の正の整数を、ゲートウェイポリシーの env ブロックまたは開発者のシェルで設定します。値はゲートウェイの最長の最初のバイトまでの時間より大きく保ってください。そうしないと、ヘッダーの返却に時間がかかる正常なリクエストを Claude Code が中止して再送信する可能性があります。次の例では、開発者のシェルで 60 秒を設定します。
応答のない再送信は、ボディのアイドルタイムアウトによって終了し、Claude Code が再試行の予算内で再試行するまで、5〜6 分待つことがあります。より早く再試行するためだけに API_TIMEOUT_MS を下げていた場合は、その値を削除してください。そうしないと、応答のない再送信 1 回でターンが No response from API で終了する可能性があります。 期限が発動したことを確認するには、開発者にデバッグログを有効にして Claude Code を起動してもらい、ログで [first-byte] no response headers を検索します。

障害時の挙動

Postgres がダウンした場合、ゲートウェイ自体はサインイン済みの開発者へのサービスを継続し、新規のサインインは失敗します。開発者が実際に作業を続けられるかどうかは、オーケストレーターが readiness をどう扱うかによって決まります。
  • 既存のセッション: ベアラートークンは JWT シークレットでローカルに検証され、セッションのリフレッシュはストアにアクセスせず、ゲートウェイプロセスは引き続き推論を処理できます
  • 新規のサインイン: デバイスフローとそのレート制限カウンターは Postgres に保存されているため、Postgres が復旧するまで失敗します
  • 利用額上限の適用: デフォルトでは障害中はフェイルオープンになるため、推論は引き続き流れます。計測なしで稼働するよりもブロックしたい場合は、フェイルクローズに切り替えてください
  • Readiness: デフォルトでは、Postgres に到達できなくなるとすぐに /readyz が not-ready を報告するため、すべてのレプリカが同時に readiness チェックに失敗します。チェックに合格したレプリカにのみトラフィックが届く環境では、ゲートウェイがまだ処理できる推論を含むすべてのトラフィックが、Postgres が復旧するまで失敗します。/healthz の liveness プローブはその間も合格し続けます。
IdP がダウンした場合、既存のセッションは ttl_hours まで機能し、新規のログインは失敗します。セッションのリフレッシュには再試行を求める応答が返され、IdP が復旧すると成功します。IdP のメンテナンス時間が頻繁にある場合は、ttl_hours を長めに設定してください。

Readiness の猶予期間

データベースのフェイルオーバーのような短時間の Postgres 障害の間もサインイン済みの開発者が作業を続けられるようにするには、store.readiness_grace_seconds をフェイルオーバーにかかる時間より長い値(たとえば 300)に設定します。利用額上限が有効でデフォルトのフェイルオープン動作の場合、ready のままのレプリカを経由するリクエストは Postgres が復旧するまで計測されないため、値はフェイルオーバーをカバーできる範囲でできるだけ小さくしてください。enforcement.fail_closed_on_error: true を設定した場合、レプリカが readiness チェックに合格している間でも、Postgres が復旧するまでゲートウェイはサインイン済みの開発者の推論を 429 の spend limit unavailable メッセージで拒否します。 この設定には、ゲートウェイサーバーで Claude Code v2.1.282 以降が必要です。それより前のゲートウェイはこのキーを検出すると起動を拒否するため、キーを追加する前にすべてのレプリカをアップグレードしてください。ロールバックについてはアップグレードで説明しています。 代わりに readiness プローブを /healthz に向けた場合も、障害中にレプリカはプローブに合格し続けますが、/healthz は not-ready を報告することがないため、Postgres 接続が復旧しないレプリカも合格し続けます。

JWT シークレットのローテーション

既存のセッションが有効なままになるよう、署名シークレットは段階的にローテーションします。
  1. 新しいシークレットを生成します。それを session.jwt_secret 配列の先頭に追加します。
  2. デプロイをロールします。新しいトークンは新しいシークレットで署名され、古いトークンも引き続き検証されます。
  3. ttl_hours に余裕を加えた時間が経過したら、古いシークレットを削除して再度ロールします。
ローテーションは、有効期限前にセッションを強制的に終了させる唯一の方法でもあります。ベアラートークンは JWT シークレットに対してローカルに検証されるため、セッション単位での失効はありません。古いシークレットを配列に残さずにシークレットを完全に置き換えると、未失効のすべてのセッションが一度に無効になります。個々のユーザーのオフボーディングについては、IdP でそのユーザーのプロビジョニングを解除してください。そのユーザーのセッションは ttl_hours 以内に終了します。

Postgres

ゲートウェイは状態を PostgreSQL データベースに保存します。
  • データベース: PostgreSQL 本体(セルフホストまたはマネージド)で、最小バージョン以降のもの。分散 SQL データベースなど、Postgres プロトコルを実装しているだけのデータベースはサポートされていません。
  • アドレス: store.postgres_url には 1 つのホストを指定します。データベースに複数のノードがある場合は、マネージドサービスのエンドポイント、ロードバランサー、仮想 IP など、それらの前段にあるアドレスを使用してください。フェイルオーバーにかかる時間より長い readiness の猶予期間を設定してください。
ゲートウェイは 5 つのデータテーブルと _migrations テーブルを保持し、いずれも起動時のマイグレーションによって作成されます。 30 秒ごとのループが TTL を過ぎた kv の行を期限切れにし、1 時間ごとのスイープが利用額テーブルの保持期間を適用するため、無制限に増え続けるものはありません。利用額上限が設定されていない場合、書き込まれるのは kv のみです。ゲートウェイは起動時およびアップグレードのたびに独自のスキーママイグレーションを適用するため、そのデータベースロールにはテーブルを作成および変更する権限が必要です。その権限付与の範囲を狭く保つため、ゲートウェイ専用のデータベースまたはスキーマを指定してください。 利用額上限を使用している場合、データベースを失うと開発者の再ログインだけでなく、利用額の追跡と上限も失われるため、定期的にバックアップを取ってください。保持期間を待たずに退職した開発者 1 人のデータを即座に消去するには、DELETE FROM principal_emails WHERE principal = '<sub>' を直接実行します。これにより、その開発者のメールアドレス、名前、グループを保持する唯一のテーブルから削除されます。spend と admin_audit の行は、仮名化された OIDC の sub のみを参照します。

接続プールのサイズを決める

各レプリカは最大 store.max_connections 個の Postgres 接続を開きます。デフォルトは 5 です。レプリカ数 × store.max_connections が、データベースがゲートウェイ用に残している接続数以下になるようにしてください。
  • レプリカ数: 同時に稼働する最大数を数えます。オートスケーリングの最大値(オートスケールしていない場合はレプリカ数)から始め、ローリングアップデートで古いレプリカを停止する前に起動される追加のレプリカを加えます。デフォルト設定の Amazon ECS や Cloud Run では、それが同数に及ぶことがあります。
  • 残りの接続数: データベースの max_connections から、データベースが予約している分と他のクライアントが保持している分を差し引きます。PostgreSQL は superuser_reserved_connections を予約しており、デフォルトは 3 です。マネージドサービスではさらに多く予約されている場合があるため、そのドキュメントを確認してください。
たとえば、オートスケーリングの最大値が 6、ローリングアップデートで起動される追加のレプリカが最大 2、デフォルトのプールが 5 の場合を考えます。必要な接続数は (6 + 2) × 5 = 40 です。max_connections が 50 で、他のクライアントが 2 つの接続を保持しているデータベースでは、残りは 50 − 3 − 2 = 45 となるため、合計は収まります。 合計が収まらない場合は、次のいずれかを変更します。
  • データベース: max_connections を引き上げる
  • レプリカ: 稼働数を減らすか、ローリングアップデートで起動する追加のレプリカを減らすようオーケストレーターを設定する
  • プール: store.max_connections を下げる。ただし、利用額上限が有効な場合は、各レプリカの負荷に十分な大きさを保ってください。そうしないと、利用額チェックが接続を待つ間にタイムアウトする可能性があり、ゲートウェイは spend check failed: spend precheck timed out をログに記録します。

アップグレード

レプリカはステートレスであるため、ローリング再起動でゲートウェイの状態が失われることはありません。ゲートウェイは起動時にスキーママイグレーションを実行するため、新しいバイナリをデプロイするとデータベースが自動的にマイグレーションされます。同時に稼働するレプリカは Postgres のアドバイザリーロックで直列化されるため、各マイグレーションを適用するのは 1 つのレプリカのみです。 ローリング再起動やスケールインのように、オーケストレーターが SIGTERM でレプリカを停止すると、ゲートウェイは新しい接続の受け付けを停止し、処理中のリクエストとストリームが完了するのを待ってから終了します。最大 25 秒(ドレインウィンドウと呼びます)待機し、その後もまだ開いているものを閉じます。ターミナルでの Ctrl+C のような SIGINT でも同じドレインが開始され、ドレイン中に 2 回目のシグナルを受け取ると、開いているリクエストを閉じて直ちに終了します。ドレインにはゲートウェイ v2.1.274 以降が必要です。 長い生成は数分間ストリーミングされることがあります。Kubernetes と Amazon ECS では、それらのストリームにより多くの時間を与えるために、次の 2 つを一緒に引き上げてください。
  • ドレインウィンドウ: ゲートウェイコンテナで CLAUDE_GATEWAY_DRAIN_TIMEOUT_MS 環境変数を、120000 のようなミリ秒単位の正の整数に設定します。120s のような他の形式の値はゲートウェイに無視され、デフォルトの 25 秒が維持されます
  • オーケストレーターの猶予期間: Kubernetes では terminationGracePeriodSeconds、Amazon ECS では stopTimeout
猶予期間はどちらのプラットフォームでもデフォルトで 30 秒です。ドレインウィンドウより少なくとも 5 秒長く保ってください。そうしないと、ドレインが完了する前にオーケストレーターがゲートウェイを強制終了します。Kubernetes では、preStop フックの所要時間も加えてください。猶予期間のカウントは、ゲートウェイが SIGTERM を受け取った時点ではなく、フックが実行される前から始まるためです。 プラットフォームによっては、ドレインを実行できる時間に上限がある場合もあります。
  • Fargate 上の Amazon ECS: stopTimeout は最大 120 秒までです
  • Cloud Run: SIGTERM の 10 秒後にインスタンスを停止するため、ドレインウィンドウの値にかかわらず、開いているストリームに与えられる時間は最大 10 秒です
リクエストが開いたままドレインウィンドウが終了すると、ゲートウェイは drain window over after を含む警告をログに記録し、切断したリクエストの数を数え、引き上げるべき 2 つの設定の名前を示します。 マイグレーションは追記のみであるため、認識しているマイグレーションが少ない以前のバイナリへのロールバックは安全です。以前のバイナリは余分な行を無視します。また、ロールバック時には YAML が古いバイナリのスキーマに対して再検証されるため、新しいリリースで導入されたキーを採用した設定は、古いバイナリでの起動に失敗します。ロールバックする前に新しいキーを削除してください。
アップストリームから groups キーだけを削除すると、そのアップストリームはすべての開発者に開放された状態になります。ロールバックする前に削除するものを参照してください。
ゲートウェイのバージョンは自社のイメージで固定するため、新しい Claude Code リリースの修正(セキュリティ修正を含む)がデプロイ環境に反映されるのは、固定バージョンを更新して再デプロイしたときだけです。本番環境の認証情報を保持する他のサービスと同じパッチ適用サイクルにゲートウェイを含めてください。

セキュリティ

このセクションは、セキュリティレビューが尋ねる質問に答えます:ゲートウェイを通じてどのデータが流れ、どこに行くか、設計が防御する攻撃、コンプライアンスアンケートに属する回答。

データフロー

脅威モデルの概要

ゲートウェイはネットワーク境界内に位置しますが、個々の開発者ラップトップは信頼されていないと見なされます。設計はこれを 3 つの方法で説明します:
  • 開発者は生の上流キーの代わりに短命の JWT を保持します。CLI からゲートウェイへのレッグは RFC 8628 デバイスグラントを使用し、ゲートウェイの IdP との認可コード交換はデフォルト設定で PKCE を実行するため、インターセプトされた IdP 認可コードは無用です。
  • デバイス検証ページは同一オリジン POST と RFC 8628 §5.1 ごとの IP ごとのレート制限を実装します。ユーザーコードブルートフォース耐性 を参照してください。
  • ゲートウェイの IdP、OTLP コレクター、および provider: anthropic 上流へのリクエストは、サーバー側リクエストフォージェリ(SSRF)ガードを通じて行われます。DNS を解決し、リンクローカルとクラウドメタデータアドレスをブロックし、デフォルトではループバックをブロックし、接続を解決された IP にピン留めするため、オペレーター影響 URL はクラウドメタデータエンドポイントにリダイレクトできません。RFC 1918 プライベート範囲は意図的に許可されます。IdP と OTLP コレクターは一般的にプライベート IP に存在するため。その他のプロバイダーの場合、ゲートウェイは設定をロードするときにそれらのアドレスまたはメタデータホスト名を指定する base_url を拒否し、プロバイダーの SDK は DNS チェックなしで接続します。 プロキシのみのエグレス をオンにすると、そのアドレスチェックはフォワードプロキシに移動します:ゲートウェイはホスト名を渡し、プロキシのアロウリストはそれらの宛先を拒否する必要があります。 ゲートウェイが正当に到達する必要があるもの(ローカル開発 IdP やサイドカー OTLP コレクター(localhost など))がループバック上に存在する場合にのみ、ゲートウェイの環境で CLAUDE_GATEWAY_ALLOW_LOOPBACK=1 を設定します。変数はすべてのオペレーター設定 URL のループバックブロックを緩和し、ポッドがクラウドメタデータエンドポイントに到達できるかどうかをチェックするブート時警告もスキップするため、コレクターに独自の内部アドレスを与えることをお勧めします。
独自のエグレス制御を追加する場合、ゲートウェイはワークロードアイデンティティなどのインスタンスメタデータ認証情報を使用するときはいつでもメタデータサーバーに到達する必要があります。 2 つの脅威は、インフラストラクチャを保護するためのものであるため、スコープ外です:
  • 侵害されたゲートウェイホスト:ホストは上流認証情報を保持し、管理設定 をすべての接続された開発者に配布するため、ゲートウェイの設定の制御は MDM の制御に匹敵します。CLI の 承認ダイアログ はシェル対応設定のサイレント変更を制限しますが、ホストセキュリティに置き換わりません。
  • 悪意のある OIDC プロバイダー:プロバイダーはゲートウェイが信頼する id_token に署名するため、任意のアイデンティティを主張できます。IdP の検証と保護はあなたの責任です。

ユーザーコードブルートフォース耐性

開発者が /device 検証ページに入力する user_code は、20 文字のアルファベットから引き出された 8 文字です。これは 20⁸ または約 2.56×10¹⁰ の組み合わせを生成し、10 分後に期限切れになります。 ゲートウェイは rate_limits を通じて設定可能なデバイスグラントエンドポイントに IP ごとのレート制限を適用します。多くの開発者が単一の共有企業 NAT アドレスからサインインする場合は、制限を上げます。大規模ロールアウト は、それらのサイズを決定する方法を示しています。制限はサインインフローにのみ適用され、推論には適用されません。

コンプライアンス体制

  • データレジデンシー:ゲートウェイ自体のデータプレーンは、Anthropic API が設定された上流の場合を除き、Anthropic に何も送信しません。その場合、既存のデータ処理契約が推論パスに適用されます。テレメトリ、監査、アイデンティティ、設定は設定した宛先にのみ行きます。
  • ホストプロセストラフィック:ホストプロセスは Claude Code CLI です。claude gateway は Amazon Bedrock および Google Cloud の Agent Platform デプロイメントと同じサードパーティルールの下で実行され、Anthropic に何も送信しません。v2.1.227 より前では、ホストプロセスは製品バージョンとプラットフォームなどのスタートアップテレメトリを送信していました。これはコンテナ環境で CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 を設定することでオフにできました。これらのリリースはまた、ボート時に本文または認証情報なしで 1 つの HEAD リクエストを https://api.anthropic.com の /api/hello に送信していました。または環境が ANTHROPIC_BASE_URL を設定した場合はそれに、環境が HTTPS_PROXY などのプロキシ変数または mTLS クライアント証明書も設定していない限り。彼らは応答を無視したため、エグレスファイアウォールでそのリクエストをブロックしてもゲートウェイに影響しませんでした。
  • クライアント分析:CLI はゲートウェイにサインインしている間、独自の使用分析とエラー報告を無効にします。最初のサインイン前に、CLI はまだ Anthropic にスタートアップイベントを送信します。これには、管理設定がゲートウェイサインインを強制するマシンも含まれます。これらもオフにするには、ゲートウェイサインインを強制する同じ クライアント側管理設定 で DISABLE_TELEMETRY を配信します。
  • エラー報告:CLI はモデルリクエストが Anthropic のファーストパーティ API 以外のエンドポイント(Amazon Bedrock やカスタム ANTHROPIC_BASE_URL など)に行くときはいつでもエラー報告をオフにします。
  • クライアントマシン:開発者の CLI は、CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 と skipWebFetchPreflight: true が設定されていない限り、WebFetch ホスト名チェックとバージョンチェックを Anthropic に送信し続けます。プラグインマーケットプレイスのリクエスト には独自のオフスイッチがあります。データ使用 を参照してください。
  • サーベイ評価:ゲートウェイにサインインしている間、CLI は Anthropic バウンド評価アップロードを分析ストリームと一緒に無効にするため、評価を Anthropic に送信しません。
  • トランスクリプト共有:サーベイのトランスクリプト共有プロンプトで「はい」を選択すると、Anthropic にアップロードする代わりに ~/.claude/feedback-bundles/ の下にローカルファイルを書き込みます。
  • クライアント更新:更新チェックはゲートウェイトラフィックとは別です。独自の配布を通じてバージョンをピン留めし、ラップトップがリリースをフェッチしてはいけない場合は DISABLE_UPDATES を設定します。DISABLE_AUTOUPDATER はバックグラウンド更新のみを停止し、claude update は引き続き機能します。
  • TLS:本番環境で public_url を HTTPS 経由で提供します。ゲートウェイ自体のリスナー経由で listen.tls を使用するか、プレーン HTTP レプリカの前の TLS 終了 ingress から listen.public_url を設定します。どちらの場合でも。ゲートウェイはプレーン HTTP を拒否しません。IdP は本番環境で HTTPS を提供する必要があり、Postgres は ?sslmode=require をサポートします。ingress で Strict-Transport-Security を設定します。
  • 脆弱性開示:セキュリティ問題の報告 に従います

プラグインマーケットプレイスのリクエスト

Claude Code は、プラグインマーケットプレイスをゲートウェイ経由ではなく、各開発者のマシンから直接取得します。ホストの一覧は ネットワークアクセス要件 に記載されています。 開発者が初めてインタラクティブなターミナルセッションを開始すると、Claude Code は公式マーケットプレイス claude-plugins-official を登録します。カタログは downloads.claude.ai からダウンロードされ、それが失敗した場合は github.com からクローンされます。その後の更新については 自動更新されるマーケットプレイスとプラグイン で説明しています。 CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 では最初の登録は止まりません。次のいずれかの管理設定で止めることができます:
  • マーケットプレイスリスト:そのマーケットプレイスを含まない strictKnownMarketplaces 許可リスト、またはそのマーケットプレイスを指定する blockedMarketplaces エントリ
  • 環境変数:管理設定の env ブロック で CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL を "1" に設定
最初の登録は、開発者がゲートウェイにサインインする前、つまりゲートウェイポリシーがまだ届いていない時点で実行される場合があります。この最初の起動にも対応するには、ゲートウェイポリシーの cli または code ブロック に加えて、クライアント側管理設定 でも選択した設定を配信してください。

トラブルシューティング

ご質問やフィードバックについては、Claude Code サポートをご利用いただくか、Claude Code GitHub リポジトリで issue を開いてください。Anthropic のアカウントチームに問い合わせることもできます。問題を報告する際は、以下の情報を含めてください。
  • Gateway の問題: gateway の stderr(該当するウィンドウの)、gateway.yaml(シークレットは削除)、gateway のバージョン(ランディングページの / と /managed/settings の x-cc-gateway-version レスポンスヘッダーに表示)、および最近の変更内容
  • ログイン問題: 開発者が claude --debug-file ./claude-debug.txt を実行して再現し、そのファイルと同じウィンドウの gateway の監査ログを送信
  • 推論の問題: リクエストされたモデル、設定されたアップストリーム、およびリクエストの gateway 監査ログ(どのアップストリームがそれを処理したか、およびレスポンスステータスを記録)
gateway の stderr には監査イベントストリームが含まれ、監査ログには開発者の ID が記録され、デバッグファイルには開発者のマシンからのフックと MCP サーバーの出力が記録されます。公開 issue に投稿する前に、これらを確認して削除してください。 Cloud gateway sign-in was not completed メッセージには gateway ホスト名が示されます。Claude Code がピンされたフィンガープリントと提示されたフィンガープリントの両方を持つ場合、メッセージにはそれぞれの最初の 16 文字も表示されます。 Claude Code がゲートウェイサインイン後に couldn't load your organization's managed settings を報告する場合、Claude Code は理由を示し、その場で再起動して、会話を再開します。Claude Code が再起動できない場合(例えば、バックグラウンドセッション)、Claude Code はセッションを終了し、サインインを保持します。

サインイン後にリクエストヘッダーが大きすぎる

開発者が多数の IdP グループに所属している場合、サインイン後に開発者のリクエストが 431 エラーで失敗することがあります。 gateway は、リクエストのヘッダーの合計が 256 KiB(limits.max_request_header_bytes を設定している場合はその値)を超えると 431 で応答します。これらのリクエストについては、ログ行も監査イベントも書き込みません。v2.1.284 より前の gateway バージョンは、16 KiB を超えると 431 で応答します。 以下のうち、gateway に該当する最初の項目から対応してください。
  • v2.1.284 より古い gateway: gateway をアップグレードしてください
  • limits.max_request_header_bytes が設定されている: 値を上げるか、キーを削除してください
  • いずれにも該当しない、またはその後も 431 が続く: IdP が発行するグループを減らしてください。Okta、Microsoft Entra ID、Google Workspace がグループを提供する方法については、Identity provider setup を参照してください
groups クレームを削減する際は、以下の設定で指定したグループを残してください。これらの設定は、開発者のアクセス、ポリシー、アップストリーム、支出上限を決定します。
  • oidc.allowed_groups: サインインできるユーザーを決定します
  • admin.admin_groups: gateway セッションで管理 API を呼び出せるユーザーを決定します
  • managed.policies 内の match.groups: 開発者に適用されるポリシーを決定します
  • アップストリームの groups: 開発者に対応するアップストリームを決定します
  • rbac_group 支出上限: 開発者に適用されるグループ上限を決定します

長い思考がプロキシのタイムアウトで終わる

アップストリームが provider: anthropic の場合は、代わりに Anthropic API アップストリームでの長い思考を参照してください。そちらでも CLAUDE_STREAM_IDLE_TIMEOUT_MS を上げますが、時間とエラーが異なります。 長い思考の後にターンが失敗し、プロキシが約 12.5 分間開いたままのリクエストを 1 件記録し、その後 504 エラーを連続して記録する場合は、ゲートウェイのポリシーで CLAUDE_STREAM_IDLE_TIMEOUT_MS を上げてください。例えば、プロキシのアイドルタイムアウトが 240 秒の場合、連続するのは 10 件のリクエストで、それぞれが 240 秒で切断されます。
  • 最初のリクエスト: 最初のレスポンスイベントである message_start を配信した後、Claude が思考している間は ping のみを運ぶストリームです。デフォルト設定では、Claude Code は約 12.5 分後にこのストリームを終了します。
  • 残りの 10 件: 同じリクエストをストリーミングなしで送信し、その後再試行したもので、デフォルトでは合計 10 回送信されます。これらには ping が届かないため、応答が遅いとプロキシのタイムアウトに達します。
この修正のためにプロキシのタイムアウトを延ばす必要はありません。プロキシのタイムアウトだけを上げた場合、ストリーミングなしのリクエストは、応答が Claude Code 自身の待機時間(デフォルトでは 300 秒)より長くかかった時点で依然として失敗します。

原因を確認する

開発者に claude --debug-file ./claude-debug.txt で失敗を再現してもらい、そのファイルで次の行を検索してください。
開発者がすでに CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK を 1 に設定している場合、ストリーミングなしのリクエストは発生せず、ターンは API Error: Stream idle timeout - no chunks received で終了します。同じ修正が適用されます。

値を選ぶ

2 列目が最も長い思考の間をカバーする CLAUDE_STREAM_IDLE_TIMEOUT_MS の値を選んでください。それがわからない場合は 1800000 から始めてください。ストリームは、この値より約 7.5 分長く ping のみで維持できます。 ゲートウェイが ping を送り続けている間にアップストリームがハングした場合、開発者も Claude Code がストリームを諦めるまでそれだけの時間待つことになります。完全に無音になった接続は、ボディのアイドルタイムアウトがこの変数に従わないため、引き続き 5〜6 分後に終了します。

ポリシーで値を配信する

対象とする開発者にすでに Claude Code の設定を配信している gateway.yaml 内の各ポリシーに、env エントリを追加してください。そのポリシーにすでにある code、cli、または settings キーの下に配置します。まず値を試すには、1 つのグループに一致するポリシーから始めてください。ポリシーの一致と継承の仕組みについては、managed を参照してください。この例では、cli をキーとする match: {} ポリシーにエントリを追加します。
cli キーを使うと、ターミナル、IDE 拡張機能、Agent SDK のセッションが対象になります。Claude Desktop の Code タブについては、cli または code を選ぶを参照してください。 編集したファイルを読み込むようにゲートウェイを再起動してください。その後、開発者に Claude Code を再起動してもらい、CLAUDE_STREAM_IDLE_TIMEOUT_MS を取得させてください。

Anthropic API アップストリームでの長い思考

provider: anthropic がモデルの唯一のアップストリームで、プロキシが約 20 分間開いたままのリクエストを 1 件記録し、その後 502 または 504 エラーを記録する場合は、ゲートウェイのポリシーで CLAUDE_STREAM_IDLE_TIMEOUT_MS を上げてください。
  • 長いリクエスト: message_start を配信した後、Claude が思考している間は ping のみを運ぶストリームです。Claude Code はデフォルト設定では約 20 分後にこれを終了し、変数を上げるとそれより後に終了します。
  • エラー: その後 Claude Code がストリーミングなしで送信するリクエストです。それぞれがゲートウェイからの 502 で失敗するか、プロキシのタイムアウトがゲートウェイの待機時間より短い場合はプロキシの 504 で失敗します。その待機時間は timeouts.upstream_ttfb_ms ですが、この修正のために上げる必要はありません。
原因を確認するには、原因を確認するを参照してください。 最も長い思考の間をカバーする時間の値を選んでください: デフォルトでは約 20 分、900000 では 30 分、1800000 では 45 分です。その後、ポリシーで値を配信するの手順に従ってください。