Обновить

Комментарии 39

Заведение отдельной виртуалки с чистым окружением (без посторонних и продовых секретов) будет лучшим вариантом. После полной заливки делаем снапшот, и дальше пусть разносит ее сколько хочет - код в гитлабе, отдельные папки в бекапе, а остальное восстанавливается из снепшота. И агент не должен иметь доступа к проду, вообще - он коммитит, а дальше мы ручками проливаем на прод с другой машины или из гитлаба.

Из докера пускать тоже вариант, но он намного более сложный, неудобный и хрупкий.

Вы отлично описали два полярных подхода, но полноценные виртуальные машины для меня заметно снижали комфорт использования, в статье как раз описан промежуточный вариант, удобно как в докере, надежно, как в виртуалке.

Но нужно будет прикрутить своий прокси с политиками, настроить firewall (достаточно неочевидным образом, так как он должен работать поверх виртуалки), настроить иньекцию стокенов (тоже нетривиально), настроить доступ к дискам, каким-то образом всё это мониторить.
Да,ну на фиг такое счастье!

Вы имеете в виду выстраивание изоляции и инъекции секретов своими руками?

Так в этом и суть инструмента, он сам все проксирует и настраивает под капотом

Он дже добавляет секреты тольков очень ограниченный набор сервисов, разве нет?

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

Полноценная виртуалка жрет слишком много ресурсов и времени на старт

Еще отдельная боль для меня была монтирование директорий, не все всегда все видит

Та же тревожность, только в профиль: когда проектируешь CI/CD для Telegram-ботов, токены ботов, ключи от продакшн-баз и секреты вебхуков часто лежат в переменных окружения или в .env, и агент, запущенный от моего пользователя, видит их все. Хуже того, боты по своей природе открыты внешнему миру — любой пользователь может прислать сообщение, которое через лог попадёт в контекст агента, и это уже не гипотетическая промпт-инъекция, а рабочий вектор.

Я пришёл к тому же: изолировать среду. Но вместо полноценных виртуалок пока использую контейнеры с read-only-маунтами и прокидываю только нужную директорию. Это не серебряная пуля, но хотя бы ограничивает радиус взрыва. А какой инструмент вы в итоге нашли и насколько он зашёл в боевых сценариях? Потому что проблема «агент видит всё, что вижу я» до сих пор держит меня от того, чтобы дать агенту SSH-доступ на продакшн, и я почти перестал спать.

Для меня отлично подошел вариант с изоляцией через sbx, в частности, ключи можно держать снаружи песочницы за счет sbx secret и агент не будет видеть никакие секреты

Upd
"никакие" звучит слишком радикально, стоило сформулировать мягче, "не будет видеть секреты, добавленные в sbx secret"

Несовсем понял, как именно изолировать секреты. Ну, токены, которые sbx поддерживает, понятно. А как именно помогает /etc/sandbox-persistent.sh ? Он же ничего толком не изолирует.
Ну, и вообще остаётсся вопрос изоляции ключей и секретов.

Все так и докер прямо указывает это в документации. sbx secret позволяет хранить набор ключей для ограниченного числа поддерживаемых сервисов

У подхода Docker Sandbox есть серьёзный недостаток в плане безопасности: из такой песочницы элементарно сбежать на хост. Поскольку рабочий каталог с проектом шарится с хостом, то агент может подложить в каталог проекта малозаметные файлы, которые приведут к выполнению кода на хосте: git hooks, .mise.local.toml, direnv, etc. - есть тьма инструментов, которые "для удобства" выполняют код из файлов проекта, и зачастую изменения в таких файлах git diff не показывает. Так что идея делать git commit/push на хосте - это как раз уязвимость (из-за хуков), а не усиление безопасности.

На мой взгляд категорически неприемлемо шарить каталог проекта с агентом. Агент должен работать как отдельный сотрудник, с собственным клоном репо проекта, в собственном домашнем каталоге, имея доступ только к разрешённым для него секретам. И обмениваться с ним кодом можно только через git push/pull - это исключает атаки через все вышеупомянутые "невидимые" файлы.

Ещё один важный нюанс: если не вайб-кодить, то не получится ограничиться работой только внутри claude - изменения нужно ревьювить, допиливать, а для этого нужно иметь доступ к уже настроенному и удобному окружения хоста (IDE с кучей утилит и их конфигов).

