nerve-agent can execute shell commands on the machine where it runs. Treat the
agent token like a production secret and run the process with the least
privileges your workflow allows.
The agent sends its relay token in the WebSocket Authorization: Bearer header.
Avoid putting agent tokens in command history, logs, process managers with loose
permissions, or URLs. Older relays may still accept a ?token= fallback, but
that path can leak through proxy and access logs and should be treated as
deprecated.
- Run the agent as a dedicated unprivileged user.
- Store the agent token in
/etc/nerve-agent.envwith restricted permissions. - Store the agent ECDH key outside the repository, for example
/var/lib/nerve-agent/agent.key. - Avoid running as
rootunless your handler explicitly needs it. - Use a small allowlisted handler/runbook script for production automation.
- Prefer explicit local actions such as
restart-nginxordeploy-statusover arbitrary shell text typed on a phone. - Keep sudoers rules narrow. Allow exact commands, not a general shell.
- Set a command timeout that matches the expected runbook duration.
The safest production shape is:
- Nerve delivers a signed command envelope.
nerve-agentdecrypts it and verifies the Ed25519 signature.- A local handler maps a small set of approved names to exact local commands.
- The agent returns encrypted output.
This keeps the useful remote action loop while avoiding a phone-sized SSH session with broad host privileges.
The current agent trusts authenticated keyring updates received from the relay. That keeps setup simple for the first public agent, but it is not the final zero-knowledge trust model. A stronger release should verify keyring updates with an out-of-band trust root or cryptographic proof.
This limitation does not affect the send-only signal path. Sender DSNs cannot connect as agents, read history, decrypt old content, or execute commands.
Please report security issues privately through GitHub Security Advisories for
the nerve-ink/nerve-agent repository.