Claude apps gatewayとは — 構築手順とSSOで複数クラウドを統合
Claude apps gatewayは自社のクラウド経由でClaude Codeを使うためのセルフホスト型ゲートウェイです。構築手順、対応する上流、使えない機能を解説します。
Claude apps gatewayは何を解決するか
Claude apps gatewayは、自社のクラウド経由でClaude Codeを使わせるためのセルフホスト型ゲートウェイです。開発者のClaude Codeとモデルプロバイダーの間に立ちます。
サーバーはclaudeバイナリに含まれており、claude gateway --config gateway.yamlを実行するだけで立ち上がります。ノートPCで動かすのと同じ実行ファイルがそのままサーバーになります。社内に別途置くLLMゲートウェイ(LiteLLMなど)とは別物です。
開発者はAPIキーやクラウドの認証情報を持たず、企業のIDプロバイダー(IdP)でサインインします。ゲートウェイが上流の認証情報を保持し、IdPグループ単位でモデルアクセスとmanaged settingsを強制し、利用状況のテレメトリを組織自身の可観測性スタックへ中継します。上流にはAmazon Bedrock・Claude Platform on AWS・Google Cloud's Agent Platform・Microsoft Foundry・Anthropic APIを選べ、複数を組み合わせたフェイルオーバーにも対応します。ゲートウェイはプロンプトや応答の内容をログにも保存にも残しません。ただし、ログやトレースを有効にした宛先には、コマンドやファイルパスが含まれることがあります。
データレジデンシー要件で自社クラウド経由の推論が必須、あるいは必須ではないが望ましいという組織向けの機能です。そうした要件が無く、SCIMプロビジョニングやWeb・モバイル版のClaude Codeも使いたいのであれば、Claude Enterpriseの方が適していることもあります。社内にすでに別のLLMゲートウェイがあり、そちらを継続するか迷う場合は選び方の比較を先に確認しておくと、この構築が自組織に合っているかを判断しやすくなります。
前提条件
| 項目 | 必要な状態 |
|---|---|
| Claude Codeのバージョン | 必要な状態v2.1.195以降(claude gatewayサブコマンドとサインインフローがこのバージョンから同梱)。ゲートウェイサーバー・開発者端末の両方が対象。Claude Platform on AWSを上流にする場合はゲートウェイサーバー側がv2.1.198以降。Claude Desktopを接続する場合はゲートウェイサーバー側がv2.1.203以降 |
| OIDC IdP | 必要な状態Okta・Microsoft Entra ID・Google Workspace・Keycloak・Dex等のOIDC準拠IdP。SAML・LDAPは非対応 |
| PostgreSQL | 必要な状態11以降(11〜13はゲートウェイサーバーがv2.1.290以降。公式は新しい版を勧めています)。デバイスサインインフローの状態管理とレート制限カウンターに使う。支出上限を設定する場合は監査・支出・ID関連のテーブルも持つため要バックアップ |
| モデルの上流 | 必要な状態Bedrock・Claude Platform on AWS・Google Cloud・Microsoft Foundryの認証情報、またはAnthropic APIキー。複数指定してフェイルオーバー可能 |
| HTTPS | 必要な状態開発者端末とサインイン用ブラウザから到達できるhttps://。ゲートウェイのホスト名またはIPアドレスはプライベートアドレスのみ解決すること(RFC 1918・リンクローカル・CGNAT・IPv6 ULA・ループバック)。自組織が所有する公開IPv4ブロックで社内を採番している場合は、managed settingsのgatewayInternalNetworksで宣言すれば受け付けられる(開発者端末がv2.1.268以降)。宣言できるのは最大4ブロックで、互いに重複させられません。開発者端末が宣言したブロック内のアドレスから直接接続する必要があり、NAT・コンテナ・WSL2の内側や、プールが範囲外のVPNからは拒否されます。あわせてゲートウェイのaccess_control.allow_cidrsも同じブロックに揃えます。listen.tlsで証明書を渡すか、TLS終端するingressの背後に置く。どちらの場合もlisten.public_urlに外部オリジンを設定する |
| 実行環境 | 必要な状態サーバーはLinuxのネイティブバイナリのみ。macOSはローカル開発用、Windowsサーバーは非対応 |
プライベートアドレス限定の制約は意図的なガードレールです。プロキシ経由でHTTPS接続する環境では、プロキシのホストも私的アドレスに解決される必要があり、そうでなければゲートウェイのホストをNO_PROXYに加えます。信頼されたゲートウェイは開発者端末でコマンドを実行できる設定を配布できるため、公開アドレスに置くと第三者からの悪用経路になります。
ステップ1: OAuthクライアントをIdPに登録する
先にゲートウェイのホスト名を決めます。リダイレクトURIがそのホスト名に一致する必要があるためです。IdP側で新しいOIDC Webアプリケーションを作成し、リダイレクトURIをhttps://<gatewayのホスト>/oauth/callbackに設定して、発行されたclient_idとclient_secretを控えます。
ステップ2: PostgreSQLを用意する
Postgres 11以降(11〜13はサーバーがv2.1.290以降)であれば、マネージドサービスの最小プランでも構いません。メンテナンスが終わった版なので、選べるなら新しい版にします。ゲートウェイは起動時に自分のスキーマをマイグレーションするため、データベースロールにはテーブルの作成・変更権限が必要です。
ステップ3: gateway.yamlを書く
最小構成は5つのセクションだけで、それ以外の項目にはすべて既定値があります。シークレットは${ENV_VAR}展開で読み込むため、設定ファイル自体はバージョン管理に置けます。
listen:
host: 0.0.0.0
port: 8080
public_url: https://claude-gateway.internal.example.com
oidc:
issuer: https://login.example.com
client_id: 0oa1example2
client_secret: ${OIDC_CLIENT_SECRET}
allowed_email_domains: [example.com]
session:
jwt_secret: ${GATEWAY_JWT_SECRET}
ttl_hours: 1
store:
postgres_url: ${GATEWAY_POSTGRES_URL}
upstreams:
- provider: bedrock
region: us-east-1
auth: {}この設定だけでAmazon Bedrockの既定モデルカタログを使ったサインインが動きます。Bedrockの上流にはbedrock:InvokeModelとbedrock:InvokeModelWithResponseStreamをinference-profile/us.anthropic.*とfoundation-model/anthropic.*の両方のARNに持つAWSプリンシパルが必要です。静的キーよりIRSA・ECSタスクロール・EC2インスタンスプロファイルでの認証情報供給が推奨されます。IdPグループ別のRBAC・managed settings・複数上流のフェイルオーバーは、この最小構成を土台に追加していきます。
session.jwt_secretは32文字以上が必須です。短い値だと起動時に設定検証で止まるため、openssl rand -base64 32で生成した値を環境変数で渡します。
Note: 対象アカウントでBedrockコンソールのモデルカタログから一度だけ利用申請フォームを提出しておく必要があります。IAMの権限設定に加えて、この申請の提出が必要です。
ステップ4: 起動して確認する
claudeバイナリを含むコンテナイメージをビルドし、Postgresと一緒に起動します。ゲートウェイは設定を読み込み、Postgresへ接続してスキーママイグレーションを適用し、IdPに対してOIDCディスカバリーを実行し、上流クライアントを構築してからリッスンを始めます。設定・Postgres接続(5秒タイムアウト)・OIDCディスカバリー・上流クライアント構築のいずれかが失敗すると、ゲートウェイは劣化した状態でトラフィックを受け付けるのではなく、エラーを出して終了します。TLSを終端するingressがすでにあるなら、コンテナを使わずclaude gateway --config gateway.yamlで直接起動できます。その場合はpublic_urlをingressのオリジンにし、listenをループバックまたはクラスタ内部アドレスに束ねます。
起動を確認する検証は3段階で、上から順に、最初に失敗したものが原因の場所を指します。
起動確認の3段階
- 1
ディスカバリードキュメントを取得する
/.well-known/oauth-authorization-serverをcurlで取得します。返れば、ゲートウェイが起動し、設定が有効で、起動時のチェックを通過しています。失敗したなら起動が完了していないので、stderrを見ます。 - 2
デバイス認可をリクエストする
POST /oauth/device_authorizationがdevice_codeとuser_codeを返せば、Postgresへ書き込めています。失敗したなら、接続文字列とロールの権限を疑います。 - 3
ブラウザで検証URLを開く
verification_uri_completeを開き、IdPのサインイン画面へ飛ぶことを確認します。IdPまで届かないならリダイレクトURIの不一致です。届いてエラーで戻る場合は、ゲートウェイの監査ログにemail domain not allowedのような拒否理由が残っています。
起動が成功しても推論経路までは検証されない点に注意します。BedrockとGoogle Cloud's Agent Platformのインスタンス認証情報は起動時ではなく最初のリクエストで解決されるため、起動確認の3段階を通過した後も、実際にモデルへリクエストを送るまでは上流の認証情報が正しいかどうかは分かりません。
起動に失敗したときの実際の出力
Claude Code v2.1.285で、最小構成のYAMLをmin.yamlとしてローカルで起動し、失敗の出方を確かめました。上流のAWS認証には触れていません。ファイルが無い場合は、1行で終わります。
claude gateway --config ./nope.yaml
# claude gateway: ENOENT: no such file or directory, open './nope.yaml'${ENV_VAR}に対応する環境変数が未設定だと、変数名を挙げて止まります。
claude gateway --config min.yaml
# claude gateway: undefined env var in config: OIDC_CLIENT_SECRETsession.jwt_secretに短い値を入れると、スキーマ検証のエラーがJSONで出て、pathにsessionとjwt_secretが入ります。メッセージはString must contain at least 32 character(s)です。
Postgresへ届かない場合は、設定を読み込んだ後に2秒間隔で3回まで再試行し、原因を書いて終了します。
[gateway] warn could not connect to Postgres at boot, attempt 1 of 3: Failed to connect. Trying again in 2s
[gateway] warn could not connect to Postgres at boot, attempt 2 of 3: Failed to connect. Trying again in 2s
[gateway] error could not connect to Postgres at boot: Failed to connect. Check store.postgres_url. If the database needs longer to become reachable, raise store.connect_timeout_seconds (now 5s)
claude gateway: could not connect to Postgres: Failed to connect. Check store.postgres_url in min.yamlDBの起動が遅い環境では、最後のエラーが示すとおりstore.connect_timeout_secondsを上げます。
ステップ5: 開発者をサインインさせる
開発者端末のmanaged settingsファイルでforceLoginMethodを"gateway"に、forceLoginGatewayUrlをゲートウェイのpublic_urlに設定します。この状態で/loginを実行すると、Cloud gateway画面がURL入力済みの状態で直接開きます。開発者はこの画面でEnterキーを押し、ブラウザでのサインインを完了させます。
managed settingsを配布していない端末では、開発者が~/.claude/settings.jsonにこの2つのキーを書いて指定することもできます(開発者端末がv2.1.295以降)。プロジェクトの.claude/settings.jsonでは読まれず、管理者のmanaged settingsが届いた端末ではユーザー設定のゲートウェイ指定は無視されます。
CLIはゲートウェイのTLSサーバー証明書をホスト名ごとに初回接続時にフィンガープリント認証(pinning)します。/loginのプロンプトにはフィンガープリントの先頭16文字が小文字16進数で表示されるため、管理者はゲートウェイURLと一緒にこの値を周知し、開発者が照合できるようにします。証明書をローテーションするたびに全開発者がこの信頼プロンプトを再度目にするため、ローテーションは計画されたイベントとして扱います。
複数クラウドをどうまとめるか
upstreamsブロックは複数のプロバイダーを並べてフェイルオーバーさせられます。リージョンやプロバイダーを切り替えても、切り替えはゲートウェイの背後で行われ、開発者側の設定変更は要りません。モデルアクセスはIdPグループ単位でavailableModels許可リストにマッピングされ、ゲートウェイがサーバー側で許可されていないモデルへのリクエストを拒否します。
Claude Desktopも同じゲートウェイに接続できますが、入口のキーが違います。
Claude CodeとClaude Desktopの接続設定
Claude Code(CLI)
forceLoginMethodとforceLoginGatewayUrlを配布用のmanaged settingsに書きます。/loginがCloud gateway画面で開きます。
Claude Desktop
Claude Desktopのmanaged configurationでbootstrapUrlを<listen.public_url>/user/bootstrapにし、ポリシー側でdesktopキーによるオプトインを行います。ゲートウェイ側はv2.1.203以降が必要です。
DesktopはゲートウェイのIdPでCLIと同じブラウザSSOを行い、設定をAnthropicではなくゲートウェイから取得します。CLIとDesktopの両方を使う開発者は、それぞれ別にサインインします。セッションは共有されません。接続後はCowork・Codeタブ(既定で有効)のモデルリクエストがゲートウェイを通り、ChatタブはchatTabEnabledをtrueにすると有効化できます(ゲートウェイがv2.1.227以降の場合、ポリシーのdesktopブロックでも設定可能)。
使えない機能・制限
| 機能 | 状態 | 補足 |
|---|---|---|
| サーバー側のWeb検索 | 状態利用不可 | 補足CLIはゲートウェイがどの上流プロバイダーへルーティングしているか分からず、Web検索のサポート有無を検証できないため無効化される |
| Remote Control | 状態利用不可 | 補足ゲートウェイを名指ししたエラーが表示される |
/design-sync・/design-login | 状態利用不可 | 補足どちらもclaude.aiへの接続が必要で、ゲートウェイセッションのCLIはclaude.aiに接続しないため、コマンド自体が表示されない |
フィーチャーフラグの取得が必要な機能(/import・claude import等) | 状態利用不可 | 補足ゲートウェイセッションのCLIはフラグの取得を行わない |
| Bedrock Mantleエンドポイント | 状態上流として利用可 | 補足ゲートウェイサーバーがv2.1.283以降なら上流に指定できる。既定のBedrock上流はbedrock-runtimeエンドポイントとAWSの既定の認証情報チェーンを使う |
| 1時間キャッシュTTL | 状態利用不可 | 補足すべての上流が1時間TTLに対応しているわけではないため、ゲートウェイ経由のプロンプトキャッシュは5分TTLで動く |
| ファーストパーティ限定の最適化(グローバルキャッシュスコープ等) | 状態利用不可 | 補足CLIがゲートウェイセッションでは有効化しない |
| OTLP/gRPC | 状態未対応 | 補足OTLP over HTTPのみ |
| SAML・LDAP | 状態未対応 | 補足OIDCのみ。必要ならOIDCブリッジを前段に置く |
| マルチテナント(複数OIDC発行者) | 状態未対応 | 補足1ゲートウェイにつき1発行者。複数必要ならインスタンスを分ける |
| Windowsサーバー | 状態未対応 | 補足Linuxにデプロイする。macOSはローカル開発用のみ |
| Helm chart | 状態提供なし | 補足ステートレスな標準のDeploymentとして動かす。デプロイ定義は自組織で用意する |
| 管理UI | 状態提供なし | 補足設定はgateway.yamlで、変更するには再デプロイする。支出上限には管理用のAPIがある |
一方で標準のプロンプトキャッシュ・Auto mode(サードパーティプロバイダーのルールに従う対象モデルのみ)・IdPグループ単位のモデルアクセス統制・OTLPテレメトリのファンアウトは利用できます。
よくあるつまずき
- パブリックアドレスでの拒否:
/loginはゲートウェイのホスト名が解決する全アドレスをチェックし、1つでも公開アドレスなら拒否します。VPNや内部ロードバランサーの背後に置く前提を崩さないようにします - CIパイプラインでの誤用: ゲートウェイのサインインはブラウザのデバイスフローのみでサービストークンが無いため、承認する開発者がいないCIジョブは認証できません。こうしたパイプラインはプロバイダーへの直接構成(/setup-bedrockウィザードのような手順)に切り分けます。CIやリモート開発機からapps gatewayを使う回避策にAgent SDK・
claude -pを含めた具体的な構成をまとめています - Desktopだけの端末でのegress抜け: Desktopが起動するClaude Codeセッションには、ゲートウェイのegress許可リストが親プロセスの設定として渡ります。モデル一覧と無効化ツールはDesktopが自分で適用しますが、egress許可リストだけは親設定経由でしか届きません。管理者が配備したmanaged設定のある端末では、
parentSettingsBehavior: "merge"が無いと親プロセスの設定は無視されます。入れ忘れると、その制限は届かないままになります - リトライの枯渇を見落とす: 上流の障害が続くと、Claude Code側でリトライが尽きたセッションが出ます。追い方はretry exhaustionの検知にあります
- 証明書ローテーションの周知漏れ: TLS証明書を更新すると全開発者に信頼プロンプトが再表示されるため、更新前に新しいフィンガープリントの先頭16文字を周知しておくと、開発者が照合できます
まとめ
社内にプライベートなネットワークとOIDC対応のIdPがあり、推論を自社のクラウド経由にしたいなら、構築の手間はgateway.yamlの5セクションとPostgresで収まります。CIジョブやWeb・モバイル版の利用が要件に入るなら、ここで手戻りが出るため、先に制限の表を当てはめて判断します。