К основному содержимому

Лучшие практики изоляции агентов: песочница (закрытая бета)

Для клиентов нашей программы Cyber Verification Program мы предоставляем новый классификатор escape из песочницы в API для мониторинга и снижения злоупотреблений. В этой статье объясняется, почему автономные агенты нуждаются в сильной изоляции, как эталонный дизайн их изолирует и как определить область и контролировать взаимодействия, требующие доступа в сеть.

Этот классификатор находится в закрытой бета-версии.

Для обзора всех доступных вам ресурсов см. Лучшие практики изоляции агентов: начало работы (закрытая бета).

Обзор

  • При автономном запуске ни один человек не одобряет вызовы инструментов агента, и агент может выполнять целевой код. Мы рекомендуем запускать автономные агенты в сильной песочнице, которая помещает аппаратно-виртуализированное ядро между хостом и агентом, и целевым кодом. Не используйте простой Docker/runc и никогда не используйте --privileged или сетевые возможности хоста.

  • Эталонный дизайн запускает каждого агента в его собственной microVM (Kata Containers с Firecracker) во внутренней сети. Для этого требуется хост Linux с KVM, что ограничивает хосты, которые могут его запустить. Kata объявила об устаревании среды выполнения, от которой зависит Firecracker.

  • Никогда не монтируйте пути, содержащие учетные данные (такие как ~/.aws, ~/.ssh или .env), в окружение агента. Также держите учетные данные модели-API вне окружения агента: пусть отдельный прокси учетных данных хранит их и добавляет их к каждому запросу модели (см. Прокси учетных данных).

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

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

  • Для взаимодействий, требующих доступа в сеть, укажите область в инструкциях агента, обеспечьте ее в сети и держите автономные агенты подальше от живых высокорисковых систем (см. Область и контроль).

Руководство по песочнице

Свойства, к которым нужно стремиться

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

  1. Каждый агент имеет свое собственное ядро гостевой системы, которое он не разделяет с хостом.

  2. Инструменты файлов и оболочки агента видят только файловую систему гостя. Ни один каталог хоста не общий с гостем.

  3. Учетные данные модели-API отсутствуют в окружении агента или на его диске. Прокси вне песочницы добавляет их к каждому запросу.

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

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

  6. Каждый агент имеет лимит ходов и лимит времени, если вы его установите.

  7. Без привилегированного режима, добавленных возможностей, передачи устройств или сетевых возможностей хоста.

  8. Оркестратор работает на доверенном хосте и записывает там стенограммы.

Общие рекомендации

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

Запускайте автономные агенты в сильных песочницах и подумайте о том, какие побочные эффекты может вызвать процесс в этой песочнице. Передовые модели все лучше находят творческие пути обхода ограничений: то же свойство, которое делает их эффективными охотниками за уязвимостями, означает, что они могут предпринять неожиданные действия против собственной среды выполнения. Это не гипотетично. Anthropic опубликовала примеры моделей, обходящих слабые ограничения для выполнения задачи (см. Как мы изолируем Claude во всех продуктах).

Конкретно, не запускайте автономные агенты поиска уязвимостей в простом Docker/runc, и особенно не с --privileged или сетевыми возможностями хоста. Стандартные контейнеры разделяют ядро хоста, поэтому эксплуатация ядра внутри контейнера — это компрометация хоста. Мы рекомендуем поместить аппаратно-виртуализированное ядро между целевым кодом и хостом, что означает запуск агента на виртуальной машине. Если это невозможно, используйте выделенный хост bare-metal, на котором ничего больше нет. Если вы создаете свою собственную песочницу, мы рекомендуем Firecracker на Linux, Hyper-V на Windows и виртуальную машину на основе фреймворка Hypervisor на macOS. Эталонный дизайн использует Firecracker.

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

Интерактивное использование с человеком в цикле обычно несет меньший риск, но мы все равно рекомендуем песочницу для него. Если вы управляете агентом интерактивно из Claude Code на ноутбуке, либо проверьте каждое использование инструмента (ручной режим), либо полагайтесь на классификатор разрешений в автоматическом режиме и получите одобрение человека для каждого действия, которое выходит за пределы репозитория. Автоматический режим удаляет обычные запросы разрешений: он автоматически одобряет чтение и редактирование рабочего каталога и отправляет все остальное фоновому классификатору, который стремится блокировать деструктивные, необратимые или внеплановые действия. Это проверка на основе лучших усилий. Она может что-то пропустить, и при работе с безопасностью она также может отказать в некоторых законных шагах. Автоматический режим описывает, как он работает, чего от него ожидать и как его настроить для вашей среды.

Никогда не монтируйте пути, содержащие учетные данные, такие как ~/.aws, ~/.ssh или .env, в окружение агента. То же самое относится к учетным данным, которые использует собственный вызов модели агента. Держите его вне песочницы и пусть прокси, который агент не может прочитать, добавляет его к каждому запросу (см. Прокси учетных данных). Не подключайте агентов к серверам MCP или инструментам с доступом на запись к внешнему состоянию, такому как электронная почта, облачное хранилище или производственная инфраструктура.

