Threat model and deployment guidance for lerobot-device-connect. This document covers this package and how it sits in the Device Connect + LeRobot stack. Broker ACLs, portal credential issuance, MCP client policy, and LeRobot core safety live in upstream components unless noted here.
This driver is not a safety-certified robot controller. It forwards observation and motor commands to LeRobot robot implementations (LeKiwi first) and mirrors state for agents over Device Connect.
Do not open a public issue for exploitable security bugs.
- Prefer GitHub private vulnerability reporting once a remote is configured.
- For issues in dependencies, also report to the upstream project when appropriate:
- device-connect /
device-connect-edge - lerobot
- Hugging Face security for LeRobot-specific concerns
- device-connect /
Include: description, reproduction steps, affected version/commit, impact, and suggested mitigation if you have one.
| Shape | Driver runs on | Robot path | Main exposure |
|---|---|---|---|
| Sim / CI | Laptop or CI | SimLeKiwiBridge (no hardware) |
Mesh registration if broker connected; operator confusion with real device_id |
On-robot (local) |
Raspberry Pi on LeKiwi | LeKiwi → Feetech bus + USB cameras |
Serial bus control, camera/mic data, LAN reachability |
Teleop laptop (client) |
Operator PC | LeKiwiClient → ZMQ to lekiwi_host |
Open ZMQ on robot LAN, leader arm USB, keyboard capture |
| Portal / remote | Robot or edge host | Any mode + nats://portal.deviceconnect.dev |
Anyone with mesh credentials can invoke RPCs |
| Component | In this repo? | Notes |
|---|---|---|
LeRobotDeviceDriver RPC/event surface |
Yes | Primary attack surface for mesh callers |
RobotBridge (local / client / sim) |
Yes | Translates RPCs to LeRobot I/O |
TeleopComposer (leader + keyboard) |
Yes | Local USB + input devices; teleop_step RPC |
device_connect_edge.DeviceRuntime |
Dependency | Messaging, credentials, allow_insecure |
lerobot.robots.lekiwi.lekiwi_host |
Dependency | ZMQ cmd/obs on robot; watchdog stops base |
| Feetech motors / omni base / cameras | Hardware + LeRobot | Physical safety boundary |
[Human supervisor] [LLM agent host]
| |
| supervises | MCP / IDE (device-connect-agent-tools)
v v
Device Connect broker (NATS / Zenoh)
portal.deviceconnect.dev OR local lab broker
|
| invoke_device / RPC
v
lerobot-device-connect (this package)
|
+-----------------+------------------+
| |
local: Feetech /dev/tty* client: ZMQ tcp://robot:5555/5556
+ USB cameras (requires lekiwi_host on robot)
| |
v v
LeKiwi hardware (arm + omni base)
Optional teleop path (client mode typical):
[Leader arm USB] [Keyboard on teleop PC]
| |
v v
SO100Leader KeyboardTeleop
\ /
`--> TeleopComposer.compose_action() --> send_action --> ZMQ --> robot
| Asset | Why it matters |
|---|---|
| Physical robot | Arm motion and mobile base velocity can injure people or damage property |
| USB cameras | get_observation_with_cameras exposes JPEG frames over the mesh |
| Portal / NATS credentials | Grant Device Connect membership; invoke RPCs on registered device_id |
| ZMQ cmd socket (5555) | Unauthenticated JSON actions on robot when lekiwi_host binds tcp://*:5555 |
| Feetech serial bus | Direct motor commands in local mode |
| Leader arm calibration | Wrong teleop mapping can cause unexpected follower motion |
| Environment / CLI config | DEVICE_ID, LEROBOT_REMOTE_IP, credential file paths |
- Compromised or mis-prompted agent — repeated
send_action,teleop_step, or camera RPCs (motion spam, exfiltration). - Mesh participant with valid NATS credentials — same RPC surface as MCP without IDE supervision.
- LAN attacker on robot Wi‑Fi — connects to ZMQ ports, scans for open broker, reaches Pi services.
- LAN attacker on teleop LAN — targets operator laptop running client mode + teleop.
- Credential thief — reads portal
.json/.credsfrom disk, backups, or shared Downloads folder. - Malicious teleop operator — legitimate USB/keyboard access; social/physical access model.
| RPC / event | Data / effect | Primary risks |
|---|---|---|
send_action |
Full motor-space dict to robot | Unbounded commands; no driver-side kinematic clamps |
teleop_step |
Leader + keyboard → composed action | Requires teleop connected; merges untrusted local input with mesh-triggered cycles |
get_observation |
Scalar joints / velocities | Information disclosure of robot state |
get_observation_with_cameras |
Scalars + base64 JPEG | Privacy; large payloads (broker DoS) |
stop_base |
Zero base velocities | Safety-relevant; should not be the only guard |
set_arm_positions / set_arm_joint / nudge_arm_joint |
Arm goal positions (base stopped on local host) | Unbounded joint commands; LeRobot max_relative_target may clip |
get_arm_positions |
Arm joint positions | Information disclosure |
state_update (event) |
Scalar stream on change (polled at LEROBOT_STATE_HZ) |
Disclosure to mesh subscribers when joints/base move |
get_features / get_status |
Schema and connectivity | Reconnaissance |
Unlike reachy-mini-driver, this package does not implement numeric clamps on
send_action keys. LeRobot / LeKiwi apply max_relative_target and host watchdog
behavior upstream.
| Control | What it does | Limitation |
|---|---|---|
| Scalar-only default observation | get_observation omits numpy camera arrays |
Cameras still available via get_observation_with_cameras |
| JPEG encoding for cameras | Configurable quality; structured JSON | Any mesh invoker with rights can request frames |
teleop_step gating |
Returns error if teleop not configured/connected | send_action still accepts arbitrary dicts |
| Sim mode isolation | No hardware I/O | Sim device can still join a real broker if misconfigured |
| Portal credential discovery | Glob under ~/Downloads when --portal |
Convenience for lab; risky on shared machines |
allow_insecure default false |
Passed to DeviceRuntime |
README examples use --allow-insecure for local dev |
| Dependency on LeKiwi host watchdog | Stops base after cmd timeout (client path) | Does not stop arm; watchdog is on robot host process |
Rely on these outside this repository:
| Layer | Control |
|---|---|
| Device Connect portal | Credential issuance, tenant/device binding, TLS when not insecure |
| NATS / Zenoh ACLs | Limit who can publish/subscribe to device subjects |
| MCP / agent policy | Tool allowlists, human approval, rate limits |
| Network segmentation | Firewall ZMQ 5555/5556, block robot ports from guest Wi‑Fi |
LeRobot max_relative_target |
Limits relative joint deltas on LeKiwi |
lekiwi_host watchdog |
Stops omni base when commands stop (client topology) |
| Physical e-stop / supervision | Required for any real-robot deployment |
| Category | Example threat | Mitigation today | Residual risk |
|---|---|---|---|
| Spoofing | Caller invokes RPCs as another tenant/device | Broker credentials bind device_id; no per-RPC caller identity |
Stolen creds = full device impersonation |
| Tampering | LAN client sends ZMQ JSON to 5555 |
No auth on ZMQ; trust LAN | Isolate robot network; VPN for remote teleop |
| Repudiation | Agent denies ordering motion | stderr logging only | Add centralized audit if required |
| Information disclosure | get_observation_with_cameras over mesh |
JPEG vs raw; scalars in events | Any authorized invoker can pull camera frames |
| Denial of service | Large camera payloads or tight teleop_step loops |
JPEG size bounded by resolution; broker limits in edge | CPU load on Pi; serial bus saturation |
| Elevation | Upload portal creds, join mesh, control robot | File must exist on host already; portal issuance upstream | Compromised teleop laptop = creds + leader arm |
- Driver holds Feetech bus and camera devices (
/dev/ttyACM0,/dev/video*). - No ZMQ exposure from this package, but robot may still run
lekiwi_hostseparately. - Run driver as a dedicated user; restrict access to serial and video nodes.
- Requires
lekiwi_hoston robot binding ZMQ on all interfaces by default (tcp://*:5555). - Treat robot IP network as trusted or tunnel ZMQ over VPN/SSH.
- Leader arm and keyboard are local to the driver process;
teleop_stepfrom the mesh triggers local input sampling — understand who can call that RPC.
- Safe for hardware, but use a distinct
device_id(e.g.lekiwi-sim) on shared brokers.
- Agent-first RPC surface — Full
send_actiondict for flexibility; no driver-side workspace fences. Narrow broker ACLs and MCP tool lists in production. - Unauthenticated ZMQ (LeKiwi stack) — Matches upstream
lekiwi_hostdesign for low-latency teleop. Security is network-position dependent. - Optional teleop over mesh —
teleop_steplets remote agents drive cycles that read local USB/keyboard; useful for demos, risky without physical supervision. DEVICE_CONNECT_ALLOW_INSECURE— Documented for local smoke tests. Disable for portal or any shared broker.- Portal credential auto-discovery — Same pattern as reachy-mini-driver lab workflows;
prefer explicit
--portal-credentialson shared machines.
| Goal | Suggestion |
|---|---|
| Production portal | allow_insecure=false, explicit credentials path, unique device_id, reviewed NATS ACLs |
| On-robot | local mode, dedicated service user, firewall except required ports, no guest Wi‑Fi |
| Teleop | VPN to robot; bind ZMQ to localhost on robot if you patch host config; supervise teleop_step |
| Privacy | Avoid exposing get_observation_with_cameras to broad mesh principals; use scalar RPCs only |
| Dev laptop | sim + local broker + allow_insecure on loopback only |
| Multi-agent | External orchestrator; do not assume RPC ordering serializes concurrent send_action |
- Authentication or TLS for LeKiwi ZMQ
- Driver-side clamping or validation of
send_actionbeyond LeRobot - Motion leases / command ownership (not implemented)
- Encrypted storage for portal credentials
- Safety-rated emergency stop wiring through Device Connect
- Automated credential rotation
| Dependency | Security relevance |
|---|---|
device-connect-edge |
Messaging, credential loading, insecure transport flag |
lerobot |
Robot drivers, teleoperators, hub model loading (see lerobot/SECURITY.md) |
opencv-python-headless |
Image encode/decode; native code attack surface |
pyzmq (via lerobot client) |
Network parser exposure on client deployments |
Keep dependencies pinned in production images and monitor advisories for this package and LeRobot.
tests/smoke_sim_runtime.py— validates RPC/event schema registration (no fuzzing).tests/test_observation_codec.py— ensures camera arrays are stripped from scalar path.
Run before release:
python tests/smoke_sim_runtime.py
pytest tests/For upstream mesh hardening, see device-connect
and device-connect-agent-tools. For robot operation, follow Hugging Face LeRobot and
LeKiwi hardware documentation for your specific build.