kvm-pilot controls real hardware: it can power-cycle machines, mount boot
media, and inject keystrokes onto a console with no OS-level authentication on
the target. Treat it accordingly.
Please do not disclose vulnerability details in a public issue.
- Preferred: GitHub's private "Report a vulnerability" flow under the repository's Security tab. Include reproduction steps and the affected version.
- Fallback (if that button is missing — private vulnerability reporting can be toggled off): open a regular issue saying only "security report — please provide a private contact", without any vulnerability details, and a maintainer will arrange a private channel.
We aim to acknowledge reports within a few days. Do not include working exploits against third-party devices or live hosts in a public report.
- Do not expose a KVM device directly to the internet. Put it behind a VPN or an authenticated reverse proxy. The PiKVM/GLKVM web stack is not hardened for direct public exposure.
- Use TOTP/2FA where the device supports it (
pip install --pre "kvm-pilot[totp]").verify_ssldefaults toFalsebecause these devices ship self-signed certificates; set it toTrueand pin a real certificate if your environment allows. - Credentials resolve from arguments, environment variables, or a config
file. The library never writes secrets back out, and passwords plus session
tokens are redacted from error text. Prefer environment injection over
committing a config file with secrets. Avoid
--passwd/--totp-secreton the command line — argv is visible to any local user viapsand persists in shell history; useKVM_PILOT_PASSWD/ a profile,--passwd-file, or--ask-passwdinstead. If the config file holds a password or TOTP secret, restrict it (chmod 600); the CLI/library warn when it is group/other-readable. - Disabling Intel AMT is a security tradeoff, not a free win. Turning off
an enabled-but-unprovisioned ME on an ex-corporate machine is usually the right
call — unknown provisioning state is an out-of-band backdoor. But AMT is also
the only firmware-level remote console most laptops have, and the cost is
invisible until months later when you need BIOS access and discover your
HDMI-capture KVM is blind below the OS.
Before disabling it, decide explicitly: will this host ever need remote
firmware/boot work, and is physical access acceptable when it does? The middle
path is usually better than either extreme — keep AMT provisioned and
hardened (own the MEBx password, TLS transport, consent ON, management VLAN)
rather than disabled, so the console exists but no one else can reach it. See
amt-onboarding.mdand #212. - The safety layer is advisory, not a sandbox.
dry_runand the confirmation callback prevent accidental destructive calls; they are not a privilege boundary. Anyone who can run your script with valid credentials can disable them.
The vision layer transcribes whatever is on the target's screen — including a
raw_text field — and a compromised or hostile machine can display text crafted
to manipulate an LLM agent that consumes the classification (for example, text
telling the agent to power-cycle or type a command). Treat all screen content
as untrusted input, exactly like a web page an agent scrapes.
What the design guarantees today:
- A classification never triggers a destructive action on its own.
classify()andwait_for_state()return data; they never call power, HID, virtual-media, or GPIO. Every state-changing op routes throughSafetyPolicy.guard, and you wire those calls yourself (a regression test asserts a hostile classification result causes no device-state change). raw_textis length-bounded (the prompt caps the transcription) so a screen can't flood an agent's context.- Over MCP, every destructive tool is disabled until the operator opts its
effect class in via the server's own environment —
powerbehindKVM_PILOT_MCP_ALLOW_POWER; the act toolstype_text/press_key/send_shortcut/mousebehindKVM_PILOT_MCP_ALLOW_HID;mount_iso/ejectbehindKVM_PILOT_MCP_ALLOW_MEDIA;ssh_execbehindKVM_PILOT_MCP_ALLOW_SSH— and each invocation additionally requires approval (a human elicitation, orconfirm=trueunder a standing policy). A screen-injected agent cannot set server env vars, and a reboot chord (Ctrl+Alt+Del) is classified by effect, so it needs the power gate even over the HID transport.
What you must still do: if you wire an agent to act on classifications, gate every destructive step behind human/policy approval — do not let free text from the screen select an action. The MCP server's per-invocation approval model (#61) is the structural version of this.
In scope: credential handling, secret redaction, the safety-gating logic, and
injection issues in how kvm-pilot constructs requests. Out of scope:
vulnerabilities in PiKVM, GLKVM, GL.iNet firmware, or third-party VLM servers —
report those to their respective projects.