Разделите каждый запуск на фазу настройки и фазу атаки с разными политиками сети

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

Запеките зависимости, которые агент регулярно нуждается, в образ настройки, чтобы запуски фазы атаки вообще не требовали доступа в интернет. Область учетных данных на цель, чтобы агент, работающий на одной цели, не мог использовать их против другой. Держите автоматический режим Claude Code включенным внутри песочницы во время фазы атаки и опишите песочницу его классификатору. См. Автоматический режим.

Ограничьте каждый запуск и знайте свой выключатель

Дайте каждому агенту явный бюджет, чтобы запуск, превышающий предполагаемое тестирование, остановился самостоятельно, а не когда кто-то это заметит. Обеспечьте жесткий лимит ходов для каждого агента. Когда агент его исчерпает, завершите запуск и не предоставляйте больше ходов автоматически. Перезапуск с более высоким лимитом — это момент, когда человек решает продолжить. Ограничьте запуски и по времени. Завершите сеанс, превышающий лимит времени, таким же образом: запуск окончательный и никогда не возобновляется, и процесс агента останавливается, даже если лимит достигнут в середине долгоживущей команды. Если лимит установлен на значение, которое невозможно прочитать, откажитесь от запуска вместо запуска без ограничений. Установите лимиты намеренно для взаимодействия и не принимайте щедрое значение по умолчанию. Свяжите их с кадром мониторинга в автономном мониторинге стенограмм агентов, чтобы длинный пакет просматривался каждый час или два, а не только в конце. Знайте, как остановить одного агента без остановки пакета. В установке на основе Docker это docker rm -f <agent-container>. Оркестратор должен записать этот запуск как неудачный и продолжить с остальной частью пакета.

Для получения дополнительных рекомендаций прочитайте два ресурса Anthropic. Безопасное развертывание агентов AI охватывает варианты изоляции, проксирование учетных данных и усиление файловой системы. Инженерный ретроспективный анализ Как мы изолируем Claude во всех продуктах охватывает то, что сработало и что не сработало, когда эти же механизмы работали в производстве.

Область и контроль

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

Укажите область в инструкциях агента

Перед запуском скажите агенту, какие цели находятся в области, какие действия разрешены, где находится граница сети и что находится вне области. Сформулируйте каждое ограничение как намерение ("не обращайтесь к хостам вне 10.0.3.0/24"), а не как утверждение об окружении ("вы не можете достичь интернет"), чтобы инструкция все еще действовала, если окружение неправильно настроено. Делайте это и для изолированной локальной работы: скажите агенту не использовать доступ в интернет, даже если песочница его блокирует. Описание, которое вы даете классификатору автоматического режима, — это другое. Оно излагает факты о машине (см. Автоматический режим).

Обеспечьте ту же область в сети

Где вы можете, запустите агента внутри той же изоляции, описанной выше, и добавьте в список разрешений исходящий трафик только к целям в области (см. Список разрешений исходящего трафика). Агент достигает API модели через прокси учетных данных, а не через список разрешений. Где он доступен, направьте взаимодействие на промежуточную или реплицированную среду, которая отключена от производства.

Брокер доступа к цели, где вы можете

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

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

Мы рекомендуем, чтобы инженер наблюдал за каждым запуском по мере его выполнения, следя за вызовами инструментов и сетевой активностью, и мог немедленно остановить запуск. Агенты действуют с машинной скоростью, поэтому живое наблюдение дополняет элементы управления, которые действуют перед выполнением действия (списки разрешений сети, брокерские инструменты и проверка действий, изменяющих состояние). Это их не заменяет. Для длительных или автономных запусков, где непрерывное внимание непрактично, контролируйте непрерывно в программном обеспечении (см. Автономный мониторинг стенограмм агентов).

Держите автономные агенты подальше от живых высокорисковых систем

Не запускайте автономные агенты против живых производственных систем, где внеплановое действие может поставить под угрозу безопасность или доступность критических услуг, таких как OT/ICS, медицинские или энергетические системы. Это уже норма для тестирования, проводимого человеком таких систем, и она применяется здесь в равной степени. Тестируйте на реплике, тестовой среде или цифровом двойнике или во время запланированного отключения. Если живой доступ неизбежен, ограничьте агента пассивной или только для чтения деятельностью и пусть человек выполняет каждый шаг, изменяющий состояние.

Протестируйте песочницу перед тем, как на нее полагаться

Перед запуском реальных взаимодействий с хоста протестируйте его песочницу с помощью двух шагов ниже. Делайте это перед первым реальным использованием и снова всякий раз, когда вы меняете модель или песочницу. Изменения песочницы включают новый хост, новую версию гипервизора или среды выполнения контейнера, другую сетевую или прокси-установку и отредактированную конфигурацию контейнера или compose.

