Command Execution
Last updated
The rules that apply when the agent runs a shell command.
run_command never sees a raw shell string. Argv-only input, bare-command-name enforcement, and a parsed (not pattern-matched) sh -c script are the three layers — see the Sandbox page for the exact rules. The same rules cover the background variant (v1.3.1); run_command_background was renamed background_command (Removed in v1.3.2). Commands on the read-only allowlist (532 embedded entries since v1.3.3, 409 after cd was dropped in v1.3.0; matched on the binary plus up to two arguments since v1.0.25: git status, docker ps, ls, ...) skip the confirm gate unless an argument is a sensitive path or the call sets network: true; everything else is gated by the active permission mode, and under auto an irreversible command (destructive Git, infrastructure, cloud, deploy, migration or SQL operations) still asks even when an allow rule matches. Since v1.3.3 the allowlist check lives in internal/agents/exec/readonly: commands that can set values or load plugins (date, hostname, sysctl, nm, objdump) get per-command argument checks, --version / -v entries must match the whole argv, git global flags are limited to an explicit list and git options that start an external program (--ext-diff, --textconv, -O) are refused, and an sh -c / bash -c script matches only when every inner command does and it has no variable assignment, export, printf -v, arithmetic or parameter expansion. Matched calls run concurrently. Since v1.3.3 a run_command / background_command confirmation also shows a one-sentence explanation written by the dispatcher model. Networking inside the sandbox is off unless the call sets network: true (v1.0.25), which confirms under safe and runs under auto. Since v1.3.0 sandbox: false runs one command outside the sandbox, and only after the user's system password is verified, whatever the permission mode or allow rules. Since v1.3.2 an argv ['sudo', '<binary>', ...] is accepted too: it raises a sudo: <cmd> confirmation that always asks for the system password (none is shown while the sudo ticket is still valid), then runs as sudo -n <binary> ... outside the sandbox; sudo inside sh -c is still rejected. Since v1.3.11 an argv that contains a secret mask this daemon produced (see Security Model) is refused, so a command that needs a key reads it inside the same call, such as ['sh', '-c', 'set -a; . ./.env; set +a; curl ...'].Since v1.3.0 a TUI line starting with
! runs the rest as a shell command typed by the user: it goes to $SHELL -c (else /bin/sh) in the TUI's work directory with the user's own permissions, outside the sandbox and without the confirm gate, capped at 30 minutes; the exit code and output (up to 32 KiB) are then sent to the agent to report on. Since v1.3.2 a ! command containing sudo first opens a password popup when no sudo ticket is valid, verifies the password with sudo -S -v, then runs; a wrong password shows [Denied] password: incorrect password.The command policy is a denylist, not an allowlist:
denied_command in config.json is the only list, and anything not on it runs subject to sandbox and confirmation. The former white_list / path_white_list keys are no longer read, and sensitive_map was renamed to sensitive_path — a config still carrying any of these keys is ignored silently (the startup warning was dropped in v1.1.2).