Module remote: remote machine management

🔵 Module remote maintains a machine inventory and gives agents limited access to them over SSH/SCP: host listing, command execution, file transfer, and availability checks — under a per-machine policy. Private keys are not stored in the inventory and never appear in API responses.

The module is part of the standard distribution (config/modules.enabled → remote).

51.1 Inventory

A machine is described by a document: slug, host, port, user, tags, the authentication method, and the policy. The inventory lives in DuckDB (logs/machines.db) and is seeded from config/remote/machines.yaml: when the DB is first opened, records from the file are added if a machine with that slug does not yet exist. Edits made via the API/tools are saved to the DB and are not overwritten on redeploy.

# config/remote/machines.yaml
machines:
  - slug: web-1
    host: 10.0.0.10
    user: deploy
    tags: [prod, web]
    known_hosts: accept_new      # strict | accept_new | insecure
    auth:
      type: key_secret           # agent | key_file | key_secret | password_secret
      name: WEB1_SSH_KEY
    policy:
      mode: allowlist            # deny | readonly | allowlist | full
      allow: ["uptime", "systemctl status *", "df -h"]
      deny: ["rm -rf *"]
      require_approval: false

The path to the DB and to the seed are overridden by the AGENT_OS_REMOTE_DB and AGENT_OS_REMOTE_MACHINES variables.

51.2 Execution policy {#policy}

policy.mode defines what is allowed to be done on a machine:

Mode Behavior
deny (default) execution forbidden, inventory only
readonly only commands from allow (the same check as allowlist; the name documents the intent)
allowlist only commands from allow
full everything except commands from deny

allow/deny — patterns with * and ? (full match of the command string). deny always takes precedence over allow. Under require_approval: true, the call must pass approved: true — otherwise the agent will not execute the command until it receives explicit consent.

By default a machine is in deny mode — fail-closed: until a policy is set, the machine is available only as an inventory record. Files (ssh_upload/ssh_download) are allowed only under mode: full.

51.3 Authentication

auth.type What it is
agent local ssh-agent / ~/.ssh/config (default)
key_file path to a private key on disk (~ supported)
key_secret private key stored in secrets under the name name
password_secret password in secrets (password SSH is not yet supported in the runner)

Named credentials are read through the host port agent_os.Secrets (name allowlist), so the module declares the agent_os.Secrets capability. Secret references are taken from both the YAML seed and DB records — both inventory entry points are equivalent.

51.4 Tools

The module adds 8 kinds of tools (see Tool Reference):

kind Purpose
machine_list list machines (opt. filter tag)
machine_get a single machine by slug
machine_upsert create/update a machine
machine_delete delete a machine
ssh_exec execute a command on a machine
ssh_upload upload a file to a machine (SCP)
ssh_download download a file from a machine (SCP)
remote_health availability check

Example:

kind: ssh_exec
name: run_on_machine
description: Выполнить команду на управляемой машине

51.5 HTTP API

Inventory admin API (behind admin authentication, see HTTP API):

Endpoint Description
GET /v1/machines list machines 🔒
POST /v1/machines create/update a machine (body — document) 🔒
GET /v1/machines/:slug a single machine 🔒
PUT /v1/machines/:slug update a machine (slug from the path) 🔒
DELETE /v1/machines/:slug delete a machine 🔒

Responses use the "redacted" representation of a machine (redacted()): the secret name and keys are never disclosed.

51.6 Security

51.7 Testing locally

Like any tool, the engine can be run without a server:

AGENT_OS_REMOTE_MACHINES=config/remote/machines.yaml \
AGENT_OS_REMOTE_DB=/tmp/machines.db \
./bin/agent-os tool config/agents/<agent>/tools/<tool>.yaml '{"slug":"web-1","command":"uptime"}'

51.8 Limitations