Вопрос

OpenClaw sandbox: что чем ограничивается

Разводим по углам sandbox, tool policy и elevated в OpenClaw 2026.9.7 и показываем, где у песочницы остаются дыры в tool policy.

· 5 мин чтения

Коротко

  • Sandbox решает, где выполняется инструмент: внутри контейнера или на хосте. Tool policy решает, какие инструменты вообще доступны. Elevated — это «выполни exec на хосте», и только exec.
  • Если exec разрешён, песочница не делает оболочку read-only: запрет write/edit/apply_patch не мешает shell-командам читать примонтированные папки.
  • deny бьёт allow, /exec не выдаёт инструменты, elevated не обходит запрет creator-role на песочницу.

Сверено с документацией OpenClaw 2026.9.7, 2 октября 2026.

В OpenClaw 2026.9.7 три разных механизма, и путать их легко. Sandbox отвечает на вопрос «где выполняется инструмент». Tool policy отвечает «какой инструмент вообще можно звать». Elevated узкая лазейка «выполни exec на хосте». Дальше что каждый из них делает, где они пересекаются и почему разрешённого exec в песочнице хватает, чтобы прочитать всё, что туда примонтировано.

Sandbox: где работает вызов

Sandbox не запрещает инструменты, а переносит их выполнение в контейнер (Docker, Podman, SSH, OpenShell, Crabbox). Управляется ключом agents.defaults.sandbox.mode со значениями off, non-main или all. По умолчанию выключен. Режим non-main отправляет в песочницу групповые чаты и каналы, а главная сессия остаётся на хосте, для многих это сюрприз. Ключ workspaceAccess (none, ro, rw) решает, что песочница вообще видит из вашей рабочей папки.

docker.binds пробивает файловую систему песочницы: что примонтировали, видно внутри с указанным режимом. По умолчанию это rw, для исходников и секретов ставьте :ro. Если примонтировать /var/run/docker.sock, песочница фактически получает контроль над хостом. scope: "shared" игнорирует привязки отдельных агентов, остаются только глобальные. Gateway-процесс всегда остаётся на хосте, в контейнер уходит только выполнение инструментов.

Tool policy: какие инструменты существуют

Tool policy — это жёсткий стопор на список инструментов. Слоёв пять: tools.profile, tools.byProvider[provider].profile, tools.allow/tools.deny и их per-agent двойники, плюс tools.sandbox.tools.allow/deny для песочницы. Правила простые: deny всегда побеждает; если allow непустой, всё остальное считается заблокированным; /exec не выдаёт инструменты, только меняет дефолты сессии для авторизованных отправителей.

Tool policy фильтрует по имени, а не по последствиям. Если exec разрешён, запрет write, edit и apply_patch не делает команды в оболочке безопасными, агент просто прочитает файл через cat. Готовые группы (group:fs, group:runtime, group:web) — это сокращения. Для агентов только для чтения документация советует явно запрещать group:runtime и мутирующие файловые инструменты.

{
  tools: {
    sandbox: {
      tools: {
        allow: ["group:runtime", "group:fs", "group:sessions", "group:memory"],
      },
    },
  },
}

Elevated: только exec и только для своих

Elevated узкая лазейка: запустить exec на хосте из песочницы. Никаких новых инструментов он не даёт, на tool allow/deny не влияет и не превращает host=auto в переопределение между хостами. Если роль создателя сессии требует песочницу, elevated не сработает. Режим /elevated full дополнительно пропускает exec-approvals, но только если локальная политика уже полностью разрешающая.

Глобальный гейт tools.elevated.enabled должен быть включён, плюс нужны списки разрешённых отправителей по каналам в tools.elevated.allowFrom.<provider>. Per-agent гейт agents.entries.*.tools.elevated.enabled может только ужесточать: оба флага должны быть true.

{
  tools: {
    elevated: {
      enabled: true,
      allowFrom: {
        discord: ["user-id-123"],
        whatsapp: ["+15555550123"],
      },
    },
  },
}

Exec-approvals: allowlist и ask на хосте

Согласования — это отдельный слой на хосте. Он не выдаёт инструменты и не ослабляет tools.exec.*, только ужесточает. Команда проходит, когда согласны политика, allowlist и (опционально) пользователь. По умолчанию неизвестная команда спрашивает; без UI в компаньоне запрос отклоняется.

Если локальный документ согласований говорит ask: "always", сессия будет спрашивать даже при конфиге ask: "on-miss". В SQLite согласования лежат в $OPENCLAW_STATE_DIR/state/openclaw.sqlite#exec_approvals_config. На macOS приложение-компаньон получает system.run по локальному IPC и утверждает команды в UI.

openclaw sandbox explain
openclaw sandbox explain --session agent:main:main
openclaw sandbox explain --agent work
openclaw sandbox explain --json

Где слои пересекаются и где течёт

Порядок такой: сначала tool policy решает, что вообще можно звать. Потом sandbox решает, где выполнение пойдёт. И только для exec поверх всего этого работают elevated и exec-approvals. Главная дыра: tool policy смотрит на имя инструмента, а не на то, что shell-команда прочитает внутри песочницы. Если exec есть, запрет read/write не мешает команде прочитать примонтированный файл. Bind :ro ограничивает запись, но не чтение.

Режим, scope, workspace access, фактический allow/deny и источник каждого правила видны в openclaw sandbox explain. Это первое, что стоит запустить, если что-то блокируется не там, где вы ожидали.

Частые ошибки

Думать, что mode: "non-main" отправляет в песочницу и главную сессию. Нет: группы и каналы это non-main, прямой чат это main.

Полагать, что запрет write/edit/apply_patch делает песочницу доступной только для чтения. Это не так: при разрешённом exec агент прочитает всё, что примонтировано. Безопасность даёт запрет group:runtime плюс привязки только для чтения.

Примонтировать папку с секретами без :ro или примонтировать /var/run/docker.sock «на всякий случай». Первое открывает запись, второе отдаёт песочнице контроль над хостом.

Пытаться elevated обойти роль создателя с обязательной песочницей. Не выйдет: required sandbox неприступен, elevated не помогает.

Путать approvals с tool policy. Ослабление одного слоя не отменяет другие и не компенсирует их: deny в tool policy всё ещё блокирует инструмент независимо от настроек согласований.