sshHostAllowlistでClaude Code DesktopのSSH接続先を制限する
sshHostAllowlistはClaude Code DesktopのSSHセッションを許可ホストだけに絞るmanaged設定です。書き方とパターンの一致規則、CLIには効かない適用範囲をまとめます。
sshHostAllowlistは何を止めて何を止めないか
sshHostAllowlistは、Claude Code DesktopのSSHセッションが接続できるホストを、管理者が許可したパターンだけに絞るmanaged設定です。許可パターンを配ると、ユーザーは解決後のホスト名がパターンに一致するホストにしか接続できません。空配列を配った端末では、SSHセッション機能そのものが止まります。
DesktopのSSHセッションでは、接続先のマシン上でClaudeがファイルを編集し、コマンドを実行します。接続先を管理対象のサーバーに限りたいときに使うのがこの設定です。
一方で、止まる範囲は広くありません。「CLIにも効くはず」「Bashツールのsshも止まるはず」という前提で配ると、制限が空振りします。適用範囲から先に押さえます。
SSH接続そのものの追加方法や認証まわりはClaude Code SSH接続ガイドにあります。ここでは、管理者が配るこの設定に絞ります。
効く範囲は狭い — Desktopアプリの接続先選択だけ
sshHostAllowlistが届く場所と届かない場所
届く: Desktopアプリ
Desktopアプリが開くSSHセッションの接続先です。手元の端末のmanaged settingsから読まれます。
届かない: CLIとIDE拡張
ターミナルの
claudeコマンドとIDE拡張は、このキーを読みません。届かない: Bashツールのssh
セッション内でBashツールが実行する
sshコマンドは制限の対象外です。
ターミナル中心のチームがこの設定を配っても、CLI側の接続は何も変わりません。Claude Codeのセッション内でssh some-hostを実行すれば、許可リストの外にも届きます。
この設定が制御するのは、Desktopアプリがどのホストへ接続するかです。ネットワークの出口(egress)は制御しません。強い境界が必要なら、組織のネットワーク制御やゼロトラストの仕組みを併用する前提で設計します。
設定手順 — managed settingsに配列を書く
許可リストを配る手順
- 1
許可するホスト名を洗い出す
接続を許すホストを、ホスト名ベースでまとめます。サブドメイン単位で許すならワイルドカード、1台だけなら完全一致で書きます。
- 2
managed settingsに書く
ユーザー設定やプロジェクト設定に書いても読まれません。
sshHostAllowlistはmanaged settings専用のキーです。 - 3
手元の端末で動作を見る
配布後は、Desktopの環境ドロップダウンからSSH接続を選び、許可したホストに入れて、許可外のホストが拒否されることを確かめます。
書き方は次のとおりです。
{
"sshHostAllowlist": ["*.devboxes.example.com", "bastion.example.com"]
}この例が許すのは、devboxes.example.comとその配下のサブドメインすべて、それにbastion.example.comの1台です。キーを置かなければ既定は未設定で、どのホストにも接続できます。つまり、設定を配り忘れた端末は、制限なしの状態のままです。
配列を空にすると意味が変わります。"sshHostAllowlist": []は「許可ホストなし」ではなく、SSHセッションを丸ごと無効にする指定です。段階的に絞る途中で仮の空配列を置くと、SSH経由で開発している人の作業が止まります。
パターンの一致規則 — 判定されるのは解決後のHostName
パターンの型は3つで、大文字小文字は区別されません。
*: 任意のホストに一致する(制限なしと同じ効果)*.example.com:example.com自体と、配下のすべてのサブドメインに一致する- それ以外: ホスト名との完全一致
次の表は、["*.devboxes.example.com", "bastion.example.com"]に対する判定を、型の規則どおりに当てはめた例です。
| 解決後のホスト名 | 一致するパターン | 結果 |
|---|---|---|
box1.devboxes.example.com | 一致するパターン*.devboxes.example.com | 結果許可 |
devboxes.example.com | 一致するパターン*.devboxes.example.com | 結果許可(ワイルドカードは親ドメイン自身も含む) |
Bastion.Example.com | 一致するパターンbastion.example.com | 結果許可(大文字小文字は無視) |
other.example.com | 一致するパターンなし | 結果拒否 |
見落としやすいのは、判定の対象です。SSH Hostの欄には、user@hostnameの形か、~/.ssh/configで定義したHost名を入れられます。ポートの欄は、空ならSSH configの値か22番が使われます。判定にはその入力文字列そのものでなく、~/.ssh/configをssh -Gで解決した後のHostNameと、許可パターンを突き合わせます。HostのエイリアスやProxyCommand・ProxyJumpを使う構成も、最終的に解決されるHostNameが一致すれば許可されます。
実際の解決結果は、手元でssh -Gを実行すると確認できます。次はOpenSSH 10.2p1(macOS同梱)で、先頭の設定をそのまま別ファイルに書いて実行した出力です(接続は発生しません)。
Host devbox1
HostName box1.devboxes.example.com
ProxyJump bastion.example.comssh -F ./ssh_config -G devbox1 | grep -i -E "^(hostname|proxyjump|port) "hostname box1.devboxes.example.com
port 22
proxyjump bastion.example.comdevbox1というエイリアスで接続しても、判定にはその解決結果のhostnameが使われます。したがって*.devboxes.example.comに一致して許可されます。逆に、エイリアス名のdevbox1を許可リストに書いても、解決後のホスト名と一致しないので効きません。許可パターンを決める前に、ユーザーが使う接続名でssh -Gを回し、hostnameの行を集めておくと書き漏れを防げます。
接続先の判定は手元、接続後の統制はリモート
SSHセッションでは、managed settingsを読む場所が段階で変わります。
どの端末のmanaged settingsが効くか
接続先を選ぶとき
Desktopアプリが動いている端末のmanaged settingsを読みます。sshConfigs・sshHostAllowlist・disableDesktopLocalSessionsは、いずれもここから読まれます。
接続したあと
セッションは、リモートホスト上のmanaged settingsファイルを読みます。Claude Codeとしての統制は、こちらに置いたものが効きます。
接続後のセッションは、リモートに置いたmanaged settingsの権限ルールや、availableModelsのようなモデル制限に従います。モデル制限は、Desktopのセッションでもターミナルと同じように適用されます。
つまり、リモートの開発VMに厳しいポリシーを配っても、そのVMへ誰が接続できるかは変わりません。接続先の制限は手元の端末に、セッション内の統制はリモートに、と配る場所を分けます。
Desktopのセッションには、SSH以外にも種類があり、managed settingsの届き先がそれぞれ違います。
- この端末のローカルセッション: 端末に置いたmanaged settingsファイルが適用されます。管理コンソールから配信した設定も、Anthropic APIを使うセッションで対象のログインやキーを使っていれば届きます
- クラウドセッション: サーバー側で管理される設定(server-managed settings)を受け取ります。端末に置いたファイルは届きません。Anthropic管理のVMで動くためです
- SSHセッション: リモートホストのmanaged settingsファイルを読みます
SSH接続先の制限を端末のファイルに書き、リモートのファイルには別の統制を書く、という二重の配布になる点が、他の種類との違いです。
接続先の側にも前提があります。リモートマシンはLinuxかmacOSで、初回の接続時にDesktopがClaude Codeをリモートへ自動でインストールします。個人用のスキルも、手元ではなくリモートのホームディレクトリにある~/.claude/skills/から読まれます。許可ホストを決めるときは、接続先のこの条件も合わせて見ます。
接続後のSSHセッションでも、権限モード・コネクタ・プラグイン・MCPサーバーが使えます。ただしclaude.aiのコネクタは、Desktopが利用者ごとにClaude Codeへ直接渡します。そのため、リモートのmanaged-mcp.jsonなどMCPの設定ではこれらを止められません。コネクタを統制したいときは、組織側のコネクタのツール制御を使います。「接続後の統制はリモート」という原則の例外です。
sshConfigsと組み合わせる — 候補を配り、到達先を絞る
接続先の候補を最初から配りたいときは、sshConfigsを使います。ユーザーの環境ドロップダウンに接続が自動で並びます。id・name・sshHostが必須で、sshPortとsshIdentityFileは任意です。
{
"sshConfigs": [
{
"id": "shared-dev-vm",
"name": "Shared Dev VM",
"sshHost": "user@dev.example.com",
"sshPort": 22,
"sshIdentityFile": "~/.ssh/id_ed25519"
}
]
}managed settingsで配った接続は、ユーザーが選べるだけで、編集も削除もできません。ただしsshConfigsは、ユーザー自身が~/.claude/settings.jsonに書ける設定でもあります。アプリのダイアログから追加した接続は、そこに保存される仕組みです。つまり、sshConfigsだけでは接続先を制限できません。制限の役目はsshHostAllowlistが担います。
3つの設定キーの役割は次のとおりです。
| 設定キー | 書ける場所 | 役割 |
|---|---|---|
sshConfigs | 書ける場所managed / ユーザー(自分のsettings.json) | 役割環境ドロップダウンに接続先候補を追加する |
sshHostAllowlist | 書ける場所managedのみ | 役割接続できるホストのパターンを制限する(空配列でSSH自体を無効化) |
disableDesktopLocalSessions | 書ける場所managedのみ | 役割端末上のローカルセッションを止め、SSHやクラウドだけを残す |
disableDesktopLocalSessionsは、値がJSONの真偽値trueのときだけ有効です。文字列の"true"や1は無視され、警告がログに残ります。Claude Desktop v1.37937.0以降が必要で、ターミナルのCLIはこのキーを読みません。
有効にした端末では、環境ドロップダウンのLocalが灰色になって選べなくなり、SSH接続が設定されていれば、新規セッションは最初のSSH接続を既定にします。既存のローカルセッションは一覧に残りますが、続きの操作はできません。同じ端末へのSSH接続も拒否されます。
灰色のLocalには、組織が無効にした旨のツールチップが付きます。Windowsでは、WSLの項目も同じように灰色になります。WSLの可否は別のポリシーで決まります。既存のローカルセッションを続けようとすると、この端末ではローカルセッションを使えないという趣旨のメッセージが出ます。
ローカルを止めると、開発者はSSHかクラウドで作業することになります。そのときの到達先を絞る部品がsshHostAllowlistで、配布側はsshConfigsで最初の接続を用意しておく組み合わせです。拒否された端末に出る画面の違いや配布の要件は、disableWslSessionsでClaude Code DesktopのWSLを組織展開するでも扱っています。
配布前の確認とつまずき
配る前に、次の3点を見ます。
- ワイルドカードが広すぎないか:
*.example.comと書くと、example.com自体と配下のサブドメインがすべて対象です。他部門が管理するサブドメインまで入ります sshConfigsの接続先が許可パターンに入っているか: 配ったsshHostが解決後に許可パターンへ一致しなければ、その接続には入れない想定になります。候補を配る側と許可する側は、同じ表で管理すると食い違いません- SSH経由で開発している人への周知: 空配列は影響が大きく、既存の作業フローを止めます
つまずきやすい点は、次の3つです。
- ユーザー設定に書いた:
~/.claude/settings.jsonや.claude/settings.jsonに書いても無視されます。managed settingsにだけ書きます - エイリアス名を書いた: 判定は解決後の
HostNameです。短いエイリアスではなく、実際のホスト名を書きます - リモート側に配った: 接続先の許可判定は、手元の端末のmanaged settingsを見ます。リモートのVMに配っても、そこへの接続は止まりません
まとめ
許可リストは、Desktopアプリの接続先を絞る入口の制御で、CLI・IDE拡張・Bashツールのsshには届きません。判定はssh -Gで解決した後のHostNameで行われるので、パターンを決める前に実際の解決結果を集めておくと、書き漏れが減ります。