Песочница

Команды оболочки, которые запускает агент, ограничены песочницей операционной системы — Seatbelt в macOS, bubblewrap в Linux: запись только в рабочую область, без чтения учётных данных и без сети, если вы её не разрешили.

Разрешения решают, можно ли выполнить команду. Песочница ограничивает, что команда может сделать после запуска. Песочница включена по умолчанию: команда оболочки, запущенная агентом, может писать только в вашу рабочую область и во временные каталоги, не может читать хранилища учётных данных и не имеет доступа к сети — даже к localhost, — если вы его не разрешили.

Эти два уровня работают вместе. Команда в песочнице остаётся ограниченной, даже если делает что-то неожиданное, поэтому можно одобрять больше команд, не вчитываясь в каждую.

Как это работает

ПлатформаМеханизмПримечания
macOSSeatbelt (sandbox-exec) со сгенерированным профилемВстроен в macOS. Ничего устанавливать не нужно
Linuxbubblewrap (bwrap) со сгенерированным списком аргументовУстановите bubblewrap через менеджер пакетов
WindowsПока недоступноКоманды оболочки отклоняются, если вы явно не отказались от песочницы. См. Безопасный отказ

Песочница применяется к командам оболочки (Bash, Process и Terminal) и к вспомогательным процессам, которые Cusp запускает для сессии, например к проверке типов и языковым серверам. Собственные файловые инструменты Cusp (Read, Edit, Write, …) через неё не проходят: для них действуют разрешения и защищённые пути.

Команды в песочнице также запускаются с очищенным окружением: ключи провайдеров и собственные учётные данные Cusp из него удалены.

Политика по умолчанию

РазрешеноЗаблокировано
ЗаписьКорневые каталоги рабочей области (ваш рабочий каталог и все дополнительные каталоги), временный каталог пользователя и /tmpВсё остальное. Внутри рабочей области конфигурация и хуки git, а также конфигурация агентов и редакторов остаются только для чтения
ЧтениеВсё остальноеХранилища секретов в домашнем каталоге: ~/.ssh, ~/.aws, ~/.gnupg, ~/.azure, ~/.kube, ~/.config/gcloud, ~/.docker/config.json, ~/.netrc, ~/.password-store, ~/Library/Keychains, токены CLI (~/.config/gh, ~/.git-credentials, ~/.pypirc, ~/.cargo/credentials, ~/.vault-token, …), профили браузеров, сокеты сред выполнения контейнеров и каталоги данных агентов (~/.cusp, ~/.claude, ~/.codex, ~/.gemini), кроме навыков внутри них
СетьНичегоВесь сетевой доступ, включая localhost

Перед построением профиля пути разрешаются до их реального расположения, поэтому выбраться наружу через символическую ссылку нельзя (в macOS /tmp превращается в /private/tmp).

Как открыть доступ к сети

Локальные порты

Серверам разработки, локальным базам данных и наборам тестов часто нужен localhost. Разрешите порты, которые они используют:

~/.cusp/settings.json
{
  "sandbox": {
    "network": {
      "allowLocalPorts": [3000, 5432]
    }
  }
}

allowLocalBinding: true открывает localhost полностью. Порт самого демона не открывается никогда.

Домены

Чтобы команды могли обращаться к определённым хостам, например к реестру пакетов, перечислите их в allowedDomains. Тогда трафик пойдёт через фильтрующий прокси Cusp:

~/.cusp/settings.json
{
  "sandbox": {
    "network": {
      "allowedDomains": ["registry.example.org", "*.example.com"],
      "deniedDomains": ["uploads.example.com"]
    }
  }
}
  • Запись — это точное имя хоста, шаблон для поддоменов (*.example.com подходит для api.example.com, но не для example.com), * для любого хоста или IP-адрес, в каждом случае с необязательным :port.
  • deniedDomains важнее allowedDomains.
  • При запросе к хосту, которого нет ни в одном списке, Cusp спросит вас: разрешить один раз, разрешить на сессию или запретить.
  • Частные и локальные адреса доступны только через явную запись с хостом или IP.
  • Отклонённый запрос получает ответ 403, тело которого начинается с «Blocked by Cusp network policy:», чтобы агент мог сказать вам, какой хост ему нужен.

В Linux список разрешённых доменов пока носит рекомендательный характер. Программы направляются на прокси через HTTP_PROXY и связанные переменные, но изоляции через сетевые пространства имён пока нет, поэтому программа, игнорирующая настройки прокси, может выйти в сеть напрямую. В macOS ограничение обеспечивает профиль песочницы. Cusp показывает об этом уведомление при старте сессии.

