Salta ai contenuti

Controllo remoto e mobile

Control Center è un’app desktop, ma il lavoro che segue non si ferma quando ti allontani dalla scrivania. Il controllo remoto associa il tuo telefono al tuo cc_server, tramite Remote, l’app complementare su remote.usectrl.dev, così puoi seguire la flotta da lì: leggere messaggi e ticket, rispondere a un agente, gestire le tue notizie, senza che l’audio, la trascrizione, il codice sorgente o le credenziali che risiedono sul server lo lascino mai.

Consideralo un compagno prevalentemente di lettura del deck. Non intende sostituire il client desktop completo.

Il telefono raggiunge cc_server tramite un WebSocket: una connessione diretta (loopback, LAN, tailnet o wss://) oppure una stanza ad accesso su invito su un broker di segnalazione che inoltra frame sigillati. Non esiste alcun canale dati peer-to-peer.

Il telefono associato raggiunge una porzione piccola e intenzionale della superficie del server:

  • Leggere ticket, agenti, spazi e i relativi messaggi e le tue notizie
  • Rispondere: inviare un messaggio in uno spazio, aggiornare o assegnare un ticket, contrassegnare un articolo come letto o salvato
  • Avviare un playbook: istanziare un modello di piano salvato con i suoi parametri. Questo si limita a proporre un piano; nulla viene eseguito o speso finché un operatore non lo approva in Plan Studio su un client completo
  • Cambiare spazio di lavoro, dal selettore del telefono stesso

È quasi tutto quello che può fare. Un telefono è un principal con privilegi inferiori rispetto a un client completo. Non può avviare processi, consumare budget LLM, eseguire push su GitHub o creare spazi di lavoro. Vedi il modello di accesso per come questo venga applicato, e non solo inteso.

La connessione viaggia su un relay intermediato da un broker: il server entra in una stanza ad accesso su invito su un broker wss:// come proprietario e ogni client associato — desktop, web, telefono — entra nella stessa stanza con un token di ammissione a scadenza. Tre pezzi concorrono:

Pezzo Ruolo
Remote (app per telefono) L’app web complementare, ospitata per impostazione predefinita su remote.usectrl.dev, oppure self-hosted. Si carica in un browser e conserva il record di associazione in IndexedDB.
Broker di relay Un relay wss:// senza stato (cc_signaling_server) che ospita stanze a N vie. Trasporta solo frame opachi: ogni payload è sigillato end-to-end tra telefono e server, quindi il broker non vede mai i dati dell’app né il segreto di associazione e non interpreta mai ciò che inoltra.
cc_server Il proprietario della stanza. Risponde alle chiamate del telefono attraverso lo stesso dispatcher usato da ogni altro client.

Un’offerta di associazione contiene un descrittore di connessione che elenca ogni percorso verso il server (LAN, tailnet, wss:// pubblico, relay) insieme alla sua impronta di identità. Il resolver del telefono sceglie il percorso raggiungibile migliore e fissa l’impronta alla prima connessione (TOFU); il relay garantisce la connettività anche quando non esiste alcun percorso diretto, senza poter mai leggere il traffico.

L’associazione viene generata dall’app e consegnata come link diretto; vedi Associa un dispositivo per la procedura. Qui conta l’anatomia.

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

Il payload viaggia nel frammento dell’URL, la parte dopo # che i browser non inviano mai al server, quindi l’host HTTPS della PWA non lo vede mai. Contiene tutto ciò che serve al telefono per raggiungere il server e dimostrare chi è: il descrittore di connessione (ogni percorso più l’impronta di identità), un id del dispositivo appena generato, una chiave precondivisa di 32 byte e un timbro di scadenza. Il telefono lo decodifica, archivia localmente un record di associazione e rimuove il frammento, così il segreto esce dall’URL.

Esistono due forme di payload e non sono intercambiabili. Il QR per telefono generato dal pannello di associazione nell’app è il PairingPayload v2 descritto sopra, puntato all’host della PWA Remote. cc_server pair --client-url emette un link v1 diverso e più vecchio ({s, i, k} — URL del server, id del dispositivo, chiave) destinato solo al client web.

Differiscono anche per durata, cosa su cui è facile sbagliarsi:

Generata da Scadenza della credenziale
Pannello di associazione nell’app (pairing.mint) 30 giorni, sempre
cc_server pair dalla riga di comando Nessuna — la credenziale non scade

Un dispositivo associato è autenticato ma non attendibile. Diversi gate indipendenti impediscono che un’associazione approvata (o trapelata) diventi il pieno controllo del server.

1. L’appartenenza, non l’associazione, è il confine

Sezione intitolata “1. L’appartenenza, non l’associazione, è il confine”

Una chiave di associazione valida dimostra quale dispositivo sei. Ciò che puoi leggere o modificare è deciso dal tuo ruolo nello spazio di lavoro, risolto di nuovo a ogni singola chiamata, e dalle concessioni per repository su tutto ciò che espone contenuto di repository. Un dispositivo con una chiave perfettamente valida ma appartenente a un utente che non è membro dello spazio di lavoro indicato viene rifiutato con «Not a member of this workspace».

La soglia minima di ruolo deriva dal tipo di operazione, a meno che questa non ne dichiari una propria: le letture richiedono guest, le modifiche richiedono member, le operazioni distruttive richiedono admin.

2. Un telefono è un livello di sessione inferiore

Sezione intitolata “2. Un telefono è un livello di sessione inferiore”

Oltre al controllo del ruolo, una sessione da telefono ha capacità inferiori rispetto a una sessione desktop o web. Le operazioni dichiarate esclusive dei client completi vengono rifiutate per un telefono prima che il gestore venga eseguito, indipendentemente da quanto sia privilegiato l’utente dietro di esso: generazione, elenco, rinomina e revoca delle associazioni dei dispositivi; lettura e impostazione della connettività del tunnel; backup del server ed esportazione/importazione degli spazi di lavoro; rilevamento e terminazione dei processi; probe degli adapter; impostazioni del server; amministrazione SSO; controllo della flotta; e presa in carico o riconsegna di un agente in esecuzione.

3. Una lista di autorizzazione degli strumenti che nega per impostazione predefinita

Sezione intitolata “3. Una lista di autorizzazione degli strumenti che nega per impostazione predefinita”

Per la superficie degli strumenti MCP in particolare (tools/call), una lista di autorizzazione che nega per impostazione predefinita stabilisce quali strumenti può invocare il telefono. Tutto ciò che non è elencato viene rifiutato prima di essere eseguito. La lista è sbilanciata verso lettura e osservazione, più una manciata di scritture solo locali — un messaggio, un aggiornamento di ticket, un contrassegno su un articolo — che non consumano budget LLM, non avviano processi e non toccano alcun sistema esterno.

Sono negati, per esempio: consultare un agente, avviare una revisione IA, terminare un agente, pubblicare una revisione su GitHub, assumere o licenziare agenti, creare uno spazio di lavoro.

4. Ambito dello spazio di lavoro per ogni chiamata

Sezione intitolata “4. Ambito dello spazio di lavoro per ogni chiamata”

Il server non conserva alcuno «spazio di lavoro corrente». È senza stato per progettazione: ogni chiamata con ambito di spazio di lavoro deve indicare il workspace_id di destinazione nei propri argomenti e il dispatcher rifiuta la chiamata del tutto quando manca o indica uno spazio di lavoro che il server non ha registrato — prima che qualcosa apra un database. Un telefono non può quindi mai ereditare o scivolare nell’ambito di un altro client, e indicare uno spazio di lavoro estraneo non aiuta, perché il controllo di appartenenza del gate 1 si applica comunque. È lo stesso invariante di isolamento degli spazi di lavoro che il resto del prodotto applica.

5. Frame sigillati end-to-end con la chiave precondivisa

Sezione intitolata “5. Frame sigillati end-to-end con la chiave precondivisa”

Ogni frame tra telefono e server è sigillato con la chiave di associazione; il token di ammissione serve solo a far entrare un client nella stanza, non decifra nulla. Il broker inoltra testo cifrato e non vede mai la chiave. Un dispositivo revocato trova la propria credenziale già rimossa, quindi fallisce in modo restrittivo alla riconnessione.

Una credenziale generata dall’app ha una scadenza di 30 giorni; superata quella, il gate di connessione la rifiuta e il telefono deve essere riassociato. La revoca è immediata: il server osserva la tabella dei dispositivi e chiude le sessioni aperte di un dispositivo revocato entro pochi secondi invece di aspettare la sua connessione successiva.

Un limitatore a finestra scorrevole limita il traffico degli strumenti remoti a 120 chiamate al minuto, con un sotto-limite più stretto di 30 al minuto sui verbi di modifica. Il budget appartiene al principal, non alla sessione: tre tuoi dispositivi attingono a un’unica quota, quindi un client dirottato non può comprarsi margine aprendo più sessioni e un membro rumoroso non può affamare gli altri.

Il broker di relay è deliberatamente stupido: ospita stanze, inoltra frame sigillati e non conserva account, dati dell’app né chiavi. Le stanze sono ad accesso su invito e transitorie. I dati dell’app, l’audio, la trascrizione, il codice sorgente e le credenziali restano tutti sul server.

Una volta associato, il telefono riceve aggiornamenti in tempo reale come frame di notifica — nuovi messaggi degli agenti, ticket assegnati a te, cambi di stato — che rispecchiano le notifiche del desktop. Il server trasmette quei frame a ogni sessione connessa e il filtro dello spazio di lavoro viene applicato lato client, quindi ciò che vedi è limitato allo spazio di lavoro che stai guardando.

Superficie Cosa mostra
Impostazioni → Tu → I tuoi dispositivi (/workspaces/:workspaceId/settings/you/devices) Client associati con stato in tempo reale, più Associa un nuovo client (browser web, app desktop o telefono) e revoca

Lo stesso pannello genera associazioni per un secondo browser o per un’app desktop, non solo per i telefoni: il flusso è identico, cambia solo il link diretto.