Security

This is a device whose purpose is to type on your computer.

Read that before putting one on a network you care about. Everything below is published in the open alongside the code, because a tool with this reach should be assessed on what it actually does rather than on an assurance.

Threat model

Whoever holds the key can press any key.

Anyone who reaches the daemon's port with the key can type anything and click anywhere. On a machine with a shell, a browser or a login prompt, that is arbitrary code execution on the target: out of band, invisible to the target's own logs, and unaffected by anything installed on it. No sandbox, no undo, no confirmation.

Physical access to the board gives the same, and the key with it. Treat the board as you would treat a keyboard already plugged into the machine, because that is what it is.

Where the boundary actually sits

Not in this software. The limit on what can be done is the permissions of the account being typed into, and your authority to operate the machine at all. The tool does not distinguish authorised work from unauthorised, and neither does the target.

That is also what makes it useful for hardening a build, testing a kiosk or checking an appliance with no API. The authorisation is the part that lives outside the software, and it has to be yours.

The real gate

Control it the way you already control people.

The daemon has no privilege model and cannot have one. It presses keys, and keys do whatever the signed-in account can do. Everything you already run on human users therefore applies to the agent unchanged, and that is where the limit belongs: give it an account with exactly the permissions the task needs, and no more.

A standard user cannot approve an elevation prompt.
A service account scoped to one system cannot reach production.
A snapshot taken first makes a mistake free to undo.
If the account is a domain administrator, that is the blast radius, and nothing in this narrows it.

So the answer to "how do we stop the agent doing something terrible" is to constrain the account, not the keyboard. Your existing directory, group policy, role model and review process are the controls that work here. You do not need a new access-control model for this, and we are not asking you to trust one we wrote.

This applies identically to every path we offer. It is a property of the account being typed into, not of how the keystrokes arrived, so nothing about the choice of hardware makes it stricter or looser.

Two things that follow from it

Typing is destructive and there is no undo. A misread screen, a wrong coordinate or a confused agent can delete data, change configuration or approve something irreversible. Test against something you can restore, with an account scoped to the task.

What we describe here is design intent, not assurance. None of it is audited, certified or tested against a standard, and the properties are what the code is meant to do. Do not treat any of it as the control. The boundary that matters is the target's own account.

Responsibility

Three parties, and only one of them is us.

Our daemon does not replace the security of the hardware it runs on. It adds an authenticated service beside whatever is already there, so a deployment's posture is the sum of three things and we own the smallest of them.

The platform, which is its vendor's On an off-the-shelf KVM the board keeps running its own firmware, web interface, virtual media and power control, and we leave all of it untouched. On the open board the credential is the device's own login and the firmware is an upstream project's. Defects in either belong to them. We will help route a report and we will not pretend to have fixed it.
The daemon, which is ours One service, authentication mandatory, refusing to start without a key and checking every request, with no localhost exemption. That is the part we wrote, the part we will fix, and the part worth reporting to us.
The network, which is yours The daemon has no transport encryption and no rate limiting, so the segment it sits on is carrying real weight. Change the board's default console and web credentials, restrict its own firmware ports to a management host, expose only the daemon's port to whatever drives it, and keep the firmware current.

Put plainly: installing this on a KVM adds a second front door to a board that already had one. We are responsible for ours being locked. The first one, and the corridor both of them open onto, are not ours to secure.

The high-performance path

No network at all, so physical access is the control.

The fast path is not networked. There is no listening port, no address to reach it on, and no radio brought up: the firmware never initialises one. It connects by USB at both ends, one side to the target and the other to the machine running the agent, with no route between them for anything that is not a keystroke. Most of the section above therefore does not apply to it. There is no transport to encrypt, nothing to rate-limit, no second service beside a vendor's web interface, and nothing on a network to find in the first place. What replaces all of it is physical: whoever can reach the machine it is plugged into, or walk up to the hardware itself, has the same power the key confers on the other path. That is the trust boundary of a keyboard on a desk, and it should be secured the way you would secure one.

Two layers, and which of them each path asks of you. The endpoint row does not change between them.
 Endpoint Network layer
High-performance path yours, as for any usernone to secure
Networked hardware yours, as for any useryours as well

Removing the network removes a layer of work. It does not narrow what the agent can do once it is typing, because that was never a function of the wire.

What that costs you

It cannot be operated remotely. The agent has to run on the machine physically connected to it, so there is no driving a target in another building without something else providing that reach, and whatever provides it becomes the exposed surface instead.

Firmware updates are physical too. There is no over-the-air path, by construction rather than by omission, which is one fewer way in and one more visit to site.

What the daemon does

The controls that are there.

Authentication is mandatory. It refuses to start without a key and checks every request. There is no localhost exemption, because code running on the board is not authority to type on the target.
The key never leaves the board it was generated on and never appears on a command line. Handling and comparison are documented in the repository for anyone who wants to check them.
Anything held is released after five seconds of silence, and the hold inside a tap is capped, so no request can pin a key down.

What it does not do

The controls that are your job.

No TLS. The token crosses the network in the clear. Run it on a trusted segment or tunnel it.
No rate limiting and no lockout. The key is the whole of the access control. Expose that port and nothing else.
No audit trail, deliberately. An audit log of a keyboard is a keylogger, and real passwords go through this path. Record at the caller instead: who asked, what kind of action, how many characters. Never the characters.
Screenshots are unfiltered. Whatever is on the screen goes to whoever asked for it, and if that is a hosted model it leaves your network.

The one people miss

A screen is untrusted input.

Text on a screen can carry instructions, and an agent reading that screen may act on them. A crafted filename, a web page, an error dialog or an email preview is an input channel into the thing driving your keyboard.

This is not hypothetical and it is not specific to us. It is the consequence of pointing a language model at arbitrary pixels while giving it hands. Scope what the agent is allowed to reach, keep the account it types into as small as the job allows, and do not point it at a screen showing content you would not run.

One-way by construction

The control channel is fire and forget, with no acknowledgement and no return path. Video comes in, keystrokes go out, and nothing travels back the other way. That was chosen for latency, but it is the right shape for a second reason: the motor path should not sense and the sensing path should not actuate. You do not type with your eyes, and you do not read with your hands.

Structurally different

It is not a HID injector.

An injector types blind into a machine it cannot see, and depends on nobody watching. This is closed-loop, and the agent interface enforces that: the actions that move or type refuse to run unless a look returned a frame in the last minute. Clearing a stuck key is exempt, because needing a screenshot to release a held key would be backwards.

We are precise about what that buys. It is a guardrail on the agent, not an access control on an attacker. The underlying API enforces nothing of the kind, and anyone holding the key bypasses the idea entirely. What it gives you is that an agent cannot act on an assumption about a screen it has not seen. That is a correctness property first and a safety one second.

Reporting something

Use private vulnerability reporting on the agentkvm repository rather than a public issue. In scope: anything that drives the target without the key, anything that leaks the key, a defect in the authentication path, the look-before-act rule or the stuck-key watchdog.

Out of scope because it is the design: the daemon types on the target, so anyone holding the key can do whatever the logged-in account can do. That is what the tool is.