Настройки

Настройки песочницы используют распространённую схему sandbox, поэтому существующий блок песочницы в .claude/settings.json работает как есть.

КлючТипЗначение
sandbox.enabledbooleanВыполнять команды оболочки в песочнице (по умолчанию true)
sandbox.failIfUnavailablebooleanОтклонять команды оболочки, если песочницу нельзя применить (по умолчанию true). При false они выполняются вне песочницы
sandbox.filesystem.allowWritestring[]Дополнительные пути, доступные для записи
sandbox.filesystem.allowReadstring[]Исключения из списка запрета чтения
sandbox.filesystem.denyReadstring[]Дополнительные пути, которые нельзя читать
sandbox.network.allowLocalPortsnumber[]Порты localhost, которые команды могут занимать и к которым могут подключаться
sandbox.network.allowLocalBindingbooleanПолностью открыть localhost (по умолчанию false)
sandbox.network.allowedDomainsstring[]Хосты, доступные через фильтрующий прокси
sandbox.network.deniedDomainsstring[]Хосты, запросы к которым всегда отклоняются
sandbox.network.allowUnixSocketsstring[]Unix-сокеты, к которым могут подключаться команды

Следующие ключи принимаются, чтобы существующие настройки загружались, но Cusp пока их не применяет: autoAllowBashIfSandboxed, allowUnsandboxedCommands, excludedCommands, filesystem.denyWrite, network.allowAllUnixSockets, network.httpProxyPort и network.socksProxyPort. Запуск вне песочницы всегда требует вашего подтверждения, и ни одна команда не исключается из песочницы.

Кто что может менять

Репозиторий не должен иметь возможности отключить собственную песочницу. Настройки, которые её ослабляют, учитываются только из ваших пользовательских настроек, управляемых настроек или --settings и игнорируются с предупреждением в настройках проекта в .cusp/ или .claude/:

  • enabled: false и failIfUnavailable: false
  • allowUnsandboxedCommands и excludedCommands
  • allowLocalBinding, allowLocalPorts, allowUnixSockets и allowAllUnixSockets
  • filesystem.allowRead и filesystem.allowWrite

При этом проект может сделать свою песочницу строже, например через filesystem.denyRead или network.deniedDomains.

Когда команда заблокирована

По голому Operation not permitted трудно понять, что пошло не так в песочнице. Когда команда в песочнице завершается с ошибкой, Cusp смотрит на ошибку и код выхода и сообщает агенту, какое ограничение, скорее всего, сработало: запись за пределами рабочей области, чтение защищённого хранилища учётных данных или сетевой запрос к конкретному хосту. Агент может работать в рамках ограничения или объяснить, что ему нужно.

Если агент решит, что ему действительно нужно выполнить команду вне песочницы, он указывает dangerouslyDisableSandbox в вызове Bash. Это всегда требует вашего подтверждения; ни правило, ни режим, ни классификатор не могут его дать.

Безопасный отказ

Если песочницу нельзя применить — потому что не установлен bwrap, нет sandbox-exec или на платформе нет песочницы (Windows), — Cusp не станет молча выполнять команды вне песочницы. Он отклоняет команды оболочки и показывает уведомление при старте сессии. Тогда можно:

  • Установить песочницу (в Linux — пакет bubblewrap).
  • Одобрять запуск отдельных команд вне песочницы, когда агент об этом просит.
  • Указать "sandbox": { "failIfUnavailable": false } в пользовательских настройках, чтобы выполнять команды оболочки вне песочницы, оставив движок разрешений единственным уровнем защиты.

То же правило действует для всех уровней защиты в Cusp: проверка, которая не может выполниться, запрещает или спрашивает, но никогда не разрешает.

Аудит

Каждое решение о разрешении и каждое соединение через сетевой прокси записывается в <data directory>/audit/<session>.jsonl, который можете читать только вы.

Ограничения

  • Песочница ограничивает процессы, которые запускает агент. Она не ограничивает сам демон и файловые инструменты Cusp.
  • Команды, которые вы разрешили выполнить вне песочницы, ничем не ограничены.
  • Чтение намеренно разрешено широко. Всё, что доступно для чтения за пределами списка запретов, например исходный код в других папках, может прочитать команда в песочнице. Чтобы скрыть такие пути, добавьте их в filesystem.denyRead.
  • Долго работающие процессы, запущенные через Process, остаются в песочнице на всё время работы, включая дочерние процессы.
  • В Linux список разрешённых доменов носит рекомендательный характер (см. выше).

На этой странице