Command Payloads
Command payloads execute a single binary with a structured list of arguments on the target machine. They are ideal for simple, atomic operations.
A Command is not a freeform terminal line. It is structured:
bin— the binary or program to run (e.g.docker).arguments— an ordered list of plain string values passed to the binary (e.g.pull,myregistry/myapp:latest).working_directory— an optional absolute path the binary runs in.
Each argument is delivered to the binary as a separate, literal string. There is no shell parsing a single command line, so shell metacharacters, command chaining, pipes, and shell variable expansion are not available. For anything more complex, use a Script Payload or multiple actions/sequence steps.
When to Use Commands
Section titled “When to Use Commands”| Use Commands For | Use Scripts Instead |
|---|---|
| Single binary invocations | Multi-step workflows |
| Simple tool invocations | Conditional logic |
| Quick system commands | Error handling complexity |
| Docker/container commands | Piping or redirection |
Command Structure
Section titled “Command Structure”Instead of typing a terminal line, you specify the binary and each argument separately.
Basic Command
Section titled “Basic Command”To run docker pull myregistry/myapp:latest:
- bin:
docker - arguments:
pull,myregistry/myapp:latest
With Variable Substitution
Section titled “With Variable Substitution”Arguments and the working directory support variable placeholders. To pull a parameterized image:
- bin:
docker - arguments:
pull,#{registry}/#{image}:#{tag}
Variable substitution is not permitted in the bin (binary path) for security reasons — the binary path must be a literal value.
Environment Variables
Section titled “Environment Variables”Resolved non-sensitive variables are also injected into the executed process as MANTIS_* environment variables. Variable names are uppercased before the prefix is applied, so a variable named image is available to the process as MANTIS_IMAGE, and a variable named tag is available as MANTIS_TAG.
Declared environment variable values are templates too, so an action can hand a binary any variable under a name of its own choosing, a sensitive one included: API_KEY = #{api_key}.
Shell Metacharacters Are Quoted, Not Rejected
Section titled “Shell Metacharacters Are Quoted, Not Rejected”For the shell executors (Sh, Bash, Pwsh, Zsh) each argument is shell-quoted. Sh, Bash and Zsh wrap it in POSIX single quotes, escaping any single quote it contains as '\''; Pwsh wraps it in PowerShell single quotes, doubling any single quote to ''. A metacharacter inside an argument therefore reaches the binary as a literal character instead of being interpreted, which is what a deployment variable holding a $, an & or a quote needs in order to keep working. Arguments are checked for one character only: the null byte.
The bin value is the part that is filtered. For a shell executor it must contain none of
; | & $ ` ( ) { } < > ' " \ ! * ? [ ] # ~nor a newline or carriage return, nor a .. path component — so it cannot be made to name something other than the intended executable. A script’s path is checked for null bytes and .. only, because it is passed as argv rather than composed into a shell line.
Because quoting makes the shell ignore the argument’s contents, you still cannot:
- Chain commands with
&&,||, or; - Pipe with
| - Expand shell variables with
$VAR—$HOMEarrives at the binary as those five characters - Use command substitution with backticks or
$(...) - Use globs such as
*or?— they are passed through unexpanded - Use redirection with
<or>
For the Default executor no shell is involved at all: arguments go to the process as argv, so nothing is interpreted and nothing needs quoting.
To run multiple commands, use a Script Payload or split the work across multiple actions / sequence steps.
Executor Selection
Section titled “Executor Selection”Choose the appropriate executor for command execution:
| Executor | Command Interpretation | Platform |
|---|---|---|
| Default | Direct execution (no shell) | Cross-platform |
| Sh | sh -c | Linux/macOS (WSL on Windows) |
| Bash | bash -c | Linux/macOS (WSL/Git Bash on Windows) |
| Pwsh | PowerShell | Cross-platform |
| Zsh | zsh -f -c (no user startup files) | Linux/macOS (WSL/MSYS2 on Windows) |
Command Examples
Section titled “Command Examples”Each example lists the binary and its ordered argument strings.
Docker Operations
Section titled “Docker Operations”Pull an image:
- bin:
docker - arguments:
pull,#{image}:#{tag}
Start a container:
- bin:
docker - arguments:
run,-d,--name,#{container_name},-p,#{port}:80,#{image}
Stopping and removing a container requires two separate operations — run them as two actions or two sequence steps (one docker stop, one docker rm), since you cannot chain them in a single command.
Package Management
Section titled “Package Management”APT (Debian/Ubuntu):
- bin:
apt-get - arguments:
install,-y,#{package}
(Run apt-get update as a separate step rather than chaining it.)
YUM (RHEL/CentOS):
- bin:
yum - arguments:
install,-y,#{package}
Chocolatey (Windows):
- bin:
choco - arguments:
install,#{package},-y
Service Control
Section titled “Service Control”Systemd:
- bin:
systemctl - arguments:
restart,#{service_name}
Windows Services:
- bin:
pwsh(Pwsh executor) - arguments:
Restart-Service,-Name,#{service_name}
File Operations
Section titled “File Operations”Download file:
- bin:
curl - arguments:
-o,#{destination},#{url}
Extract archive:
- bin:
tar - arguments:
-xzf,#{archive},-C,#{destination}
Variable Substitution
Section titled “Variable Substitution”Syntax
Section titled “Syntax”Argument strings, declared environment variable values and working_directory are templates. Mantis renders every #{...} in
them before the command runs:
| Template | Description |
|---|---|
#{version} | Replaced with the version variable value |
#{version | ToLower} | The value passed through a filter |
#{Mantis.Environment.Name} | A system variable describing the deployment |
See Variables for filters, conditionals and the Mantis.* system
variables. The bin field is never rendered.
Arguments are plain ordered strings — there is no type, default, or required metadata attached to an individual argument. Provide the values you need as ordered argument strings.
Variables as Environment Variables
Section titled “Variables as Environment Variables”In addition to placeholder substitution, every resolved variable is injected into the executed process as a MANTIS_* environment variable. Variable names are uppercased before the prefix is applied — for example, the variable tag is available as MANTIS_TAG. This is the supported way to pass values to a binary that reads configuration from the environment.
Exit Codes
Section titled “Exit Codes”Commands report success or failure via exit codes:
| Exit Code | Meaning | Mantis Behavior |
|---|---|---|
| 0 | Success | Step marked complete |
| Non-zero | Failure | Step marked failed |
The exit code of the invoked binary is used directly. There is no shell, so there is no chaining to influence the reported result — the binary either exits 0 (success) or non-zero (failure).
Working Directory
Section titled “Working Directory”A Command runs in the Tarsus agent’s default working directory unless you set the working_directory field. Set it to an absolute path:
- bin:
docker - arguments:
compose,up,-d - working_directory:
/opt/myapp
The working_directory field supports variable substitution (e.g. /opt/#{app_name}). Because there is no shell, you cannot change directories with cd && ... — use working_directory or absolute paths instead.
Timeouts
Section titled “Timeouts”Commands have a configurable timeout (default: 300 seconds). If exceeded:
- The command is terminated
- The step is marked as failed
- The error message indicates a timeout
Set appropriate timeouts for long-running commands:
| Operation | Suggested Timeout |
|---|---|
| Docker pull | 600s (10 min) |
| Package install | 300s (5 min) |
| Service restart | 60s (1 min) |
| File download | Variable by size |
Security Considerations
Section titled “Security Considerations”Provide Secrets as Variables
Section titled “Provide Secrets as Variables”Do not embed secret literals in argument strings, and do not attempt $API_KEY-style shell expansion — a shell executor quotes each argument, so $API_KEY reaches the binary as those eight characters rather than as the variable’s value.
Instead, define the secret as a sensitive variable and declare an environment variable on the action whose value is #{api_key}. The value is filled in when the command is delivered to the target, so it never appears in the command definition or in the queued command, and the binary reads it from its environment. A sensitive variable reaches only the actions that reference it; it is not added to the MANTIS_* set.
Input Validation
Section titled “Input Validation”Arguments are passed as literal strings: a shell executor quotes each one, so a *, ?, ;, |, & or quote inside an argument is inert rather than interpreted. Quoting, not rejection, is what prevents command injection through argument values — the argument is accepted, so validate the variable values you supply. An argument such as #{path} is substituted verbatim into a single argument string, so ensure it contains the value you intend.
Troubleshooting
Section titled “Troubleshooting”Command Not Found
Section titled “Command Not Found”Error: command not found: dockerSolutions:
- Set
binto an absolute path, e.g./usr/bin/docker - Ensure the binary is in the agent’s PATH
- Check that the executor selection matches the target OS
Permission Denied
Section titled “Permission Denied”Error: permission deniedSolutions:
- Check file permissions
- Verify the agent runs with the correct user
Command Rejected
Section titled “Command Rejected”Error: Command rejected: invalid characters in command or argumentsThis names the binary or the script path, not an argument value: an argument is quoted, and is refused only for a null byte.
Solutions:
- Remove shell metacharacters (
;,|,&,$, quotes, globs, etc.) frombin - Remove any
..component frombinor from a script’s filename - Split chained operations into separate actions or a script — quoting means a
;in an argument is passed to the binary rather than acted on by the shell - Provide dynamic values as variables (
#{name}) rather than shell expansion
Variable Not Substituted
Section titled “Variable Not Substituted”If you see #{variable} in the output:
- Verify the variable is defined for the deployment
- Check that the name matches exactly (case-sensitive)
- Ensure the template is in an argument or
working_directory, not inbin
Best Practices
Section titled “Best Practices”- Keep commands simple — one binary invocation per command
- Use absolute paths — for
binand forworking_directory - Use variables —
#{name}for dynamic argument values - Provide secrets as sensitive variables — referenced as
#{name}, for example in a declared environment variable - Reach for scripts — when you need chaining, pipes, conditionals, or redirection
Next Steps
Section titled “Next Steps”- Script Payloads - For complex multi-step operations
- Testing Actions - Validate before deployment
- Versioning - Managing command changes