В результате, более правильный подход к безопасной работе с агентами, на мой взгляд, совершенно противоположный подходу Docker Sandbox/Dev Container/виртуалок: с изолированной средой нужно шарить не каталог проекта, а настроенное окружение хоста (рабочие инструменты).

Пример реализации этого подхода (даже два варианта - один на базе ssh ai-dev@localhost а второй на базе linux namespaces) я выложил в https://github.com/powerman/sandbox-ai-dev. К сожалению, утилиту для упрощения установки я пока не реализовал, плюс поддерживается только Linux (впрочем, вариант на базе ssh в теории можно адаптировать для macOS).

Приятно видеть комментарий, реализующий альтернативный подход.

Насчет малозаметных файлов тейк понятный, сам об этом думал, но решил, что граница между безопасностью и комфортом для меня пролегает в первую очередь по непреднамеренным деструктивным действиям агента. Меня в первую очередь пугает неожиданное изменение системных файлов или пресловутый rm rf, а sandbox для этого подходит идеально.

Кстати, замечательная идея насчет клона репо, пока писал статью, завезли новое, что в обзор не попало. Dokcer sbx стал из коробки поддерживать Clone mode, насколько это близко вашему подходу и реализации?

Что касается настроенной IDE хоста, улавливаю некое противоречие, наличие отдельной копии для агента неизбежно ухудшает скорость синхронизации, в случае с подключение по SSH к среде разработки в локальной песочнице да, этот момент решается, хоть и сложнее настраивать окружение.

А вот насчет шарить окружение категорически не согласен, все переменные окружение, доступные агенту, потенциально под угрозой.

Расскажите, а как у вас дела с Docker контейнерами? Доступно ли внутри песочницы изолированное ядро для запуска контейнеров?

Меня в первую очередь пугает неожиданное изменение системных файлов или пресловутый rm rf

У меня в репо в README выложен rationale и модель угроз, почитайте, возможно передумаете. Если вкратце, то на сегодня в принципе нет защиты от атак prompt injection и supply chain - нет и даже не предвидится. Это значит что любой агент в любой момент становится вредоносным. Учитывая отсутствие защиты и популярность этой темы (выраженную например в проценте вредоносных навыков для openclaw - я видел цифры порядка 60% если не путаю) полагаться на то, что это не случится лично с нами - довольно наивно. Поэтому, на мой взгляд, Вы не того опасаетесь.

Clone mode, насколько это близко вашему подходу и реализации?

В плане того, чтобы не шарить с агентом рабочий каталог - да, по описанию очень похоже. Упомянутую мной дырищу это должно закрыть, так что рекомендую его использовать. А вот удобство работы в отдельной VM всегда будет сильно хуже, чем в привычной среде на хосте - и моё решение умудряется совместить безопасность и это удобство, чем и уникально. :)

Что касается настроенной IDE хоста, улавливаю некое противоречие, наличие отдельной копии для агента неизбежно ухудшает скорость синхронизации, в случае с подключение по SSH к среде разработки в локальной песочнице да, этот момент решается, хоть и сложнее настраивать окружение.

У меня там два варианта. На базе Linux namespaces синхронизация обеспечивается через ro bind-mount этих конфигов, что моментально. На базе ssh на localhost синхронизация пока сделана через rsync при запуске, в целом работает прекрасно, но есть и другие варианты на будущее. Но синхронизация конфигов это половина дела, ещё нужно открывать ссылки в браузере хоста, сохранять look&feel DE хоста для GUI приложений, показывать десктопные уведомления на хосте, проигрывать звуковые уведомления, etc. В целом у меня всё получилось - работа в песочнице никак не ощущается отличной от работы на хосте в плане UX.

А вот насчет шарить окружение категорически не согласен, все переменные окружение, доступные агенту, потенциально под угрозой.

Я под окружением имел в виду утилиты и их конфиги, начиная с zsh и заканчивая VS Code, а вовсе не переменные окружения.

К слову говоря, у меня там довольно сильно проработана защита от случайных утечек секретов - grep/ps/env никаких секретов никогда не возвращают. Специально, конечно, все доступные агенту секреты получить можно без проблем запустив secret-tool - но тут уже срабатывает фактор что все доступные агенту секреты были созданы специально для него, так что никакого "лишнего" доступа они не дадут.

Расскажите, а как у вас дела с Docker контейнерами? Доступно ли внутри песочницы изолированное ядро для запуска контейнеров?

