2026: OpenClaw Exec Approvals на эксклюзивном удалённом Mac (SSH headless): политика tools.exec, файлы состояния одобрений и консервативный откат без UI — воспроизводимая матрица решений + FAQ
Превратите выполнение команд из «тихой суперсилы» в проверяемый контракт: как Exec Approvals стыкуются с tools.exec, где на диске должны жить записи об одобрениях на хосте только с SSH и какие консервативные откаты не дают безголовому шлюзу зависнуть, когда нет рабочего стола, чтобы нажать «Разрешить».
1. TL;DR — что внедрить в первую очередь
- Раздельная политика: трактуйте
tools.execкак сочетание статических allowlist (бинарник + форма argv), ограничений рабочего каталога, гигиены окружения и бюджетов на вызов (таймаут, лимит вывода). - Устойчивые одобрения: храните pending / approved / rejected в файле состояния или компактной БД под единственным писателем процесса шлюза; не полагайтесь только на ОЗУ SSH-сессии.
- Реальность headless: если уведомления Aqua недоступны, направляйте решения человека в внеполосный канал (чат-опс, тикет, вебхук) или через
ssh -Lк локальной админ-консоли; дефолт шлюза — отказ с постановкой в очередь, а не автодопуск. - Воспроизводимость: каждый шаг runbook должен повторяться из
ssh user@macс теми же файлами; для согласованности окружений шлюза см. OpenClaw: WSL2, Linux systemd и автозапуск шлюза, гибрид с Mac по SSH (FAQ 2026).
2. Exec Approvals и другие «ворота» (node pairing, skills, hooks)
Exec Approvals отвечают на вопрос: «Может ли этот principal прямо сейчас запустить эту команду хоста с такими argv и cwd?» Они ближе всего к границе с оболочкой ОС. Node pairing — «какое устройство может привязаться к шлюзу?» Skills / plugin hooks — обёртки вокруг вызовов инструментов и телеметрии. Типичный провал: включили богатые хуки, а tools.exec оставили слишком широким — аудит выглядит полным, а blast radius всё ещё полный shell.
Для автоматизации из CI выравнивайте входную аутентификацию с тем же принципом наименьших привилегий; для воспроизводимых сборок и дрейфа зависимостей полезно держать в голове матрицу SwiftPM и Package.resolved на эксклюзивном удалённом Mac (SSH), чтобы «доверенный» пайплайн не обходил exec-политику за счёт неявных команд.
3. Плоскости политики tools.exec (что кодировать в конфиге)
Держите ортогональные плоскости, чтобы диффы в Git были читаемыми:
- Бинарники: только абсолютные пути или контролируемые корни PATH; формы вроде
curl | bash— только под явный break-glass с ID тикета в argv. - Argv: префиксные allowlist, запрещённые флаги (например, неуместные цепочки
-c), верхняя граница числа токенов против злоупотребления парсером. - Cwd: только корни workspace; по возможности режьте побеги через symlink, если рантайм это поддерживает.
- Env: в неинтерактивных сессиях убирайте унаследованные секреты; инжектируйте только allowlist переменных.
- Бюджет: wall-clock таймаут, (опционально) affinity CPU, лимит байт вывода, квота одновременных exec на сессию.
На эксклюзивном удалённом Mac можно позволить себе жёстче, чем на общем ноутбуке: у пользователя шлюза нет легитимной причины собирать «случайные» проекты вне объявленных workspace.
4. Файлы состояния одобрений: раскладка, блокировки и восстановление после порчи
Безголовому шлюзу всё равно нужна устойчивая очередь pending. Минимальные свойства:
- Один писатель: один процесс сериализует переходы (pending → approved / rejected / expired); два CLI, мутирующих один JSON без блокировок, — антипаттерн.
- Ключи идемпотентности: стабильный хэш (principal, cwd, argv[], версия политики); ретраи не должны плодить дубликаты строк.
- TTL: pending истекают в
expiredс явной строкой аудита, чтобы агенты не висели вечно. - Порча данных: держите последний good-снимок или append-only журнал; при ошибке парсинга — fail closed (запрет exec) и алерт, никакого молчаливого усечения.
Храните состояние под домашним каталогом сервисного пользователя шлюза (например, выделенный openclaw), а не в world-writable /tmp, чтобы гонки нескольких SSH-сессий не смешивали решения между арендаторами.
5. Консервативные откаты без UI
Нативные GUI-запросы macOS по чистому SSH не существуют. Предпочтительные схемы:
- Внеполосный approver: метаданные pending в Slack/Teams/Telegram со signed deep links; ответ несёт токен, который потребляет шлюз.
- Мост через тикет: Jira/Linear через API; переход в Done несёт аттестацию одобрения, которую шлюз верифицирует.
- Локальный UI через port forward: админка на
127.0.0.1на Mac иssh -Lс ноутбука оператора — «безголовое железо», но не Notification Center. - Break-glass файл: ограниченный по времени маркер с монотонной меткой времени, проверяемый шлюзом; автоудаление по окну; пейджинг security при создании.
Консервативный дефолт — очередь + отказ, если канал approver не подтвердил в SLA, а не молчаливый allow: иначе обрыв сети превращается в произвольное исполнение кода.
6. Воспроизводимая матрица решений (в приложение к ADR)
| Сигнал | Интерпретация | Рекомендуемое действие |
|---|---|---|
| Запрос exec на неизвестный путь бинарника | Дрейф политики или инъекция PATH | Отказ; лог argv[0]; одобрение только после merge PR с allowlist путей |
| Файл одобрений заблокирован >30 с | Зависшая блокировка или упавший писатель | Проверить PID-файл; по runbook снять stale lock; ротация логов; не dual-write из CLI при работающем шлюзе |
| Очередь pending растёт при всплеске CI | Вебхуки без бюджета на exec | Rate-limit входа; шардирование workspace; поднять слоты одобрений или вынести низкорисковые read-only tools в отдельный класс |
| Канал approver недоступен | Нет пути без UI | Fail closed; метрика degraded mode; опционально заранее оформленный maintenance token |
| Тот же ключ идемпотентности, другой хвост argv | Попытка мутации при ретрае агента | Отклонить; новый ключ при смене argv; bump версии политики в логах |
7. FAQ
В1: Должны ли Exec Approvals зеркалировать одобрения чтения ФС?
О: Не один к одному. Чтения часто массовые и ниже по риску; exec — высокий риск. Для exec держите более жёсткие правила argv и cwd, даже если read внутри workspace либерален.
В2: Можно ли автодопускать «доверенных» пользователей CI?
О: Предпочитайте доверие, привязанное к артефакту: подписанный OIDC-токен от issuer CI, отображённый на короткоживущий principal, плюс статические allowlist. Не доверяйте одной строке username == ci-bot.
В3: Где здесь LaunchAgents?
О: Шлюз должен чисто подниматься после перезагрузки; pending на диске должны перечитаться до приёма трафика. Проверяйте контрольной перезагрузкой по SSH.
В4: Хотим нативные уведомления macOS — достаточно SSH?
О: Нужна интерактивная Aqua-сессия (залогиненная консоль) или отдельный notifier с entitlements; SSH сам по себе UI не даёт. Используйте внеполосные каналы.
8. Почему Mac mini и macOS остаются сильной базой для шлюзов с тяжёлыми одобрениями
Exec Approvals и ужесточение tools.exec настолько надёжны, насколько предсказуемы ядро и долгоживущий процесс под ними. macOS даёт launchd для детерминированных рестартов, согласованную Unix-модель прав для сервисного пользователя шлюза и OpenSSH, который команды уже умеют эксплуатировать в break-glass. На Apple Silicon Mac mini сочетаются сильный single-thread и очень низкое энергопотребление в простое — очередь одобрений круглосуточно не «кажется» лишней на счёте за электричество.
Gatekeeper, SIP и FileVault снижают фоновый риск вредоносного ПО относительно типичных образов Windows; машина остаётся тихой в шкафу или на полке рядом с стойкой. Унифицированная память помогает, когда логи, лёгкая наблюдаемость и сам шлюз делят один хост без постоянного свопа. Если нужен кремний, который не борется со сном, термикой и фоновыми сервисами, Mac mini M4 — разумная база на 2026 год: откройте главную страницу, сравните тарифы и выкатите одобрения на железе, которое не мешает runbook.
Посмотрите варианты Mac mini на SSHMac и закрепите Exec Approvals на выделенном хосте уверенно.