opencode-sandbox — OpenCode в изолированном контейнере Docker

· 5 мин чтения
opencode sandbox docker security ai-agents
📂 Исходный код на GitHub

opencode-sandbox — запуск OpenCode внутри изолированного контейнера Docker или Podman. Агент может устанавливать пакеты и всячески ломать систему, но всё остаётся внутри песочницы. Конфигурация общая для всех контейнеров, сессия сохраняется, есть seccomp-защита (opencode-guard) и опциональное разделение ядра через gVisor. Лицензия GPL-3.0.

opencode-sandbox — OpenCode в изолированном контейнере Docker

opencode-sandbox — OpenCode в изолированном контейнере Docker

Агентный ИИ-ассистент вроде OpenCode умеет запускать команды, ставить пакеты и править файлы. Это удобно, но вызывает тревогу: а если он снесёт рабочие данные или утащит ключи? Проект opencode-sandbox отвечает на это просто: он запускает OpenCode внутри отдельного контейнера Docker или Podman. Песочница — это изолированная среда, в которой агент может делать что угодно, но не может выйти за её пределы и навредить хост-машине.

Задача проекта сформулирована без полутонов: пусть любой агентный ИИ работает как угодно, ставит пакеты, ломает систему — но всё, что он сделает, остаётся внутри песочницы.

Что даёт песочница

  • Безопасный эксперимент. Агенту можно разрешить ставить пакеты, компилировать, запускать сомнительные скрипты: ущерб не выходит за пределы контейнера.
  • Закрытая информация о железе. Серийные номера платы, UUID, модель и размер диска, сведения о GPU и PCI, параметры загрузки ядра и идентификатор загрузки хоста — всё это внутри контейнера не видно или подменяется.
  • Общая конфигурация. Настройки, агенты, скиллы и MCP-серверы лежат в общем каталоге и доступны любому контейнеру. Не нужно каждый раз настраивать их заново.
  • Сессия не теряется. Пересоздаётся контейнер, а данные OpenCode остаются: можно продолжить с того же места.

Как устроен запуск

Запускается официальный образ OpenCode, а поверх — обёртка, которая настраивает изоляцию, монтирует каталоги и передаёт параметры.

Параметр Значение по умолчанию
Образ ghcr.io/anomalyco/opencode:latest
Проект текущий каталог, чтение и запись
Данные сессии .opencode-sandbox/, монтируется в /root/.local/share/opencode
Конфигурация $HOME/.config/opencode, только чтение
Запрошенные лимиты 4 ГБ памяти, 2 CPU, 1024 процесса
DNS 1.1.1.1

Каталог сессии создаётся с правами 0700, так что он доступен только вашему пользователю. Общий конфиг по умолчанию подключается только для чтения — запись разрешается флагом --edit-config. Установка плагинов может потребовать именно этого флага.

Установка

Готовые пакеты есть для основных дистрибутивов:

# Debian / Ubuntu
sudo apt install ./opencode-sandbox_*_amd64.deb
# Fedora
sudo dnf install ./opencode-sandbox-*.rpm
# Arch
sudo pacman -U ./opencode-sandbox-*-x86_64.pkg.tar.zst
# Gentoo
sudo emerge opencode-sandbox

Для Arch есть и AUR — два варианта: сборка из исходников (yay -S opencode-sandbox-git) и готовый бинарник (yay -S opencode-sandbox-bin).

Ручная установка:

tar -xzf opencode-sandbox-*.tar.gz
cd opencode-sandbox-*/
mkdir -p ~/.local/bin/build
cp opencode-sandbox opencode-project-init ~/.local/bin/
cp build/opencode-guard ~/.local/bin/build/

Защитный модуль ищется рядом с запускалкой как build/opencode-guard, затем в /usr/lib/opencode-sandbox/guard. Свой путь можно задать флагом --guard=PATH.

Запуск

cd ~/code/myproject
opencode-project-init
opencode-sandbox
opencode-sandbox --opencode-model=some-model

Первая команда подготавливает каталог проекта: создаёт .opencode-sandbox/ и напоминает добавить его в ignore-файл. Вторая запускает изолированный OpenCode. Нужен интерактивный терминал.

Опции

Опция Что делает
--edit-config Разрешает запись в общий конфиг (по умолчанию только чтение)
--no-pull Использует уже скачанный образ (по умолчанию образ всегда подтягивается заново)
--no-network Просит контейнер обойтись без сети
--no-guard Выключает защитный модуль
--runtime=docker / --runtime=podman Выбор среды выполнения, по умолчанию определяется автоматически
--guard=PATH Путь к своему бинарнику защиты
--gvisor Требует зарегистрированный в Docker runsc и отключает защитный модуль
--container-key=value Передаёт --key=value в среду выполнения контейнера
--opencode-key=value Передаёт --key=value в сам OpenCode

Автоматический выбор среды: без прав root сначала пробуется Podman, затем Docker; с правами root — Docker с gVisor, затем Podman, затем Docker.

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

opencode-sandbox --model=provider/model          # проигнорировано
opencode-sandbox --opencode-model=provider/model # передано в OpenCode

С параметрами контейнера стоит быть осторожным: они меняют защиту песочницы, и эти изменения не показываются в запросе подтверждения. Например, --container-privileged=true даёт контейнеру больше доступа к хосту.

Два уровня защиты

Защитный модуль (opencode-guard). Небольшая программа на C, которая накладывает seccomp-фильтр на системные вызовы. Она блокирует доступ к чувствительным системным файлам, а вместо настоящих данных хоста сообщает данные песочницы — например, свои значения памяти и идентификатора системы. Базовые проверки сведений о файлах при этом остаются доступны.

gVisor (runsc). Вариант посерьёзнее: контейнер работает не под обычным ядром хоста, а под отдельным ядром на уровне пользователя. В этом режиме защитный модуль не нужен, а часть системных файлов отдаётся в синтетическом виде. Запускается только с Docker, у которого в списке сред выполнения зарегистрирован runsc.

Rootless-вариант gVisor требует --ignore-cgroups, и тогда запрошенные лимиты по памяти, CPU и числу процессов не применяются — выводится предупреждение. В rootful-режиме лимиты работают.

Что именно скрыто

Что Docker + guard Podman + guard Docker + gVisor
Серийник платы, UUID, вендор (/sys/class/dmi/id) закрыто закрыто закрыто
Модель и размер диска (/sys/block) закрыто закрыто закрыто
Параметры загрузки ядра (/proc/cmdline) запрещено маскируется синтетика
uname синтетика синтетика синтетика
/proc/meminfo, /proc/cpuinfo запрещено маскируется частично
Прямые CPU-запросы (CPUID, affinity) видны видны видны

Последняя строка важна: модель процессора и список доступных CPU прятать не удаётся.

Ограничения

Изоляция контейнера — не полная анонимность и не гарантия от побега.

  • Общие файлы. Агент видит каталог, в котором запущена песочница, и данные сессии. Общий конфиг OpenCode доступен только для чтения, если не включён --edit-config.
  • Сеть. По умолчанию сеть доступна, а ваш публичный IP виден. Отключается флагом --no-network.
  • Параметры контейнера. Прямые опции --container- могут ослабить или обойти защиту.

Разработка

Сборка защитного модуля — командой make, тесты — командой make test (они собирают модуль и запускают тесты на Python). Форматирование скриптов проверяется через shfmt, хук включается так:

git config core.hooksPath .githooks

В планах разработчиков — изоляция на базе Kata VM. Лицензия — GPL-3.0-or-later, текст лежит в LICENSE.

Источник: https://github.com/Antiquete/opencode-sandbox