Докер доступен, но ядро ОС общее - защита от эксплойта ядра автоматом требует (micro)VM, а VM автоматом убивает UX, так что я сделал выбор в пользу UX.

При использовании варианта ssh используется rootless docker под юзером ai-dev, в варианте на namespaces запускается rootful docker но внутри того же userns что и вся песочница, так что получение там рута никаких дополнительных прав снаружи песочницы не даёт.

А вот удобство работы в отдельной VM всегда будет сильно хуже, чем в привычной среде на хосте - и моё решение умудряется совместить безопасность и это удобство, чем и уникально

Насчет совмещения плюсов во многом соглашусь. За исключением отсутствия отдельного ядра внутри.

У меня там два варианта. На базе Linux namespaces синхронизация обеспечивается через ro bind-mount этих конфигов, что моментально.

Расскажите, пожалуйста, подробнее или укажите место в репозитории, где посмотреть. Видимо, не все верно понял, но пока кажется, что и скрытые от гита файлы, которые обсуждали парой сообщений выше, должны синхронизироваться.

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

Разделяю этот подход, хоть у нас и немного разошлись взгляды на шеринг рабочих директорий.

Сильно за рассматривать агента как отдельного актора, что подразумевает, в том числе, выдачу ему персонализированных учетных данных.

У меня там два варианта. На базе Linux namespaces синхронизация обеспечивается через ro bind-mount этих конфигов, что моментально. На базе ssh на localhost синхронизация пока сделана через rsync при запуске, в целом работает прекрасно, но есть и другие варианты на будущее. Но синхронизация конфигов это половина дела, ещё нужно открывать ссылки в браузере хоста, сохранять look&feel DE хоста для GUI приложений, показывать десктопные уведомления на хосте, проигрывать звуковые уведомления, etc. В целом у меня всё получилось - работа в песочнице никак не ощущается отличной от работы на хосте в плане UX.

Очевидное пустое поле для sbx это агентные IDE, в том числе Cursor. Нет из коробки варианта запуска Cursor IDE в песочнице так, чтобы агент шарил ручками в песочнице, а GUI был доступен пользователю через хост без задержек. Смотрели ли в эту сторону?

Ps насчет Readme пока не успеваю ознакомиться, вернусь позже

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

Синхронизируются конфиги вроде ~/.bashrc и ~/.config/git/. Пример списка в репо тут. Каталог с проектами/репо у агента полностью собственный, в нём не синхронизируется ничего, только через git push/pull.

Смотрели ли в эту сторону?

А что туда смотреть, у меня это всё штатно работает. Я же говорю, по UX работа в песочнице ничем от работы на хосте не отличается. У меня в песочнице открыто несколько терминалов, можно прямо в них запускать GUI приложения вроде VS Code/Cursor и они штатно работают прямо на Wayland хоста, видят в прокинутых конфигах текущую тему DE, имеют доступ к /etc и /usr хоста, etc. Можно запускать их не в терминалах а хоть прямо из менюшки DE - только нужно вызов нужного приложения обернуть через скрипт sandbox-а (примерно в том же духе, как работает firejail etc.).

Пока вы рассказываете довольно интересно, посмотрю, и, если интересен отзыв, вернусь в течение пару недель

Просто не давай агенту писать в .git и проблемы с невидимыми скриптами отвалятся сами собой

Задумался о технической реализации этого. Предполагаем что агентам не верим и что просто промпта нам недостаточно. Хуки? Отобрать у пользователя, запускающего агента, права на запись в директорию?

Агент, который имеет возможность изменять код и запускать тесты - имеет возможность делать абсолютно что угодно (просто добавив временный код в тест и запустив тесты разрешённой командой). А агент который таких возможностей не имеет - бесполезен. Поэтому единственный рабочий способ что-либо агенту запретить - запустить его в песочнице/виртуалке где запрещённое действие выполнить не может никто, включая Вас.

С одной стороны, все исполнение можно вынести в пайплайн, с другой, если можем защититься от нежелательных действий на раннере, то что нам мешает это сделать в среде агента.