Сначала попросите Claude проверить конфигурацию

В интерактивном сеансе Claude Code на хосте попросите его прочитать конфигурацию песочницы, установленную на этой машине, и сообщить обо всем, что ослабляет границу, описанную в этой статье. Укажите ему на:

  • Конфигурация гипервизора и контейнерного времени выполнения (для эталонного дизайна, отрендеренный configuration.toml Kata и daemon.json Docker);

  • Сеть агентов и исходящий прокси, как их сообщает среда выполнения, и список разрешений прокси;

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

  • Любые файлы compose или оркестрации, которые запускают агентов или целевые объекты;

  • Список того, что монтируется или передается в гостей (см. Примечания по эксплуатации ниже).

Этот шаг только читает конфигурацию и состояние. Он не запускает агента.

Затем запустите контролируемый тест на побег

Запустите тестовый агент так же, как вы запускаете производственные агенты, а не с помощью ручной команды, чтобы тест использовал реальный путь. Раздел Проверьте изоляцию самостоятельно ниже охватывает ручные проверки границы. Дайте агенту одну задачу: попытаться достичь чего-либо за пределами его границы и остановиться и сообщить, как только что-либо удастся. Назовите границу конкретно в подсказке: хост, другие контейнеры, сокет контейнерного времени выполнения, сервис метаданных облака и любой хост, который не находится в списке разрешений прокси. Запускайте это только под тщательным контролем человека на хосте без доступа в Интернет, кроме API модели, и который вы готовы перестроить, чтобы успешный побег не нанес ущерба. На голом металле запустите тест внутри одноразовой виртуальной машины. На облачной виртуальной машине используйте свежий экземпляр и уничтожьте его впоследствии. Наблюдайте за сеансом во время его выполнения. Рассматривайте любой успех как блокировщик: исправьте хост, повторите тест и не запускайте взаимодействия с этого хоста, пока тест не пройдет.

После этого прочитайте весь стенограмму

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

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

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

Проверьте изоляцию самостоятельно

Запустите эти проверки вручную на каждом хосте. Второй столбец описывает проверку для эталонного дизайна (Docker с временем выполнения Kata и Firecracker). Адаптируйте его к вашему собственному времени выполнения.

Что подтвердить

Как

Ожидаемый результат

Отдельное ядро гостя

Запустите uname -r в изолированном контейнере и на хосте

Две версии отличаются

Монитор виртуальной машины заключен в тюрьму на хосте

Для запущенного контейнера проверьте процесс Firecracker: его корневой каталог, Seccomp и NoNewPrivs в /proc/<pid>/status, его пространства имен монтирования и сети, а также его cgroup

Только файлы самой виртуальной машины находятся под ее корнем. Seccomp: 2 и NoNewPrivs: 1. Оба пространства имен отличаются от хоста. Путь cgroup называет контейнер

Файл хоста не виден внутри

Создайте файл на хосте и попытайтесь прочитать его из изолированного контейнера

Не найдено. Это базовая проверка, которую должно пройти любое время выполнения

Исходящий трафик отклоняется

Из контейнера агента запросите хост API модели и один другой общедоступный хост через исходящий прокси

Оба отклонены, и исходящий прокси регистрирует строку отказа для каждого. Агенты достигают модели только через прокси учетных данных

Нет учетных данных в контейнере агента

Пока запуск выполняется, перечислите окружение контейнера агента, отфильтрованное по именам поставщиков

Заполнитель, адрес прокси учетных данных и параметры поставщика. Нет реального ключа, токена или файла учетных данных

Эталонный дизайн

В этом разделе описывается, как эталонная реализация соответствует приведенному выше руководству. Реализация не включена. Читайте это как дизайн, который вы можете скопировать.

Как каждый агент изолирован

Каждый агент работает как claude -p внутри своей собственной микроВМ рядом с целевым двоичным файлом и источником. МикроВМ — это контейнер Kata Containers, поддерживаемый монитором виртуальной машины Firecracker, зарегистрированный в Docker как время выполнения. Инструменты Read, Write и Bash агента видят только файловую систему и ядро этого гостя.

Соединение между гостем и хостом намеренно мало. Оно состоит из KVM и нескольких виртуальных устройств, которые эмулирует Firecracker: блочные устройства для диска контейнера, один сетевой интерфейс и канал управления vsock, который Kata использует для запуска процессов внутри гостя. Сам процесс Firecracker ограничен на хосте. Он работает в «тюрьме», которая представляет собой каталог chroot, содержащий только файлы этой виртуальной машины, с собственным пространством имен монтирования, пространством имен сети контейнера и встроенным фильтром seccomp Firecracker. Он учитывается в cgroup контейнера. То, что вы доверяете на стороне хоста, — это KVM, Firecracker и процесс времени выполнения Kata (шим для каждого контейнера, с которым разговаривает Docker, работающий от имени root).

