Claude Media
sshHostAllowlistでClaude Code DesktopのSSH接続先を制限する

sshHostAllowlistでClaude Code DesktopのSSH接続先を制限する

sshHostAllowlistはClaude Code DesktopのSSHセッションを許可ホストだけに絞るmanaged設定です。書き方とパターンの一致規則、CLIには効かない適用範囲をまとめます。

sshHostAllowlistとは何か

sshHostAllowlistは、Claude Code DesktopのSSHセッションが接続できるホストを、管理者が許可したパターンだけに絞るmanaged設定です。ユーザーが環境ドロップダウンから任意のホストへSSH接続することを防ぎ、あらかじめ承認した踏み台サーバーや開発用VM群だけに接続先を限定します。空配列を設定すると、SSHセッション機能そのものを組織全体で無効化できます。

DesktopのSSHセッションは、接続先のマシン上でファイル編集やコマンド実行をそのまま行える機能です。接続先が社内の管理対象サーバーだけに限られていれば問題になりませんが、ユーザーが任意のホストを自由に追加できる状態だと、管理外のインフラへコードやコマンド実行の権限をそのまま渡してしまう経路になります。sshHostAllowlistは、その接続先の範囲そのものを組織のポリシーとして固定する役割を担います。

SSH接続の基本的な使い方(接続の追加方法や認証まわり)はClaude Code SSH接続ガイドにまとめてあります。本記事は、そこで軽く触れているだけのsshHostAllowlistの設定手順とパターンの一致規則を、管理者向けに掘り下げます。

この設定が効く範囲 — CLIやBashツールには届かない

制限が及ぶのはDesktopアプリが自分で開くSSHセッションの接続先選択だけです。Bashツールから実行する生のsshコマンドは対象外なので、Claude Codeのセッション内でssh some-hostを直接叩けば許可リストの外へも到達できてしまいます。ネットワーク境界そのものを固めたいなら、この設定だけに頼らず組織のネットワーク制御やゼロトラスト側の仕組みと組み合わせる必要があります。sshHostAllowlistが制御しているのは、あくまでDesktopアプリがどのホストへの接続を提示するかという入口です。

設定手順 — managed settingsへの追加

sshHostAllowlistはmanaged settingsファイルにしか書けません。ユーザー設定やプロジェクト設定に同じキーを書いても無視されます。まずは許可するホストのパターンを配列で用意します。

{
  "sshHostAllowlist": ["*.devboxes.example.com", "bastion.example.com"]
}

この例では、devboxes.example.comのサブドメインすべてと、bastion.example.comという1台の踏み台ホストへの接続を許可しています。この2パターンに一致しないホストは、ユーザーが環境ドロップダウンで新規のSSH接続を追加しようとしても選択肢に出ません。

配列を空にすると挙動が変わります。"sshHostAllowlist": []と書いた場合、個別のホストを許可するのではなく、SSHセッション機能そのものを無効化します。段階的に許可ホストを絞り込むつもりで一時的に空配列を置くと、意図せずSSH機能全体を止めてしまうので注意してください。

パターンの書き方とマッチング挙動

パターンの判定には3つの型があります。

  • *: 任意のホストに一致する(実質的に制限なし)
  • *.example.com: example.com自体と、その配下のすべてのサブドメインに一致する
  • それ以外の文字列: ホスト名との完全一致

パターンは大文字小文字を区別しません。Bastion.Example.comと書いてもbastion.example.comにマッチします。

見落としやすいのは、判定対象になるホスト名です。ユーザーが入力したSSH Hostの文字列そのものではなく、~/.ssh/configを解決したあとのHostNameに対してssh -G相当の解決を行い、その結果と許可パターンを突き合わせます。したがって、ユーザーの~/.ssh/configに次のようなエイリアスがあっても問題なく動きます。

Host devbox1
  HostName box1.devboxes.example.com
  ProxyJump bastion.example.com

devbox1という短いエイリアスで接続しようとしても、Desktopは解決後のbox1.devboxes.example.comを見て判定するため、*.devboxes.example.comパターンに一致すれば許可されます。ProxyCommandProxyJumpを経由する構成でも同様に、最終的に解決されるHostNameだけが判定対象です。逆に言えば、エイリアス名をそのまま許可リストに書いても、解決後のホスト名と一致しなければ意味がありません。

sshConfigsで配布した接続と組み合わせる

管理者が接続先を制限するだけでなく、あらかじめ接続候補を配りたい場合はsshConfigsと組み合わせます。sshConfigsはユーザーの環境ドロップダウンに接続先を自動で追加する設定で、idnamesshHostが必須、sshPortsshIdentityFileは任意です。

{
  "sshConfigs": [
    {
      "id": "shared-dev-vm",
      "name": "Shared Dev VM",
      "sshHost": "user@dev.example.com",
      "sshPort": 22,
      "sshIdentityFile": "~/.ssh/id_ed25519"
    }
  ]
}

sshConfigsで配った接続はmanaged扱いになり、ユーザーは選べても編集・削除はできません。ただしsshConfigsはユーザー自身が自分の~/.claude/settings.jsonに追加することもできる設定なので、sshHostAllowlistと役割が違います。3つの設定キーが担う範囲は次のとおりです。

