codexdeck runs entirely on your own machine and opens no external network
connections. The host process listens only on loopback — 127.0.0.1:3240,
the USB/IP endpoint — bound to 127.0.0.1, never 0.0.0.0, so it is not reachable
from the network.
To make the Codex desktop app detect a Codex Micro, codexdeck presents a genuine virtual USB HID device and attaches it with the Microsoft-signed usbip-win2 virtual USB host controller. It:
- modifies nothing about the Codex app — no file changes, no code-signature
changes, no
NODE_OPTIONS/preload injection. Codex just sees a normal USB device on the bus. - needs no test-signing — the usbip-win2 drivers are WHQL/WHLK signed, so Secure Boot and HVCI stay on and untouched.
- runs the USB/IP server, the Codex Micro protocol emulator, and the
node-hiddeck driver in a single local Node process (apps/host).
Because the deck sends synthetic key/knob events to Codex through the virtual device, the USB/IP endpoint is a local input channel. Exposure is limited by:
- loopback-only bind (
127.0.0.1) — no other machine on the network can reach it; - single-attach, newest-wins — at most one client drives the device at a time.
Any process running as your user could, in principle, connect to 127.0.0.1:3240
and speak USB/IP to the device — treat it like any other loopback service on a
single-user machine.
codexdeck requires no administrator rights at all — not to install, not to
run. The optional autostart (docs/autostart.md) registers a
per-user logon task at RunLevel=Limited, and the host attaches its own virtual
device unelevated (usbip-win2 gives its VHCI device object a World read/write
ACE, so attach/detach/port are available to a normal user). The only
privileged install on the machine is the vendor's own signed usbip-win2 setup.
Do not run the host as SYSTEM/LocalSystem. A repo checkout typically lives under a user-writable path, so a SYSTEM-level service pointing at it would let any authenticated user replace the code and execute as SYSTEM — a local privilege-escalation hole. It is designed to run unelevated in your own session.
An earlier browser/WebHID path (apps/web + packages/bridge — a localhost
WebSocket, a Windows named pipe, and a NODE_OPTIONS node-hid shim) predates the
USB/IP host and is superseded. It is kept for reference; the shipped product is
apps/host, which uses none of it.
Please report security issues via the GitHub issue tracker. This is a personal-use interoperability tool that runs locally with no network exposure; there is no bug-bounty program.