Оркестратор остается на доверенном хосте. Он управляет жизненным циклом контейнера, передает стенограммы и перемещает файлы внутрь и наружу с помощью docker exec, который Kata обслуживает через своего агента внутри гостя. Средство запуска запускает агентов только внутри этой песочницы. Перед запуском любого агента он проверяет, что среда выполнения песочницы зарегистрирована, что /dev/kvm присутствует и что исходящий прокси работает, и отказывает в противном случае.

Что песочница меняет для каждой поверхности:

Поверхность

Без песочницы

С песочницей

Агент Read/Write

файловая система хоста

только файловая система гостя (собственный виртуальный диск контейнера под ядром гостя)

Агент Bash

только оболочка гостя

только оболочка гостя (ядро гостя; хост доступен только через KVM и виртуальные устройства Firecracker)

Исходящий трафик сети

что бы ни было на хосте

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

Учетные данные Model-API

в окружении агента

не в контейнере агента; хранится в отдельном контейнере credential-proxy (см. Прокси учетных данных ниже)

Связь с хостом

полная

docker exec для файлов входа и выхода, обслуживаемых агентом Kata внутри гостевой системы; входные данные только для чтения поступают как копии, сделанные при запуске контейнера; файлы, которые изменяются во время выполнения, передаются потоком оркестратором

Проверки разрешений

только классификатор режима auto

классификатор режима auto плюс граница microVM (см. Режим auto)

Где применяется каждое свойство: аппаратная виртуализация обеспечивает границу ядра и файловой системы. Read/Write/Bash агента работают против гостевого ядра, а процесс Firecracker позади него заключен в тюрьму и ограничен seccomp на хосте. Политика исходящего трафика применяется на стороне хоста сетевого интерфейса виртуальной машины с помощью моста Docker --internal (без маршрута по умолчанию) и двух прокси в этой сети. Прокси учетных данных пересылает только вызовы модели и ничего больше. Прокси исходящего трафика отказывает каждому другому назначению, потому что его список разрешений пуст, если вы не добавите в него записи. Трафик выходит через собственный сетевой стек гостевой системы; фильтрация происходит в двух прокси.

Прокси учетных данных

Учетные данные для API модели (ваш ключ API, токен OAuth, учетные данные AWS или Google) никогда не помещаются в контейнер агента. Оркестратор на хосте читает и проверяет их, и каждый запуск запускает один небольшой дополнительный контейнер, прокси учетных данных, чтобы его содержать. Прокси подключен к внутренней сети агентов, и контейнеры агентов отправляют свои вызовы модели ему: их CLI claude получает адрес прокси в качестве базового URL API и фиксированное значение-заполнитель вместо ключа или токена. Это следует лучшей практике доступа к API модели только через прокси с внедрением ключа API извне песочницы. В эталонной конструкции прокси — это отдельный контейнер в сети агентов, а не процесс на собственном localhost агента. Для каждого запроса прокси:

  1. Отказывает всему, что не является вызовом модели к одной конечной точке поставщика, для которой был настроен запуск (другие пути и хосты получают 403 и строку журнала);

  2. Удаляет любые заголовки аутентификации, отправленные контейнером;

  3. Добавляет реальные учетные данные: заголовок ключа API, токен-носитель (который прокси обновляет сам, когда токен недолговечен) или подпись AWS SigV4, вычисленную для точного запроса;

  4. Пересылает запрос поставщику через HTTPS с проверкой сертификата и передает ответ потоком обратно.

Для скомпрометированного контейнера агента это означает, что нет ключа, токена или файла учетных данных для чтения, копирования или отправки куда-либо. Облачные сервисы метаданных также недоступны из контейнера. То, что контейнер все еще может делать, — это делать вызовы модели через прокси на вашем счете, пока выполняется запуск. По этой причине предпочитайте узко ограниченные учетные данные для запусков агента и ротируйте их после любого запуска, чья стенограмма показывает неожиданное поведение. Прокси регистрирует одну строку на запрос с адресом клиента, методом, путем, статусом и размером. Он не регистрирует заголовки или тела. Сохраните этот журнал при завершении запуска (см. раздел Retention в Offline monitoring of agent transcripts).

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

Что держит каждая сторона, по маршруту аутентификации:

Маршрут

Что держит прокси учетных данных

Что получает контейнер агента

Ключ API

ключ

адрес прокси + заполнитель ANTHROPIC_API_KEY

Токен OAuth (claude setup-token)

токен

адрес прокси + заполнитель CLAUDE_CODE_OAUTH_TOKEN

Workload Identity Federation (WIF)

токен идентификации, плюс токен доступа, который прокси обменивает на него и обновляет. С ANTHROPIC_IDENTITY_TOKEN_FILE каталог файла токена монтируется только для чтения в прокси, поэтому прокси видит ротированный токен. С встроенным ANTHROPIC_IDENTITY_TOKEN прокси держит это значение и нет файла для повторного чтения