Спасибо за статью! Похоже, контейнер\виртуалка с --dangerously-skip-permissions - самый оптимальный способ работы с Claude, и настоящие профессионалы обычно работают именно так. Использовать Claude в виде VSCode расширения не очень удобно: он постоянно спрашивает разрешение на использование Bash-тула для чтения файлов проекта, и даже если добавить в permissions все команды для чтения(типа find, cat, head, tail, cd и т.п.), то скрипты, которые он генерирует, все равно их не проходят, потому что он почти к каждой команде добавляет что-нибудь вроде >/dev/null, и это типа считается записью в файл, требующей ручного аппрува. Если же установить Claude с NPM и запустить в терминале VSCode, то становится доступен режим /sandbox, но и он полностью не решает проблему: редиректы в /dev/null теперь проходят, но ручной аппрув все еще требуется если скрипт объявляет переменную и она expanded в ходе его выполнения(Contains simple_expansion. Do you want to proceed?).

Для ускорения да, это неочевидный плюс изоляции, но это действительно так, когда понятен потенциальный убыток, легко отпустить агент в свободное плавание. Нередко запускаю несколько агентов параллельно для разных проектов.

Жаль что в статье не раскрыли, сколько ресурсов реально отжирает этот sbx под капотом при тяжелой сборке

Хорошая мысль, включу это в следующую часть статьи, а что для вас "тяжелая сборка"?

Docker Sandbox - это ж проприетарная штука, исходников нет, хочет аккаунт на докер.ком для работы.

Пользуясь случаем, порекламирую свой https://github.com/wirenboard/agent-vm

  • эфемерная микровм, стартует за две секунды, монтируют текущую директорию и всё

  • внутри сразу нормальный дебиан (ну или чего хотите, там OCI image)

  • докер внутри можно запускать

  • умеет публиковать порты на локалхосте сама, как wsl/lima

  • фильтрует гитхаб, доступ только к заданным репозиториям, реквизитов внутри нету

  • прокидывает аутентификацию клода, кодекса и всего остального нормально, т.е. через поддельный OAuth

  • умеет весь трафик vm заворачивать в системный прокси

cd "моя директория" && npx @wirenboard/agent-vm claude

Вы описали сейчас Docker sbx по функционалу и это звучит здорово. Круто, что опенсорс;

А есть возможность настроить не системный, а просто прокси снаружи VM? Например, через локальный докер контейнер

И аналогичный вопрос, как и комментатору выше, что насчет Cursor с интерфейсом?

прокси можно конечно, оно просто из env берёт https_proxy

Здорово, пока не дошел посмотреть репозиторий, но очень интересно. А есть опции насчет запуска Cursor?

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

А можете, пожалуйста, поделиться кейсами, что за тяжелое окружение? Возможно, всем вместе интересно будет подумать над решением

На C++ / Qt, прямо очень заметно. Там чем больше памяти, тем лучше. И файловый кэш там тоже рулит даже на очень быстрых дисках.
Но и на большом и сложном проекте Java+JavaFx было заметно при полной пересборке.
А что там думать? Это принципиальное ограничение. Возвращать (больше) неиспользуемую память из виртуальных машин и выделять больше на ходу больше, при необходимости, только VmWare может, на сколько я знаю. С остальными можно только поиграться с файлами подкачки, но так себе путь.

Так получилось, что у меня как раз VMware гипервизор, до использования Docker sbx, он запускается на нативной виртуализации ОС, Hyper v для Windows.

А можете поделиться процессом, сколько нужно параллельных ВМ и сколько памяти в каждой, чтобы было комфортно?

Выделяемая виртуалке память не возвращается системе пока виртуалка работает

так вроде возвращается без всяких проблем. По крайней мере через libkrun

Да, теоритически, через virtio-balloon, если оно на KVM. Но когда я попытался это в реальности использовать... Там такой шаманизм и столько ограничений, что это просто не работает.
Там нужен Guest Agent на витруалке. Это агент должен работать и должен быть настроен. Но даже если всё правильно сделать, то памzть не освобождается, так как d Linux она совршенноо всегда и полностью занята файловым кэшем! То есть нужно принудительно кэш сбрасывать. Это уже отдельное шаманств, и это плохо для производительности. Но есть ещё и засада в том, что дальше в зависимости от настроек кэш либо не растёт и виртуалка начинает работать медленне (а на фига мы ей память выделали тогда?), или кэш пытатся разрастись и отобрать память у хоста обратно. И поверх этого ещё и виртуальная память работает и всякие эффекты даёт.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Информация

Сайт
www.ptsecurity.com
Дата регистрации
Дата основания
2002
Численность
1 001–5 000 человек
Местоположение
Россия