Claude apps gatewayのdesktopブロックでClaude Desktopに設定を配る
gateway.yamlのdesktopブロックで、Claude Desktopの設定をポリシーごとに配る方法を解説します。opt-in、cliからの導出、和集合と上書きの違い、要件バージョンまでを扱います。
desktopブロックは何をするものか
desktopブロックは、gateway.yamlのmanaged.policiesに置く任意のキーです。Claude apps gatewayが/user/bootstrapで返すClaude Desktop向けの設定を、ポリシー単位で直接指定できます。cliブロックと並べて書きます。
/user/bootstrapは、ポリシーにdesktopキーがあるユーザーにだけ応答します。キーが無ければ404です。空のdesktop: {}だけでもオプトインになり、match: {}のベース層に置けば、それを継承する全ポリシーがオプトインします。ゲートウェイ側にはClaude Code v2.1.203以降が必要です。
Desktop側の準備は別です。Claude Desktopの管理設定(managed configuration)でbootstrapUrlを<listen.public_url>/user/bootstrapに向けます。DesktopはこのURLからOAuthの発行元を導き、同じデバイスコード方式のサインインを行い、応答から設定を受け取ります。gateway.yaml全体の構成はgateway.yamlリファレンス、ゲートウェイの導入はClaude apps gatewayの使い方にあります。
cliブロックから自動で導出される項目
desktopブロックを空にしても、応答は空になりません。ゲートウェイは、マッチしたポリシーのcliブロックとトップレベルの設定から、次の項目を組み立てます。
| Desktopに渡る項目 | 導出元 |
|---|---|
| モデル一覧 | 導出元cliのavailableModels |
| 無効化するツール | 導出元cliのpermissions.denyのうち、ツール名だけの項目 |
| egress許可リスト | 導出元cliのsandbox.network.allowedDomains |
| OTLPエンドポイントとユーザー識別属性 | 導出元telemetry.forward_toとlisten.public_url(両方を設定したとき) |
Bash(npm *)のような範囲指定つきの権限ルールやhooksは、Claude Desktopに対応するキーが無いため、応答から省かれます。CLIとDesktopで同じ統制をかけたいなら、まずcliブロックに書き、Desktop固有の調整だけをdesktopに足す形が素直です。
OTLPの中継先はテレメトリの設定記事にまとめています。Desktopは全シグナルを1種類のエンコードで送ります。既定はhttp/protobufで、ポリシーのenvでOTEL_EXPORTER_OTLP_PROTOCOL(または信号別の変数)をhttp/jsonにしたときだけJSONになります。v2.1.261より前のゲートウェイは、設定に関係なくhttp/jsonを返していました。protobufしか受け付けないコレクターがDesktopの送信を拒否したのは、この挙動が原因です。
desktopブロックの書き方
desktopには、Claude Desktopの管理設定リファレンスにあるキーを、フラットなキー名のまま書きます。すべて省略可能で、書かなかったキーはDesktopの既定値で動きます。
次は公式docsの例に沿った形です。
managed:
policies:
- match: { groups: [eng-contractors] }
cli:
availableModels: [claude-sonnet-4-6]
desktop:
isLocalDevMcpEnabled: false
disableAutoUpdates: true
banner: { text: "Contractor build: internal use only" }ここに書けないキーがあります。bootstrapUrlのように、DesktopがMDMやローカルファイルからしか読まないキーです。ゲートウェイは起動時にこれを弾きます。Chatタブを有効にするchatTabEnabledはこのブロックに書けます。ゲートウェイがv2.1.227以降の場合です。
書けるキーの早見表
Claude Desktopの管理設定リファレンスで、配布方法が「MDM + Bootstrap」となっているキーが、desktopブロックで配れる候補です。公式はキーごとに「Added in 1.xxxxx.0」と、追加されたDesktopのバージョンを載せています。次の表はそのうち使う場面の多いものです。
| キー | 用途 | 必要なDesktop |
|---|---|---|
chatTabEnabled | 用途Chatタブを有効にする | 必要なDesktop1.13576.0以降 |
chatAdvancedFileAnalysisEnabled | 用途添付したExcelなどをローカルのサンドボックスで解析させる(既定はオフ) | 必要なDesktop1.14271.0以降 |
isClaudeCodeForDesktopEnabled | 用途Codeタブを有効にする(既定はtrue) | 必要なDesktop1.2581.0以降 |
isLocalDevMcpEnabled | 用途利用者が開発者設定から追加するローカルのstdio MCPサーバーを許可する(既定はtrue) | 必要なDesktop1.2581.0以降 |
disableAutoUpdates | 用途Desktopの自動更新を止める。新バージョンは管理者が配る | 必要なDesktop1.2581.0以降 |
banner | 用途サインイン後、ウィンドウ上部に常時表示するバナー | 必要なDesktop1.7196.0以降 |
builtinToolPolicy | 用途組み込みツールごと、またはBash(curl *)のような範囲指定ルールごとの承認方針 | 必要なDesktop1.8089.0以降 |
orgPluginSettings | 用途プラグインが配るMCPサーバーへの管理者ポリシー | 必要なDesktop1.8089.0以降 |
disabledBuiltinTools | 用途CoworkとCodeで拒否する組み込みツール | 必要なDesktop1.2581.0以降 |
coworkEgressAllowedHosts | 用途CoworkとCodeのセッションが接続してよいホスト | 必要なDesktop1.2581.0以降 |
managedMcpServers | 用途組織が配るMCPサーバー(リモートまたはローカル) | 必要なDesktop1.2581.0以降 |
キーによっては、値に旧形式の受け入れ期限が付いています。builtinToolPolicyのask-sessionは2026年10月7日まで受け付けられ、以降はaskと同じ扱い(呼び出しのたびに承認)になります。orgPluginSettingsを旧来のmcpServersレコード形式で書いていると、同じ日を過ぎた時点で不正な値として拒否され、プラグイン経由のMCPツールがすべてブロックされます。allow以外を設定したツールの扱いは、後述のマージ規則にも関わります。
managedMcpServersやcoworkEgressAllowedHostsのように配列やオブジェクトを取るキーは、MDMではJSON文字列として渡すのが共通の書き方です(macOSのプロファイルはネイティブの配列や辞書でも渡せます)。
表に無いキーも、リファレンスにあれば書ける可能性があります。ただし、ゲートウェイが受け付けるかどうかは、インストール済みのバージョンに同梱されたスキーマで決まります。v2.1.232より前に受け付けていた11個の機能ゲート用キーが具体的にどれかは、公式ページにも一覧がありません。表のキーが古いゲートウェイで通るかは、起動時の検証で確かめてください。
v2.1.232で追加された3つのキー(disabledBuiltinToolsほか)
v2.1.232以降のゲートウェイでは、desktopブロックに次の3つを置けます。v2.1.232より前は、受け付けるキーがchatTabEnabledやdisableAutoUpdatesなど固定の11個の機能ゲート用キーだけで、それ以外は起動時にエラーでした。
disabledBuiltinTools: Desktopで無効にする組み込みツールの指定coworkEgressAllowedHosts: Coworkセッションが接続してよいホストの許可リストmanagedMcpServers: Desktop自身のmanagedMcpServers設定。値はオブジェクトではなく配列
managedMcpServersの値の形は、CLI側のcliブロックと混同しやすい点です。cliではMCPサーバーをmanagedMcpServersのオブジェクトとして書き、.mcp.json流のmcpServersは起動時に拒否されます。desktop側は配列です。transportを持たない旧形式の項目は、起動はしますが、置き換え先を示す警告がログに出ます。v2.1.260より前は、入れ子のオブジェクト内の綴りミスが黙って捨てられていました。現在は起動時のエラーになります。
和集合になるキーと上書きになるキー
導出値との関係は、キーごとに違います。
| キー | cliからの導出値との関係 |
|---|---|
disabledBuiltinTools | cliからの導出値との関係和集合。足して無効にはできるが、permissions.denyで無効にしたツールは戻せない |
coworkEgressAllowedHosts | cliからの導出値との関係上書き。書いた値が使われ、sandbox.network.allowedDomainsからの導出値は捨てられる |
上書きの側は落とし穴になります。sandbox.network.allowedDomainsに10ホストを書いていても、coworkEgressAllowedHostsに1ホストだけ書けば、Cowork側の許可は1ホストになります。導出値に足したいなら、導出元のホストもcoworkEgressAllowedHostsに書き直す必要があります。
sandbox.network.allowedDomainsがDesktopで効かないという報告は別の話で、Claude Desktopでsandbox.network.allowedDomainsが効かない問題の記事で扱っています。
ベース層とロール別ポリシーのマージ
desktopブロックは、cliと同様にmatch: {}のベース層から補完されます。ロール別ポリシーが書かなかったキーは、ベースの値で埋まります。
競合したときの規則は、キーの種類で3通りです。
disabledBuiltinTools: ベースとポリシーの和集合builtinToolPolicy: ベースでallow以外にしたツールは、ロール別ポリシーでallowにしてもベースの値が残る- それ以外のキー: ロール別ポリシーの値が使われる
配列やbannerのような入れ子のオブジェクトは、丸ごと置き換わります。ロール別ポリシーでbanner.textだけを書くと、ベースのbanner.backgroundColorは消えます。ここは設定の粒度を間違えやすい箇所です。
起動時の検証で何が弾かれるか
ゲートウェイは起動時に、各desktopブロックをClaude Desktopが使うのと同じ設定スキーマで検証します。間違いはDesktopに届く前に、キー名つきのエラーとして出ます。起動が失敗する条件は次の4つです。
- 未知のキー
- 値が空だったり、入れ子のキーが綴り違いだったりして、Desktopが拒否または黙って捨てる値
- ゲートウェイ自身が計算するキー(推論の接続先、モデル一覧、OTLPの中継)。これらは
upstreams・models・telemetry.forward_toで設定します - 現行キーの旧称。エラーには、書くべき正式なキー名が出ます
検証に使うスキーマは、インストール済みのゲートウェイのバージョンに同梱されたものです。新しいDesktopで追加された設定を配るときは、先にゲートウェイを上げます。たとえばuserPluginMarketplacesEnabledとuserPluginUploadsEnabledは、ゲートウェイがv2.1.260以降で、メンバーのDesktopが1.37937.0以降のときに使えます。
設定変更後の確認には、ゲートウェイを設定ファイルつきで起動し直します。
claude gateway --config gateway.yamldesktopブロックに問題があれば、ここで起動が止まり、原因のキーが表示されます。運用中の確認には監査ログが使えます。Desktopからの各リクエストはdesktop_bootstrap.serveかdesktop_bootstrap.deniedとして記録されます。
バージョン要件の早見表
| 使いたいもの | ゲートウェイ(Claude Codeのバージョン) | Desktop側 |
|---|---|---|
/user/bootstrapの応答(opt-in) | ゲートウェイ(Claude Codeのバージョン)v2.1.203以降 | Desktop側— |
chatTabEnabledなど | ゲートウェイ(Claude Codeのバージョン)v2.1.227以降 | Desktop側— |
disabledBuiltinTools・coworkEgressAllowedHosts・managedMcpServers、任意キーの受け入れ | ゲートウェイ(Claude Codeのバージョン)v2.1.232以降 | Desktop側— |
| 入れ子の綴りミスを起動時エラーにする | ゲートウェイ(Claude Codeのバージョン)v2.1.260以降 | Desktop側— |
userPluginMarketplacesEnabled・userPluginUploadsEnabled | ゲートウェイ(Claude Codeのバージョン)v2.1.260以降 | Desktop側1.37937.0以降 |
| OTLPのエンコードがprotobufに従う | ゲートウェイ(Claude Codeのバージョン)v2.1.261以降 | Desktop側— |
user.email・user.groupsをDesktopのテレメトリに付与 | ゲートウェイ(Claude Codeのバージョン)v2.1.265以降 | Desktop側user.groupsは1.24012以降 |
orgPluginSettingsの配列形式 | ゲートウェイ(Claude Codeのバージョン)— | Desktop側1.15200.0以降 |
つまずきやすい点
404が返る
ポリシーにdesktopキーが無いのが原因です。Desktopを使わない組織は、desktopをどのポリシーにも書かないでください。その場合、全ユーザーで/user/bootstrapは404になります。
egress制限が効かない
Desktopだけを使うマシンでは、egress許可リストは親設定(parent settings)として埋め込みセッションに届きます。届いた設定は、管理者が配布した管理設定ソースがあるマシンでは既定で無視されます。そのソースにparentSettingsBehavior: "merge"を入れておく必要があります。入れ忘れても警告は出ず、制限なしでセッションが動きます。モデルの許可はゲートウェイ側が拒否するため、影響はegressに限られます。forceLoginGatewayUrlの記事は、CLI側のログイン設定を扱っています。Desktopの接続はforceLoginGatewayUrlではなく、Desktop側の管理設定にあるbootstrapUrlで行います。
orgPluginSettingsが効かない
ゲートウェイは配列形式で配りますが、古いDesktopはそれを無視し、プラグインのツール制御を一切かけません。メンバーを1.15200.0以降に更新してから頼ってください。
フック・環境変数がDesktopで動かない
hooks、env、範囲指定の権限ルールは、/loginでサインインしたクライアントにだけ届きます。Desktopの埋め込みセッションには渡りません。
まとめ
desktopブロックの要点は3つです。ポリシーにdesktopキーを置かないと/user/bootstrapは404になること。disabledBuiltinToolsは導出値との和集合で、coworkEgressAllowedHostsは導出値を置き換えること。ゲートウェイのバージョンが低いと、書けるキーも変わることです。
まずdesktop: {}で接続を通し、cliからの導出結果を確認してから、必要なキーを1つずつ足していく進め方なら、起動時検証のエラーで原因を特定しやすくなります。