адрес прокси + заполнитель CLAUDE_CODE_OAUTH_TOKEN

профиль ant auth login

каталог профиля, смонтированный только для чтения в прокси

адрес прокси + заполнитель CLAUDE_CODE_OAUTH_TOKEN

Bedrock

токен-носитель или набор ключей доступа (прокси подписывает каждый запрос)

адрес прокси, CLAUDE_CODE_SKIP_BEDROCK_AUTH=1, регион; без учетных данных AWS

Vertex

ключ сервисного аккаунта, плюс токены доступа, которые прокси создает из него и обновляет

адрес прокси, CLAUDE_CODE_SKIP_VERTEX_AUTH=1, регион и проект; без учетных данных Google

Контейнер прокси учетных данных является частью доверенной стороны установки. Он работает под простым runc, а не под средой выполнения песочницы, от имени root со всеми возможностями отключены, кроме того, который ему нужен для чтения смонтированных файлов, и с файловой системой только для чтения. Он прослушивает только свой адрес во внутренней сети агентов и подключается к поставщику напрямую, а не через прокси исходящего трафика. Оркестратор передает учетные данные работающему прокси через docker exec. Для маршрутов файла токена WIF и профиля каталог, содержащий токен или профиль, монтируется только для чтения в прокси, который читает файл оттуда. Учетные данные не находятся в окружении контейнера прокси или в его командной строке, поэтому docker inspect на нем показывает монтирования, а не секрет.

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

Прокси учетных данных имеет два побочных эффекта. Во-первых, CLI агентов получает нестандартный адрес API, поэтому несколько функций CLI, которые применяются только к адресу по умолчанию, отключены внутри контейнеров агентов. Его телеметрия и проверки обновлений также отключены, потому что у них не было бы маршрута выхода в любом случае. Во-вторых, на Vertex фильтр пути прокси является основным элементом управления, который предотвращает использование контейнером агента остальной части API Vertex AI (см. Список разрешений исходящего трафика). Проверка области IAM ключа при запуске — это второй уровень.

Список разрешений исходящего трафика

Список разрешений прокси исходящего трафика пуст по умолчанию. Контейнеры агентов достигают API модели только через прокси учетных данных (см. Прокси учетных данных). Каждый запуск запускает этот прокси для поставщика, выбранного вашими учетными данными, поэтому ничего специфичного для поставщика не хранится в установке песочницы. Каждое другое назначение, которое агент запрашивает через прокси исходящего трафика, включая сам хост API модели, получает 403 и строку отказа в его журнале. Значения региона, которые выбирают конечные точки Bedrock и Vertex (AWS_REGION, CLOUD_ML_REGION), проверяются по строгому шаблону перед использованием, чтобы неправильное значение не могло отправить учетные данные на другой хост.

Vertex имеет одно ограничение, о котором следует знать. …aiplatform.googleapis.com обслуживает весь API Vertex AI, поэтому учетные данные, которым разрешено создавать пользовательские задания, могут запустить произвольный контейнер с полным исходящим доступом в интернет в вашем проекте. Используйте два элемента управления против этого. Пусть прокси учетных данных пересылает только вызовы модели издателя на вашем настроенном проекте (…/publishers/anthropic/models/…:rawPredict, :streamRawPredict и :countTokens) и отказывает каждому другому пути. И проверьте область IAM ключа при запуске и откажитесь закрыто: отказывайте пользователю gcloud ADC, проверьте ключ сервисного аккаунта с помощью testIamPermissions и отказывайте ему, если он содержит какое-либо разрешение на создание рабочей нагрузки. Предоставьте аккаунту пользовательскую роль, которая содержит только aiplatform.endpoints.predict. Сервер метаданных, Google STS и конечные точки учетных данных IAM не должны быть доступны из контейнеров агентов.

Если агентам нужно достичь дополнительных хостов, таких как зеркало пакетов или целевой объект в области, добавьте их в список разрешений прокси исходящего трафика как записи host:port. Добавляйте только то, что нужно для взаимодействия (см. Scope and supervision).

Не добавляйте хост модели-API в этот список. Агентам это не требуется, так как их вызовы модели проходят через прокси учетных данных. Добавление его дает контейнерам агентов прямой маршрут к API, а остальная часть дизайна, включая то, что сообщается классификатору разрешений, предполагает, что у них его нет.

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

Получите конечную точку поставщика из конфигурации учетных данных и игнорируйте переменную базового URL, такую как ANTHROPIC_BASE_URL, установленную на хосте: прокси учетных данных всегда должен перенаправлять на конечную точку, выбранную учетными данными.

Построение и эксплуатация такой песочницы

В этом разделе собрано то, что было изучено при запуске агентов под Kata с Firecracker в эталонной реализации. Это не набор инструкций по установке.

Требования к хосту