設定キー書ける場所役割
sshConfigs書ける場所managed / ユーザー(自分のsettings.json)役割環境ドロップダウンに接続先候補を追加する
sshHostAllowlist書ける場所managedのみ役割接続できるホストのパターンを制限する(空配列でSSH自体を無効化)
disableDesktopLocalSessions書ける場所managedのみ役割端末上のローカルセッションを止め、SSHやクラウドだけを残す

disableDesktopLocalSessionstrueにした端末では、環境ドロップダウンのLocalが選べなくなり、新規セッションは設定済みのSSH接続を既定にします。この構成を取る組織ほど、ユーザーが実際に到達できるホストをsshHostAllowlistで絞る必要性が高くなります。ローカルセッションを止めた上で接続先を無制限にすると、結局どのホストにでもSSHできてしまい、制限の意味が薄れるためです。disableDesktopLocalSessions自体の配布バージョン要件や、拒否された端末に出る画面の違いはdisableWslSessionsでClaude Code DesktopのWSLを組織展開するの該当節で詳しく扱っています。

配布前に確認しておくこと

managed settingsを配る前に、次の4点を確認しておくとやり直しが減ります。

  • ワイルドカードの粒度が広すぎないか: *.example.comのように広く許可すると、他部門が管理する予期しないサブドメインまで許可対象に含まれます。必要な範囲まで具体的に絞ります
  • 配布したsshConfigsの接続先自身が許可されているか: sshConfigsで接続候補を配っても、そのsshHostsshHostAllowlistのパターンに含まれていなければ、ユーザーは候補を選べても接続時に弾かれます
  • 既存ユーザーへの影響を洗い出したか: 空配列でSSHセッションごと止める場合、すでにSSH経由の開発フローに依存しているユーザーへの周知が抜けやすいところです
  • managed settingsが対象端末に届いているか: ファイル配布か管理コンソール経由かで反映のタイミングが変わるため、配布後は実際の環境ドロップダウンで許可ホストの一覧を確認します

接続判定と接続後のポリシーは読み込み元が違う

SSHセッションでは、2種類のmanaged settingsが別々のタイミングで働きます。この違いを取り違えると、想定どおりに制限がかからない事故につながります。

接続先を選ぶ段階で見られるのは、常に手元のマシン(Desktopアプリが動いている端末)のmanaged settingsです。sshConfigssshHostAllowlistdisableDesktopLocalSessionsはいずれもここから読まれます。接続先の候補一覧や、どのホストへ接続できるかは、リモート側に何を配ろうと変わりません。

いったん接続が確立したあとは話が変わります。権限モードやモデル制限のような、セッションの中身を統制する設定は、接続先のリモートホストにあるmanaged settingsファイルが適用されます。つまり、リモートのdevVMに厳しい権限ポリシーを配っても、それだけでは「そのVMへ誰が接続できるか」は制限できません。接続先の制限は手元の端末側、セッション内の統制はリモート側と、配る場所を分けて設計する必要があります。

よくあるつまずき

管理者側でこの設定を配るときに起きやすい取り違えを挙げます。

  • ユーザー設定に書いても効かない: sshHostAllowlistはmanaged settingsからしか読まれません。ユーザーが自分の~/.claude/settings.jsonに同じキーを書いても無視されます
  • 空配列のつもりが全体無効化になる: 許可ホストを絞り込む途中で一時的に[]を置くと、個別ホストの制限ではなくSSHセッション機能そのものが止まります
  • CLIも制限されると思い込む: この設定を読むのはDesktopアプリだけです。ターミナルから直接claudeを使う運用やIDE拡張には一切影響しません
  • Bashツールのsshコマンドまで止まると思い込む: セッション内で実行する生のsshコマンドは対象外です。ネットワーク境界を固めたい場合は組織のネットワーク制御を別途組み合わせます
  • エイリアス名を許可リストに書いてしまう: 判定対象は~/.ssh/config解決後のHostNameです。ユーザーが使う短いエイリアスではなく、実際の接続先ホスト名をパターンに含めます
  • リモート側に配れば接続先も制限できると思い込む: 接続先の許可判定は常に手元の端末のmanaged settingsを見ます。リモートのdevVM側にどれだけ厳しい設定を配っても、そこへの接続そのものは制限されません

まとめ

sshHostAllowlistは、Claude Code DesktopのSSHセッションが接続できるホストを、managed settingsで指定したパターンだけに絞る設定です。ワイルドカードで範囲を許可でき、空配列にすればSSHセッション自体を無効化できます。判定はユーザーが入力したホスト名ではなく、~/.ssh/configを解決した後のホスト名に対して行われるため、エイリアスやProxyJumpを使った構成でも意図どおりに機能します。効くのはDesktopアプリの接続先選択だけで、CLI・IDE拡張・Bashツール経由のsshコマンドには及ばないので、ネットワーク境界そのものを固めたい組織は別のネットワーク制御と併用してください。接続先を配布するsshConfigsやローカルセッションを止めるdisableDesktopLocalSessionsと組み合わせて設計すると、許可ホスト以外への接続経路を実質的に塞げます。配る場所を手元の端末側とリモート側で混同しないことが、想定どおりに制限をかける最初の一歩です。

この記事を共有:XはてブLinkedIn