Sandbox для AI-агента: как ограничить код, файлы и сеть
Задача определяет вход и допустимый результат
Код, файлы и сеть изолируются в worker
Авторская схема SANDBOX-6 и синтетический CSV
Failure modes и production-проверки

$ sandbox --contract SANDBOX-6
> bind: actor / task / input
> isolate: code / files / network
> limit: time / memory / output
> route: verified / deny / reconcileAI-агент, способный запускать код или вызывать инструменты, получает доступ к процессам, файлам и сетевым адресам. Sandbox для AI-агента ограничивает последствия ошибочного или вредоносного предложения модели: задаёт границы процесса, разрешённые ресурсы, срок жизни и проверяемый результат. Это технический разбор изоляции, а не универсальная гарантия безопасности. Для общего выбора AI-специалиста в Армении есть отдельная страница.
Ниже — авторская схема SANDBOX-6 и синтетический пример агента, который анализирует загруженный CSV и сохраняет только отчёт. Пример не описывает действующее внедрение и не обещает измеренных показателей. Смежные материалы: безопасность MCP-сервера и контракт инструмента.
Проблема и требования
Prompt с фразой «не открывай секреты» не мешает запущенному процессу прочитать доступный файл. Правило должно исполняться за пределами модели. Перед запуском зафиксируйте пользователя, задачу, входные файлы, допустимый тип результата и срок действия. Отдельно решите, нужен ли агенту вообще исполняемый код: для простого преобразования данных может хватить строго типизированного инструмента без shell.
Изоляция должна ограничивать три пути воздействия. Код не должен получать полномочия хоста; файловая система должна содержать только нужные входы и отдельный каталог вывода; сеть должна быть закрыта по умолчанию или ограничена конкретными назначениями. Лимиты CPU, памяти, диска, процессов и времени нужны для отказоустойчивости. Вывод и журналы могут содержать чувствительные данные, поэтому их тоже проверяют и удаляют по политике хранения.
Архитектура SANDBOX-6
| Граница | Контракт | Проверка |
|---|---|---|
| 1. Задача | один request ID, actor и назначение | авторизация до запуска |
| 2. Образ | закреплённый образ без лишних утилит | digest и ревью зависимостей |
| 3. Код | непривилегированный процесс без host socket | профиль процесса и системных вызовов |
| 4. Файлы | вход read-only, выход в отдельный временный каталог | mount manifest и проверка путей |
| 5. Сеть | deny by default, разрешённые адреса через шлюз | правила egress и журнал соединений |
| 6. Результат | лимиты, артефакт, проверка и очистка | receipt, размер, тип и TTL |
Оркестратор принимает только типизированную заявку. Политика связывает actor, tenant и входной объект, затем формирует манифест исполнения. Изолированный worker видит копию разрешённого CSV, рабочий каталог и ровно одну точку возврата. Доступ к CRM или MCP-инструменту остаётся отдельным контролируемым вызовом: sandbox процесса не заменяет проверку прав в целевой системе.
Синтетический манифест
request_id: example-095
image_digest: sha256:reviewed-image-placeholder
user: nonroot
inputs:
- source: authorized-report.csv
mount: /input/report.csv
mode: read-only
output: /output/summary.json
network: deny
limits:
seconds: 30
memory_mb: 256
processes: 16
output_mb: 5Это проектный образец, не готовая конфигурация конкретного контейнерного движка. Значения лимитов выбирают под измеренную нагрузку. Манифест не должен принимать произвольный путь с хоста от модели. Оркестратор разрешает идентификатор входа, создаёт временный каталог и фиксирует фактически смонтированные объекты.
Компоненты и жизненный цикл
Политика сначала проверяет права на документ и необходимость запуска кода. Broker выдаёт короткоживущий идентификатор задачи, но не передаёт worker постоянный токен. Worker запускается с минимальными правами, фиксированным образом и read-only корнем. Входные файлы монтируются только на чтение, а результат записывается в отдельный ограниченный каталог. Egress-шлюз разрешает только явно одобренные назначения, если задача требует сеть; DNS, редиректы и адреса после разрешения имени входят в проверку.
После завершения оркестратор проверяет код выхода, время, размер и тип артефакта. JSON проходит схему; ссылки и строки в нём остаются недоверенными данными. Только после проверки результат доступен пользователю. При timeout worker останавливают, временные файлы удаляют, а неопределённый внешний эффект сверяют до повтора. Подробности управляемого workflow см. в AI-автоматизации, а про формулирование задач и узких инструментов — в prompt engineering.
// Псевдокод оркестратора, не готовая реализация.
const job = policy.authorize(actor, tenant, inputId, "summarize_csv");
const manifest = broker.createManifest(job, { network: "deny", output: "summary.json" });
const run = await sandbox.executeOnce(manifest, requestId);
if (run.timedOut || run.externalEffectUnknown) return reconcile(requestId);
if (!artifactSchema.safeParse(run.output).success) return reject("invalid_output");
return publishVerifiedArtifact(run.output);Ошибки и failure modes
| Сценарий | Контроль | Маршрут |
|---|---|---|
| Модель предлагает путь к секрету хоста | broker принимает ID разрешённого входа, не путь | отказ |
| Символическая ссылка уводит за пределы входа | копирование с проверкой реального пути и mount manifest | отказ |
| Код пытается выйти в сеть | egress deny и журнал | остановка, расследование |
| Зависимость запускает побочный процесс | образ, непривилегированный пользователь и лимит процессов | остановка |
| Вывод заполняет диск | квота и лимит артефакта | отказ без публикации |
| Timeout после внешнего вызова | request ID и receipt на стороне сервиса | сверка до повтора |
Контейнер сам по себе не является достаточным доказательством изоляции. Ошибки конфигурации, доступный Docker socket, привилегированный режим, общий writable volume или доступ к metadata endpoint меняют реальную границу. Для особо чувствительных задач выбирайте более сильную изоляцию и проверяйте её на своей инфраструктуре.
Тестирование и production-чек
Создайте набор фикстур: нормальный CSV, попытка чтения постороннего файла, traversal в имени файла, symlink, сетевой запрос, бесконечный цикл, многопроцессный fork, большой вывод и timeout. Для каждой фиксируйте ожидаемый отказ либо валидный артефакт и отсутствие побочных изменений. Тестируйте реальные mount и egress правила в том же окружении, где будет worker, а не только мок политики.
Перед production зафиксируйте владельца политики, digest образа, процесс обновления зависимостей, лимиты, срок хранения входов и логов, процедуру остановки и сверки результатов. Проверьте права на вход и выход для разных tenant. Мониторинг должен показывать причины отказа и неизвестные эффекты без публикации секретов в логах. Ревью архитектуры полезно провести до выдачи агенту новых инструментов или сетевых прав: связаться с командой.
const job = policy.authorize(actor, tenant, inputId);
const run = await sandbox.executeOnce(broker.manifest(job), requestId);
if (run.timedOut || run.externalEffectUnknown) return reconcile(requestId);
if (!artifactSchema.safeParse(run.output).success) return reject;
return publishVerifiedArtifact(run.output);