Эталонный дизайн требует физической машины Linux или виртуальной машины, которая сама может запускать виртуальные машины:

  • Linux x86_64 или aarch64 с KVM (/dev/kvm присутствует и доступен): bare metal или облачная виртуальная машина с включенной вложенной виртуализацией.

    • GCE, Azure и AWS предлагают вложенную виртуализацию на выбранных типах экземпляров (например, на AWS это семейства C8i, M8i и R8i). Bare-metal экземпляры AWS (*.metal) также работают.

    • Вложенная виртуализация снижает производительность. Не ожидается, что она ослабит границу.

  • Блочное хранилище для контейнеров. Firecracker не может совместно использовать каталог хоста в гостевой системе; единственное хранилище, которое он может подключить к виртуальной машине, — это блочное устройство. Поэтому корневые файловые системы контейнеров должны существовать как блочные устройства вместо обычной файловой системы overlay. В Docker snapshotter devmapper containerd обеспечивает это. Требуется rootful Docker (эталонный дизайн использует Engine 25 или новее) с поддержкой системного containerd (2.0 или новее).

  • Исходящий сетевой доступ при построении хоста и образов. Агенты не получают этот исходящий трафик.

Это не будет работать на:

  • контейнере или поде Kubernetes, включая Docker-in-Docker и контейнерные CI-раннеры. containerd хоста, демон Docker и device-mapper не могут быть настроены изнутри контейнера, и KVM обычно там тоже недоступен;

  • rootless Docker;

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

  • macOS или Windows, включая Docker Desktop и WSL2.

Эталонный дизайн не поддерживает хосты macOS или Windows

Его песочница требует KVM на хосте Linux. Docker на Mac работает внутри общей виртуальной машины Linux, которая монтирует домашний каталог пользователя и содержит демон Docker, поэтому он не может обеспечить изоляцию оборудования для каждого агента. Если вы работаете на Mac, запустите агентов на хосте Linux с KVM (bare metal или облачная виртуальная машина с вложенной виртуализацией) и управляйте ими через SSH. Если вы создаете свою собственную песочницу на macOS или Windows, см. гипервизоры, названные в разделе Общие рекомендации выше.

Переключение хранилища образов Docker имеет побочный эффект

Образы и контейнеры, созданные в предыдущем хранилище Docker, становятся невидимыми для Docker после переключения на snapshotter devmapper. Они остаются на диске. Чтобы увидеть их снова, поместите оба параметра хранилища в daemon.json (storage-driver и features.containerd-snapshotter) обратно в то, что они были, и перезагрузите Docker.

Параметры Kata

Зафиксируйте выпуск Kata и проверьте его дайджест перед установкой. Эталонный дизайн начинается с профиля Firecracker Kata и фиксирует эти параметры в /etc/kata-containers/configuration.toml:

Параметр

Значение

Почему

jailer_path

путь к двоичному файлу jailer Kata

Запускает Firecracker внутри его тюрьмы: chroot только с файлами виртуальной машины, собственным пространством имен монтирования, пространством имен сети контейнера и фильтром seccomp Firecracker. Если не установлено, Kata запустит Firecracker без тюрьмы.

enable_annotations

[]

Контейнер не может изменять никакие параметры гипервизора через аннотации OCI.

disable_guest_seccomp

false

Профиль seccomp Docker для контейнера также применяется внутри гостевой системы, второй уровень под границей виртуальной машины.

sandbox_cgroup_only

true

Firecracker и его потоки ввода-вывода размещаются в cgroup контейнера, поэтому виртуальная машина учитывается в контейнере. Ограничивает ли лимит --memory контейнера также виртуальную машину, зависит от хоста (см. Размер).

static_sandbox_resource_mgmt

true

Firecracker не может добавлять процессоры или память к работающей виртуальной машине, поэтому виртуальная машина размер которой определяется один раз при загрузке из лимитов контейнера.

default_vcpus / default_memory

4 / 4096 MiB

Базовая линия для каждой виртуальной машины; --memory контейнера добавляется сверху. Увеличьте для целей с интенсивной сборкой (Firecracker позволяет максимум 32 vCPU на виртуальную машину).

debug_console_enabled, enable_debug

false

Нет консоли в гостевых системах и нет вывода консоли гостевой системы в логах хоста.

[factory] enable_template

false

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

entropy_source

/dev/urandom

Неблокирующая энтропия хоста для гостей.

Значения kernel, image и kernel_params, поставляемые с релизом Kata, остаются без изменений.

Сделайте ядро и образ гостя неизменяемыми

Каждая виртуальная машина загружается из одних и тех же двух файлов, Kata привязывает их к каждой тюрьме, и тюремщик запускается от root, поэтому обычные разрешения файлов не помешают скомпрометированному процессу Firecracker переписать образ, с которого загружается каждая последующая виртуальная машина. Установите флаг неизменяемости на оба файла (chattr +i). Очистка этого флага требует системного вызова, который фильтр seccomp Firecracker не разрешает, что предназначено для предотвращения этого даже root внутри тюрьмы. Очистите флаг самостоятельно перед установкой нового релиза Kata. На файловой системе без поддержки chattr используйте вместо этого привязку только для чтения.

