alpacon exec

Execute a command directly on a remote server without opening an interactive terminal session. This is useful for running one-off commands, automation scripts, or retrieving output from a server.

bash
alpacon exec [flags] [USER@]SERVER [--] COMMAND...

All flags must be placed before the server name—everything after the server name is treated as the remote command. Use -- to separate the remote command explicitly, so its flags (such as -U or -d) are not interpreted as alpacon flags.

Options

bash
  -h, --help                    help for exec
  -u, --username string         Specify username
  -g, --groupname string        Specify groupname
      --env=KEY[=VALUE]         Set 'KEY' to 'VALUE', or read 'KEY' from the current shell's environment (repeatable)
      --file string             Run the script at this path on the server as a verified file instead of a command line
      --file-from string        Read the script's content from this local path instead of the --file path
      --interpreter string      Interpreter for --file (default "/bin/bash")
      --reuse-days int          Propose how long an approval of --file stays reusable, 1 to 366 days
      --work-session string     Attach this command to a work-session (overrides 'work-session use')
      --detach                  Submit the command and return immediately without waiting
      --wait                    Block and re-attempt until a reviewer approves the sudo request, or the wait times out
      --wait-approval string    Like --wait with a custom wait timeout (e.g. 30m; default 5m); implies --wait
      --output string           Output format: table or json (default "table")

Subcommands

bash
alpacon exec ls             List recent remote command executions
alpacon exec logs JOB_ID    Fetch the result of a command submitted with --detach

exec ls

List recent remote command executions, most recent first. This is where the old alpacon event listing moved—the flags are unchanged.

bash
alpacon exec ls [flags]

Aliases: ls, list

bash
  -h, --help            help for ls
  -s, --server string   Filter by server name
  -t, --tail int        Number of command entries to show, newest first (default 25)
  -u, --user string     Filter by requesting user

List the 25 most recent executions:

bash
alpacon exec ls

Narrow to one server and one user:

bash
alpacon exec ls --tail 10 --server my-server --user admin

--tail returns exactly the number of entries you ask for—--tail 250 gets you 250 entries.

Examples

Execute a command on a server:

bash
alpacon exec my-server ls -la /var/log

Execute as a specific user:

bash
alpacon exec admin@my-server cat /etc/hostname
alpacon exec -u admin my-server cat /etc/hostname

Execute with a specific group:

bash
alpacon exec -g developers my-server whoami

Use -- to pass flags to the remote command:

bash
alpacon exec root@db-server -- docker exec postgres psql -U myproject -d myproject
alpacon exec my-server -- grep -r "pattern" /var/log

Run multiple commands—the quotes keep && from being interpreted by your local shell:

bash
alpacon exec my-server -- "df -h && free -m"

Shell metacharacters (;, |, &, $) are interpreted by your local shell first—quote the remote command to send them to the server, where the remote shell interprets them again. To pass one as a literal character, add inner quotes so the remote shell does not interpret it either:

bash
alpacon exec my-server -- "echo 'hello;world'"

Attach the command to a specific work session:

bash
alpacon exec --work-session 11111111-2222-3333-4444-555555555555 my-server -- df -h

Pass an environment variable to the remote command:

bash
alpacon exec --env="KEY1=VALUE1" --env="KEY2=VALUE2" my-server -- printenv KEY1

Read a secret from the current shell without putting it on the command line or in the audit log:

bash
alpacon exec --env="PGPASSWORD" db-server -- psql -h localhost -U app -c 'SELECT 1'

If a secret ends up on the command line anyway—a secret-like KEY=VALUE pair, a password flag (e.g. -pSecret123), or a connection string with an embedded password—the server rejects the command with command_inline_credential before it runs. Move the secret to --env instead.

Verified file execution

Use --file to run a script that already exists on the target server, instead of typing a command line. The reviewer sees the exact bytes you are about to run, and the platform makes sure the server executes those same bytes—not whatever happens to be at that path by the time the command runs.

--file PATH takes the absolute path of the script on the target server. The CLI reads the script’s content from the same path on your local machine, unless you pass --file-from LOCAL_PATH to read it from somewhere else. Either way, the local copy must be byte-identical to the file on the server, or the agent refuses to run it. --interpreter PATH sets the interpreter that runs the script (default /bin/bash) and must be an absolute path. Script arguments go after --; --file does not take a command line or --env.

An approval binds those exact bytes, on that server, as that account, with those arguments—not “the file in general”. A reviewer can mark an approval as standing, and an unchanged re-run then stops asking anyone; one changed byte sends it back for review.

--reuse-days N proposes how long a standing approval stays reusable, from 1 to 366 days. The approver decides whether to grant reuse. If the workspace limit on file execution grants is shorter than N, the server refuses the request and the CLI tells you to resubmit with a shorter --reuse-days. Without the flag, a standing approval lasts until the workspace limit, or indefinitely when the workspace has none. --reuse-days requires --file.

The reviewer sees the script’s arguments along with its content, so never put a secret in an argument or in the script itself. Have the script read it from an environment variable or a file on the host at run time. The server refuses a script that carries a credential, the same way it refuses a command line that does. The script itself is limited to 64 KB.

Run a script the reviewer can read, verified byte-for-byte on the server:

bash
alpacon exec --file /opt/deploy.sh root@prod-web -- --fast

Read the local copy from a different path and choose an interpreter:

bash
alpacon exec --file /opt/deploy.sh --file-from ./deploy.sh --interpreter /bin/sh prod-web

Propose that the approval stay reusable for 30 days:

bash
alpacon exec --file /opt/deploy.sh --reuse-days 30 root@prod-web -- --fast

Asynchronous execution

Use --detach to submit a command and return immediately instead of waiting for it to finish. The CLI prints Job submitted: JOB_ID to stdout (or {"job_id": "..."} with --output json).

bash
alpacon exec --detach web-server -- apt-get update

Retrieve the result later with alpacon exec logs:

bash
alpacon exec logs a1b2c3d4-5678-abcd-ef01-234567890abc

JOB_ID must be a UUID. If the command is still running, the current status is printed and the command exits with code 0—run it again later to check for completion.

Exit codes

The remote command’s exit code is propagated, so alpacon exec exits with the same code as the command it ran on the server.

Exit code 3 indicates the command was denied by the work session gate (for example, no active session or the session does not cover the target server). With --output json, a machine-readable diagnostic is printed to stderr. See Gate errors for the error codes.

Exit code 4 indicates the sudo command is pending human approval. Approve it in the Alpacon console, then re-run—or pass --wait to block until it is approved. With --output json, the CLI emits {"status": "pending_approval", ...} on stdout.

Work session requirement

When you sign in with browser login, alpacon exec requires an active work session that includes the command scope. Token authentication (API token or service token) bypasses this requirement.

The session to attach is resolved from the --work-session flag, the ALPACON_WORK_SESSION environment variable, or the active session set with alpacon work-session use—in that order.

MFA authentication

When executing commands as a system account (e.g., root@my-server), your workspace’s Authentication settings may require additional MFA verification. The CLI MFA flow is the same as alpacon websh—see websh MFA authentication for details.

API token ACLs

When using an API token, the token must have ACL rules for each command you intend to execute. Interactive websh sessions are not restricted by command ACLs, but exec commands always require matching ACL rules.

bash
# Allow the commands this token can run on servers
alpacon token acl command add my-token --command="df *"
alpacon token acl command add my-token --command="cat /etc/hostname"

See Token ACL management for details on wildcard patterns.

Last updated: