コンテンツにスキップ

リモートコントロールとモバイル

Control Center はデスクトップアプリですが、それが追跡する作業は、デスクを離れたとたんに止まるものではありません。リモートコントロールは、あなたのスマートフォンと cc_server をペアリングします。使用するのは、remote.usectrl.dev にあるコンパニオンアプリ Remote です。これにより、外出先からフリートを追いかけられます。メッセージやチケットを読み、エージェントに返信し、ニュースフィードをトリアージできます。その間、サーバー上にある音声、文字起こし、ソースコード、資格情報がサーバーから出ることはありません。

読み取り中心の、デッキのコンパニオンだと考えてください。フルのデスクトップクライアントを置き換えるものではありません。

スマートフォンは WebSocket 経由で cc_server に到達します。直接接続(ループバック、LAN、tailnet、または wss://)か、密封されたフレームをリレーするシグナリングブローカー上の招待制のルームです。ピアツーピアのデータチャネルはありません。

ペアリングされたスマートフォンが到達できるのは、サーバーのサーフェスのうち、意図的に絞り込まれた小さな一部分です。

  • 読み取り: チケット、エージェント、スペースとそのメッセージ、およびニュースフィード
  • 返信: スペースへのメッセージ送信、チケットの更新または割り当て、記事を既読または保存済みにする
  • プレイブックの実行: 保存済みのプランテンプレートをそのパラメーターでインスタンス化します。これはプランを_提案_するだけで、フルクライアントの Plan Studio でオペレーターが承認するまで、何も実行も消費もされません
  • ワークスペースの切り替え: スマートフォン自身のピッカーから行います

ほぼこれで全部です。スマートフォンは、フルクライアントよりも低い権限のプリンシパルです。プロセスの起動、LLM 予算の消費、GitHub へのプッシュ、ワークスペースの作成はできません。これが単なる意図ではなく実際に強制される仕組みはアクセスモデルを参照してください。

接続はブローカー経由のリレーに乗ります。サーバーは wss:// ブローカー上の 1 つの招待制のルームにそのオーナーとして参加し、ペアリングされたすべてのクライアント(デスクトップ、Web、スマートフォン)が、期限付きの入室トークンを使って同じルームに参加します。3 つの要素が組み合わさります。

要素 役割
Remote(スマートフォンアプリ) コンパニオンの Web アプリ。デフォルトでは remote.usectrl.dev でホストされ、セルフホストも可能です。ブラウザーで読み込まれ、ペアリングの記録を IndexedDB に保持します。
リレーブローカー ステートレスな wss:// リレー(cc_signaling_server)で、N 者間のルームをホストします。運ぶのは不透明なフレームだけです。すべてのペイロードはスマートフォンとサーバーの間でエンドツーエンドに密封されるため、ブローカーがアプリのデータやペアリングの秘密を目にすることはなく、転送するものを解釈することもありません。
cc_server ルームのオーナー。他のすべてのクライアントが使うのと同じディスパッチャーを通じて、スマートフォンからの呼び出しに応答します。

ペアリングオファーは、サーバーへのすべての経路(LAN、tailnet、公開 wss://、リレー)とその識別フィンガープリントを列挙した接続記述子を運びます。スマートフォンのリゾルバーは到達可能な最良の経路を選び、初回接続時にフィンガープリントをピン留めします(TOFU)。リレーは、直接経路が存在しない場合でも接続性を保証しつつ、そのトラフィックを読むことは決してできません。

ペアリングはアプリから発行され、ディープリンクとして届けられます。手順についてはデバイスをペアリングを参照してください。ここで重要なのはその構造です。

https://<pwa-host>/#<payload>

ペイロードは URL のフラグメント、つまり # の後ろの、ブラウザーがサーバーに送ることのない部分に乗るため、PWA の HTTPS ホストがそれを目にすることはありません。ペイロードには、スマートフォンがサーバーに到達し、自分が誰であるかを証明するために必要なものがすべて含まれます。接続記述子(すべての経路と識別フィンガープリント)、新たに発行されたデバイス id、32 バイトの事前共有キー、そして有効期限のスタンプです。スマートフォンはそれをデコードし、ペアリングの記録をローカルに保存し、フラグメントを取り除いて秘密が URL から消えるようにします。

ペイロードの形は 2 つあり、それらは互換性がありません。アプリ内のペアリングパネルから発行されるスマートフォン用 QR は、上記の v2 PairingPayload で、Remote PWA ホストを指しています。cc_server pair --client-url は、Web クライアント専用の、異なる古い v1 リンク({s, i, k} — サーバー URL、デバイス id、キー)を発行します。

両者は有効期間も異なり、これを取り違えるのはたやすいことです。

発行元 資格情報の有効期限
アプリ内のペアリングパネル(pairing.mint) 常に 30 日
コマンドラインの cc_server pair なし — 資格情報は失効しません

ペアリングされたデバイスは認証済みですが信頼されていません。承認された(あるいは漏洩した)ペアリングがサーバーの完全な制御につながることを、いくつかの独立したゲートが防ぎます。

1. 境界はペアリングではなくメンバーシップ

「1. 境界はペアリングではなくメンバーシップ」というセクション

有効なペアリングキーが証明するのは、_どのデバイス_であるかということだけです。何を読み、何を変更できるかはワークスペースロールによって決まり、これは呼び出しのたびに再解決されます。また、リポジトリの内容を公開するものについては、リポジトリ単位の許可によっても決まります。完全に有効なキーを保持していても、指定されたワークスペースのメンバーではないユーザーに属するデバイスは、「Not a member of this workspace」で拒否されます。

ロールの下限は、操作が自ら宣言しない限り、その操作の種類から導かれます。読み取りには guest、変更には member、破壊的操作には admin が必要です。

ロールチェックに加えて、スマートフォンのセッションは、デスクトップや Web のセッションよりも低いケイパビリティを持ちます。フルクライアント専用と宣言された操作は、その背後にいるユーザーがどれほど特権を持っていても、ハンドラーが実行される前にスマートフォンに対して拒否されます。デバイスペアリングの発行、一覧表示、名前変更、失効。トンネル接続の読み取りと設定。サーバーのバックアップとワークスペースのエクスポート/インポート。プロセスの検出と停止。アダプターのプローブ。サーバー設定。SSO 管理。フリート制御。そして実行中のエージェントの引き継ぎまたは返却です。

特に MCP ツールサーフェス(tools/call)では、スマートフォンが呼び出せるツールをデフォルト拒否の許可リストが管理します。リストにないものは、実行される前に拒否されます。このリストは読み取りと観察が中心で、それに加えてローカル専用の書き込みがいくつかあります。メッセージ、チケットの更新、記事のフラグなどで、LLM 予算を消費せず、プロセスを起動せず、外部システムに触れません。

例えば、拒否されるものは次のとおりです。エージェントへの相談、AI レビューの開始、エージェントの停止、レビューの GitHub への公開、エージェントの採用または解雇、ワークスペースの作成。

サーバーは「現在のワークスペース」を保持しません。設計上ステートレスです。ワークスペーススコープのすべての呼び出しは、引数で対象の workspace_id を指定しなければならず、それが欠けている場合、あるいはサーバーに登録されていないワークスペースを指定している場合、ディスパッチャーは — 何かがデータベースを開く前に — その呼び出しを即座に拒否します。したがってスマートフォンが別のクライアントのスコープを継承したり、そこへ流れ込んだりすることは決してできませんし、外部のワークスペースを指定しても意味がありません。ゲート 1 のメンバーシップチェックが依然として適用されるからです。これは、プロダクトの他の部分が強制しているのと同じワークスペースの分離の不変条件です。

5. 事前共有キーを鍵とするエンドツーエンド密封フレーム

「5. 事前共有キーを鍵とするエンドツーエンド密封フレーム」というセクション

スマートフォンとサーバーの間のすべてのフレームは、ペアリングキーで密封されます。入室トークンはクライアントをルームに入れるだけで、何も復号しません。ブローカーは暗号文をリレーし、キーを目にすることはありません。失効したデバイスは、自分の資格情報がすでに消えていることに気づきます。つまり、再接続時にはフェイルクローズします。

アプリが発行した資格情報は 30 日に期限付けられています。それを過ぎると接続ゲートがそれを拒否し、スマートフォンは再度ペアリングする必要があります。失効は即時です。サーバーはデバイステーブルを監視し、失効したデバイスの開いているセッションを、次回の接続を待つことなく数秒以内に切断します。

スライディングウィンドウ方式のリミッターが、リモートのツールトラフィックを毎分 120 呼び出しに制限し、変更系の動詞にはより厳しい毎分 30 のサブ上限を課します。予算はセッションではなくプリンシパルに属します。あなたの 3 台のデバイスは 1 つの許容量から消費するため、乗っ取られたクライアントがセッションを増やして余裕を稼ぐことはできず、1 人の騒がしいメンバーが他のメンバーを枯渇させることもできません。

リレーブローカーは意図的に単純です。ルームをホストし、密封されたフレームを転送し、アカウントもアプリのデータもキーも保持しません。ルームは招待制で一時的です。アプリのデータ、音声、文字起こし、ソース、資格情報はすべてサーバー上にとどまります。

ペアリングが済むと、スマートフォンは通知フレームとしてライブ更新を受け取ります。新しいエージェントのメッセージ、自分に割り当てられたチケット、ステータスの変更などで、デスクトップ自身の通知を反映したものです。サーバーはそれらのフレームを接続中のすべてのセッションにブロードキャストし、ワークスペースのフィルターはクライアント側で適用されるため、表示される内容は今見ているワークスペースに限定されます。

サーフェス 表示内容
設定 → 自分 → 自分のデバイス(/workspaces/:workspaceId/settings/you/devices) ライブステータス付きのペアリング済みクライアント、および新しいクライアントをペアリング(Web ブラウザー、デスクトップアプリ、スマートフォン)と失効

同じパネルは、スマートフォンだけでなく、2 つ目のブラウザーやデスクトップアプリ用のペアリングも発行します。手順は同じで、異なるのはディープリンクだけです。