Documentation

How it works

The switchboard model - what happens on the wire between the moment an agent boots and the moment your terminal opens.

The analogy#

Think of a hotel switchboard.

  • The hidden machine is a guest with no direct phone number.
  • kino-agent is that guest ringing the front desk: “I’m in room box-1, keep this line open, I’ll wait.”
  • kino-relay is the switchboard. It cannot hear the calls — they are encrypted — it only plugs one line into another.
  • Kino SSH Manager is you ringing the hotel: “connect me to room box-1.”
  • Kino Cloud is the pass office: it issues the credentials that say who may use the switchboard at all.

One line to remember: control mints, relay checks, agent and manager carry.

What happens when you click Connect#

you                     relay                        agent
(manager)          (public server)              (hidden machine)
   │                     │                            │
   │                     │   ① agent dialed OUT       │
   │                     │◄───── earlier, at boot ────┤  "I'm box-1,
   │                     │      and stays parked      │   I'll wait here"
   │                     │                            │
   │ ② "box-1 please" ──►│                            │
   │                     │ ③ "wake up, session abc"──►│  (down the
   │                     │                            │   parked line)
   │                     │                            │ ④ agent connects to
   │                     │◄── ⑤ new line for "abc" ───┤   its own sshd
   │                     │                            │   (127.0.0.1:22)
   │◄═══ ⑥ relay plugs your line into the agent's ═══►│
   │                     │                            │
   │  ⑦ normal SSH runs through the pipe - encrypted end to end.
   │     The relay carries scrambled bytes it cannot read.

Step ① is the whole trick: the agent connected outward long before you needed it, so the firewall was never in the way. Steps ②–⑥ take well under a second.

The same thing, as endpoints#

The relay exposes exactly three WebSocket routes plus a health check:

Route Who dials it What it is
GET /healthz monitors, Kino Cloud Liveness. Returns ok.
GET /ws/control?agent_id=<id> the agent The parked line. The agent registers and waits for new_connection messages. Kept alive with 30-second pings.
GET /ws/manager/request?agent_id=<id> the manager “Reach this agent.” The relay notifies the agent and waits up to 10 seconds for it to dial back.
GET /ws/agent/data?session_id=<id> the agent The return data socket for one session. The relay hands it to the waiting manager and bridges the two.

Every session gets a fresh data socket and a fresh relay-generated session_id. The control channel is never used to carry SSH bytes.

Relay discovery#

Without discovery you tell both sides which relay to use. With it, they work it out themselves:

  1. A relay operator enrolls their relay: the relay starts with a one-time code, registers itself, and receives the controller’s public key. The controller health-checks it every minute. See Relay → Enrolling.
  2. The agent starts with --control-url instead of a fixed relay. It fetches the relay list (returned best-first), latency-races the top few, parks on the fastest healthy one, and reports where it parked. Every reconnect re-picks, so an agent migrates by itself when its relay dies or a better one appears.
  3. The manager asks “where is machine X parked?” at connect time and dials that relay. A saved relay URL acts as a fallback if the controller is unreachable.

Because relays only ever hold the public half of the signing key, a relay can verify a credential but never forge one. That is what makes a pool of community-run relays possible without trusting the operators.

Who sees what#

Your SSH password / key Your terminal session What it does know
manager Yes — it is your app; secrets live in its local encrypted vault Yes — it is your screen Everything. It is yours.
agent No No — bytes pass through encrypted That someone connected
relay No No Who talked to whom, and when. Metadata only.
control No No — it is not in the data path at all Which accounts and machines exist; which credentials were issued

Your SSH password or key is checked by the target machine’s own sshd, exactly as if you had connected directly. The relay being compromised does not leak your credentials or your session — the worst it can do is refuse to connect you, or lie about which backend you reached.

That last one is handled too: the manager pins each agent host’s SSH fingerprint, keyed by agent id, the same way OpenSSH’s known_hosts catches a swapped server.

A relay with no auth is an open door

A relay started with neither RELAY_TOKEN nor a controller public key runs open, and says so loudly at startup. Anyone who can reach it and knows an agent_id can open an SSH transport to that machine’s sshd — where that machine’s own authentication becomes the only gate. Fine for a firewalled lab. Never for anything public.

Where the trust actually sits#

  • You trust your own machine. The vault, the master password, the SSH keys.
  • You trust the target’s sshd. As you always did.
  • You do not have to trust the relay. Verification is asymmetric and the data is end-to-end encrypted.
  • You trust Kino Cloud to say honestly where an agent is. It could point you at a relay of its choosing. It still cannot read the session — and the host-key pin catches a substituted backend, which is the attack that would actually matter.

That last item is the one worth thinking about, and the answer is the same one OpenSSH has always given: verify the host key. The manager pins it per machine and warns you the moment it changes, so being routed somewhere unexpected fails loudly rather than silently.

If you would also rather the route itself be yours, run your own relay — it takes about ten minutes and changes nothing else.

Next#