Files
VoiceStudio/backend/worker/inbound/__init__.py
T
velixio ef671de36e feat(workers): let a panel dial the GPU machine, so more than one person can use it
Remote workers connect outbound: the node dials the control plane, spends an
enrollment token, pins a certificate. That stays the default and is unchanged.

It is also structurally 1:1 — a worker process holds one endpoint, one pinned
certificate and one worker id — so a second person wanting the same GPU box has
to get shell access to it, repoint the start script at their own address and
restart, which disconnects whoever was using it. Sharing a GPU requires root on
it and evicts the incumbent, and no amount of UI work fixes that, because the
constraint is the shape of the connection.

This adds the other arrangement: the node listens, and any panel holding a key
connects to it, concurrently, with no shell access to the machine.

  * NodeService mirrors WorkerService. Transport roles invert; message roles do
    not — the node still sends WorkerMessage and the panel still sends
    ServerMessage, so every state machine on both sides is untouched. Register
    folds into the stream as the first exchange and reuses the existing
    request/response messages rather than growing parallel ones.
  * Keys are per panel, not per node. Revoking one person leaves everyone else
    connected; a shared key would be revoked by nobody and leave no record of
    who used it. Stored hashed, compared in constant time against every key so
    the reply time is not an oracle, and the plaintext exists exactly once.
  * Failed authentication is throttled per source address, so one stale
    bookmark cannot lock out a different panel.
  * A connection log records every attach, refusal and disconnect, and any
    session can be kicked. That is what replaces per-job approval, which would
    make a shared GPU unusable and train people to click yes.
  * Artifacts invert too: the panel pushes inputs before assigning, and fetches
    results after. The node stages both under one contained directory and
    trusts no id or filename off the wire.

Runs in plaintext by deliberate decision, recorded with its accepted risk in
docs/adr/inbound-node-mode.md, and scoped there to LAN and self-hosted use —
never a fleet transport, which goal_v2 B2/B5.2 still require to dial out.

Off by default, and bound to 127.0.0.1 until someone explicitly widens it.
2026-08-11 22:06:12 +05:30

21 lines
1.0 KiB
Python

"""Inbound mode: the control plane dials the node, instead of the reverse.
Default remote-worker mode is outbound — the node dials the control plane, which
is what a fleet needs (goal_v2.md B2/B5.2) and what works behind NAT with no
open ports. This package is the opposite arrangement, for two cases outbound
cannot serve:
* the node is reachable but the panel is not (the panel is the laptop);
* several people want to share one GPU box.
The second is the reason this exists. Outbound is structurally 1:1 — a worker
process holds exactly one endpoint, one pinned certificate and one worker id
(``agent.py``), so "let a colleague use the 4090" means SSHing into the box,
repointing it and restarting, which disconnects whoever had it. Inbound is 1:N
by construction: the node listens once and any panel holding a key connects,
concurrently, without shell access to the machine.
See ``docs/adr/inbound-node-mode.md`` for the security posture, which is
deliberately weaker than outbound's and is scoped to LAN / self-hosted use.
"""