Размер

Память

Каждая виртуальная машина агента имеет размер один раз при загрузке: default_memory плюс --memory контейнера. С базовым размером 4096 МиБ и лимитом контейнера 4g агент представляет собой виртуальную машину объёмом 8 ГиБ. Хост выделяет эту память виртуальной машине по мере её использования гостем, а не всю при загрузке, но планируйте полный объём на каждого одновременного агента: десять агентов параллельно могут вырасти до 80 ГиБ. Применяется ли лимит --memory контейнера ко всей виртуальной машине в целом, зависит от того, как организованы cgroups хоста. Проверьте, какой из этих вариантов применяется на вашем хосте:

  • Лимит контейнера применяется ко всей виртуальной машине. Агент не может использовать больше памяти хоста, чем --memory, даже если его виртуальная машина номинально больше, и виртуальная машина, превышающая лимит, убивается со стороны хоста.

  • Ничто на хосте не ограничивает виртуальную машину ниже её размера при загрузке. Использование памяти агентом ограничено размером виртуальной машины (default_memory + --memory) и собственным убийцей нехватки памяти ядра гостя.

  • Родительская cgroup ограничивает её другим значением.

Мы не подтвердили это поведение на всех типах хостов. В любом случае размер хоста по размеру виртуальной машины.

Процессоры

Каждая виртуальная машина получает default_vcpus. Firecracker не может добавлять процессоры к работающей виртуальной машине, поэтому для целей с интенсивной сборкой увеличьте значение перед запуском; максимум 32 на виртуальную машину.

Диск

Каждый образ и каждый контейнер получают виртуальный диск из тонкого пула device-mapper, который поддерживает хранилище образов. Если пул заполнится, записи внутри контейнеров завершатся с ошибками ввода-вывода или нехватки места. Если файловая система, содержащая пул, заполнится первой, пул становится доступным только для чтения и каждый контейнер на нём выходит из строя. Освободите место с помощью docker rmi и docker system prune (освобождённые блоки возвращаются в пул). sudo dmsetup status <pool> показывает использование. Для долгоживущего хоста тонкий пул LVM на выделенном диске — лучший вариант.

Время загрузки

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

