Модуль remote: управление удалёнными машинами

🔵 Модуль remote ведёт инвентарь машин и даёт агентам ограниченный доступ к ним по SSH/SCP: список хостов, выполнение команд, передача файлов и проверка доступности — под per-machine политикой. Приватные ключи не хранятся в инвентаре и не попадают в ответы API.

Модуль входит в стандартную поставку (config/modules.enabled → remote).

51.1 Инвентарь

Машина описывается документом: slug, host, port, user, теги, способ аутентификации и политика. Инвентарь живёт в DuckDB (logs/machines.db) и сидируется из config/remote/machines.yaml: при первом открытии БД записи из файла добавляются, если машины с таким slug ещё нет. Правки через API/инструменты сохраняются в БД и не перетираются при редеплое.

# 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

Путь к БД и к seed переопределяются переменными AGENT_OS_REMOTE_DB и AGENT_OS_REMOTE_MACHINES.

51.2 Политика выполнения {#policy}

policy.mode определяет, что разрешено делать на машине:

Режим Поведение
deny (по умолчанию) выполнение запрещено, только инвентарь
readonly только команды из allow (та же проверка, что allowlist; имя документирует намерение)
allowlist только команды из allow
full всё, кроме команд из deny

allow/deny — шаблоны с * и ? (совпадение всей строки команды). deny всегда сильнее allow. При require_approval: true вызов должен передать approved: true — иначе агент не выполнит команду, пока не получит явное согласие.

По умолчанию машина в режиме deny — fail-closed: пока политика не задана, машина доступна только как запись инвентаря. Файлы (ssh_upload/ssh_download) разрешены только при mode: full.

51.3 Аутентификация

auth.type Что это
agent локальный ssh-agent / ~/.ssh/config (по умолчанию)
key_file путь к приватному ключу на диске (поддерживается ~)
key_secret приватный ключ, хранящийся в секретах по имени name
password_secret пароль в секретах (парольный SSH пока не поддержан в раннере)

Именованные креды читаются через host-порт agent_os.Secrets (allowlist имён), поэтому модуль объявляет capability agent_os.Secrets. Ссылки на секреты берутся и из YAML-сида, и из записей в БД — обе точки входа инвентаря равноправны.

51.4 Инструменты

Модуль добавляет 8 видов инструментов (см. Справочник инструментов):

kind Назначение
machine_list список машин (опц. фильтр tag)
machine_get одна машина по slug
machine_upsert создать/обновить машину
machine_delete удалить машину
ssh_exec выполнить команду на машине
ssh_upload загрузить файл на машину (SCP)
ssh_download скачать файл с машины (SCP)
remote_health проверка доступности

Пример:

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

51.5 HTTP API

Админ-API инвентаря (за админ-аутентификацией, см. HTTP API):

Endpoint Описание
GET /v1/machines список машин 🔒
POST /v1/machines создать/обновить машину (тело — документ) 🔒
GET /v1/machines/:slug одна машина 🔒
PUT /v1/machines/:slug обновить машину (slug из пути) 🔒
DELETE /v1/machines/:slug удалить машину 🔒

Ответы используют «редактированное» представление машины (redacted()): имя секрета и ключи никогда не раскрываются.

51.6 Безопасность

51.7 Тестирование локально

Как и любой инструмент, движок можно прогнать без сервера:

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 Ограничения