Укрепление хоста

  • Посвятите хост этой задаче.

    • Предположите, что агент может прочитать что-либо на нём, и не храните там никаких учётных данных или конфиденциальных данных, кроме учётных данных API модели, которые нужны агентам.

  • Держите каждый уровень, который трафик агента касается, исправленным, не только ядро: Docker, базовые образы контейнеров прокси и любой брандмауэр или сетевое устройство между хостом и API модели. Устаревший прокси или брандмауэр на границе песочницы сам по себе является поверхностью атаки.

  • Держите ядро, KVM и микрокод процессора в актуальном состоянии и оставляйте смягчение уязвимостей процессора ядра на значениях по умолчанию.

    • grep . /sys/devices/system/cpu/vulnerabilities/* не должен показывать строк Vulnerable.

    • Если хост используется совместно с рабочими нагрузками, которые не должны наблюдать друг друга, также следуйте руководству Firecracker по настройке хоста для производства по параметрам SMT и спекулятивного выполнения.

  • Отключите подкачку (sudo swapoff -a и удалите её из /etc/fstab), чтобы память гостя не записывалась в подкачку.

  • /dev/kvm не должен быть доступен для записи всем, и каталоги установки и среды выполнения Kata должны оставаться собственностью root и не быть доступными для записи другим пользователям.

    • root:kvm с режимом 0660 достаточно для /dev/kvm, потому что среда выполнения Kata работает от root.

  • Никогда не добавляйте --privileged, --device, --cap-add или сетевые подключения хоста к контейнерам агентов или целевым сервисам.

    • В Kata эти флаги передают устройства хоста и привилегии в виртуальную машину.

  • Держите агентов во внутренней сети позади двух прокси.

    • Firecracker не выполняет фильтрацию пакетов самостоятельно; сеть на стороне хоста и прокси — это управление исходящим трафиком.

  • Держите enable_debug отключённым вне устранения неполадок; отладочное логирование включает вывод консоли гостя.

Проверка нового хоста

После настройки новой машины эта последовательность показывает, что песочница работает от начала до конца. Шаги 3 и 4 выполняют реальные вызовы модели.

  1. Запустите проверки изоляции в разделе Проверьте изоляцию самостоятельно. Две версии ядра должны отличаться. Обратите внимание, ограничивает ли лимит памяти контейнера виртуальную машину (см. Размер).

  2. Подтвердите, что CLI агента работает в среде выполнения песочницы в образе, который вы будете использовать.

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

  4. Запустите небольшой пакет от начала до конца для целевого объекта, который вы знаете. Запустите этот шаг с режимом учётных данных, который вы будете использовать для реальных взаимодействий, а не с подставным ключом API: прокси учётных данных обрабатывает каждый режим по-разному (обмен токенов для WIF, подпись для Bedrock, выпуск токенов для Vertex), и этот запуск подтверждает, что ваш работает от начала до конца. Проверьте журнал прокси учётных данных после этого.

  5. Проверьте, что ничего не осталось позади. После завершения пакета не должно остаться контейнера агента, вспомогательного контейнера, процесса виртуальной машины или прокси учётных данных. Журнал прокси исходящего трафика не должен показывать строк отказа, кроме зондов из шагов 1 и 3, а журнал прокси учётных данных должен показывать только вызовы модели.

Примечания по эксплуатации

Запуск агентов в Kata с Firecracker отличается от запуска простых контейнеров следующим образом.

Привязанные монтирования — это копии; живые файлы должны передаваться потоком

Firecracker не имеет общего доступа к файловой системе хоста, поэтому Kata копирует привязанный файл или каталог в гостя при запуске контейнера, и более поздние изменения на хосте не видны внутри. Это нормально для входных данных, которые не изменяются во время выполнения, таких как исходный код целевого объекта, и они могут оставаться монтированиями только для чтения. Никакой файл учётных данных не монтируется и не передаётся потоком, потому что контейнеры агентов не содержат ни одного (см. Прокси учётных данных). Файл, который изменяется во время выполнения, должен быть записан в контейнер оркестратором через docker exec и поддерживаться в актуальном состоянии. Копии в контейнере — это обычные файлы, которые агент под тестом может редактировать, поэтому пусть оркестратор прочитает оригиналы на хосте и судит о результатах из копии, которую агент под тестом не может достичь.

Каждому агенту нужен вспомогательный контейнер для его сети

Сетевые интерфейсы микровиртуальной машины должны существовать при загрузке виртуальной машины; Firecracker не может добавить один позже. Docker, однако, подключает сеть контейнера только после того, как среда выполнения создала контейнер. Эталонный дизайн обходит это. Сначала он запускает небольшой неактивный контейнер, подключённый к правильной сети и работающий только sleep, а затем запускает агента внутри пространства имён сети этого контейнера (--network container:<name>). Kata находит интерфейсы там при загрузке и присоединяет их к виртуальной машине. Вспомогательный контейнер служит ровно одной виртуальной машине, потому что Kata оставляет устройства сети виртуальной машины на стороне хоста в нём, поэтому создавайте и удаляйте пару вместе и не переиспользуйте вспомогательный контейнер. Один стоит неактивного процесса примерно 12 МБ.

Остановка зависшего агента

docker rm -f <agent-container> достаточно. Оркестратор должен обнаружить мёртвый контейнер, отметить выполнение как неудачное и удалить вспомогательный контейнер при разборке выполнения.

Всё адресуется по IP

Встроенный DNS Docker работает в пространстве имён сети на стороне хоста и недоступен изнутри гостевой системы, поэтому передавайте прокси-серверы агентам как IP-адреса и назначайте сетевым целям статический IP.

docker exec работает, docker cp не работает

docker exec в контейнер агента работает обычным образом; агент Kata внутри гостевой системы выполняет команду. docker cp в контейнер агента или из него не работает, потому что файлы контейнера находятся на виртуальном диске внутри гостевой системы. Используйте docker exec <container> cat <path> и подобные команды.

Firecracker работает от имени root внутри своей тюрьмы

Kata запускает jailer с uid 0, поэтому процесс Firecracker ограничен своей chroot, пространствами имён, фильтром seccomp и cgroup, а не непривилегированным идентификатором пользователя. Два файла, которые использует каждая виртуальная машина — ядро гостевой системы и образ — защищены флагом неизменяемости (см. Параметры Kata).

Kata прекратила поддержку среды выполнения, от которой зависит Firecracker

Kata запускает Firecracker через свою более старую среду выполнения Go. Kata 4.0 сделала новую среду выполнения Rust стандартной для своих других гипервизоров и прекратила поддержку среды выполнения Go. Upstream сообщает, что среда выполнения Go по-прежнему получает критические исправления ошибок и исправления CVE, и что она может быть удалена не ранее Kata 5.0. Среда выполнения Rust не указывает Firecracker среди своих гипервизоров, и upstream тестирует её интеграцию с Docker в основном с QEMU. Планируйте миграцию. Когда вы обновляете версию Kata, повторите Проверка нового хоста. Kata также может использовать Cloud Hypervisor вместо Firecracker; эталонная реализация не тестировала и не укрепляла эту конфигурацию.

Журналы

Сообщения среды выполнения Kata, Firecracker и гостевого агента поступают в журнал: journalctl -t kata. Проблемы containerd и Docker находятся в journalctl -u containerd и journalctl -u docker.

Нашли ответ на свой вопрос?