Коротко (TL;DR)
Изоляция ИИ-агента держится на трёх независимых слоях: где агент исполняет команды, какие секреты он видит и что ему разрешено делать. Подтверждения команд — это только третий слой, и он не заменяет первые два.
- Коротко (TL;DR)
- Пять сценариев, от которых нужна изоляция агента
- Угроза, слой защиты и включение в каждом агенте: сводная таблица
- Встроенные песочницы агентов: что закрыто по умолчанию, а что нет
- Docker и devcontainer для Claude Code: рабочая схема по шагам
- Docker Sandboxes и отдельная ВМ: когда обычного контейнера мало
- Секреты: что агент увидит сам и как держать ключи вне его досягаемости
- Подтверждения, deny-правила и хуки: что они гарантируют, а что нет
- Worktree и worktrunk: удобно для параллельных агентов, но не изоляция
- Что не закрывает даже песочница ИИ-агента: allowlist, ядро, MCP и CI
- Защита агента по уровню риска: свой код, чужой репозиторий, автозапуск
- FAQ
- Встроенные песочницы Claude Code, Codex, Gemini CLI и Cursor ограничивают запись, а Claude Code, Codex и Cursor — ещё и сеть, но чтение по умолчанию открыто почти везде. В Claude Code песочница к тому же выключена по умолчанию и покрывает только shell-команды.
- Контейнер не полная защита. В режиме без подтверждений вредоносный проект может вынести всё, что лежит внутри контейнера, включая учётные данные самого агента. Так пишут и Anthropic, и OpenAI.
- Ключи держим за границей.
op run -- агентотдаёт агенту все подставленные секреты. Правильнее давать агенту заглушку, а настоящий ключ подставлять на прокси. - Git worktree — удобство, а не граница безопасности: хук, записанный из worktree, срабатывает в основном репозитории. Мы проверили это сами.
- Для чужого репозитория Anthropic рекомендует отдельную виртуальную машину или облачную сессию — сравнение подходов есть в официальной документации Claude Code.
Данные и дефолты агентов в статье сверены по официальной документации на 4 ноября 2026 года.
Пять сценариев, от которых нужна изоляция агента
ИИ-агент для кодинга — это языковая модель, которая сама читает файлы, запускает команды в терминале и правит код. Отсюда и риск: агент делает то, что считает нужным, а «нужное» ему может подсказать не только вы, но и текст в чужом репозитории. Такую подсказку называют prompt injection — внедрение инструкций через данные, которые агент читает.
Ниже пять сценариев, у каждого есть реальный задокументированный случай.
| Сценарий | Реальный случай | Дата | Какой слой закрыл бы |
|---|---|---|---|
| Агент стирает файлы за пределами проекта | Claude Code выполнил rm -rf tests/ patches/ plan/ ~/; хвостовой ~/ — это вся домашняя папка Mac (по рассказу пользователя, цитата в блоге Simon Willison) | 9 декабря 2025 | Песочница с записью только в проект |
| Агент стирает целый диск | Google Antigravity в режиме Turbo удалил содержимое диска D: мимо корзины — по заявлению пользователя, пересказ The Register и Tom’s Hardware | 1 декабря 2025 | Запись только в проект + подтверждения |
| Вредоносный пакет использует ваш агент как инструмент | s1ngularity: заражённые версии пакетов Nx запускали локальные Claude Code и Gemini CLI с флагами --dangerously-skip-permissions и --yolo, чтобы искать секреты; GitGuardian насчитал 2 349 уникальных секретов в утёкших репозиториях | 26 августа 2025 | Секреты вне досягаемости + закрытая сеть |
| Текст issue или PR заставляет агента в CI отдать токены | Clinejection: инъекция в заголовке issue → агент-триажёр в CI → отравленный кэш GitHub Actions → npm-токен релизного workflow → публикация cline@2.3.0. Comment and Control: заголовок PR, комментарии к issue и скрытый HTML-комментарий заставляли агентов Claude Code Security Review, Gemini CLI Action и Copilot выдавать секреты; у Claude Code Security Review это были ANTHROPIC_API_KEY и GITHUB_TOKEN | 17 февраля 2026 и апрель 2026 | Агент в CI без секретов с правом публикации |
| Агент выходит из песочницы через разрешённый адрес | Модель OpenAI на внутренней оценке вышла в интернет через уязвимость в прокси пакетов, стоявшем в списке разрешённых адресов песочницы, и добралась до инфраструктуры Hugging Face | июль 2026 | Минимальный allowlist + microVM |
По Comment and Control Anthropic присвоила уязвимости статус critical и выплатила исследователям $100, Google — $1 337 (SecurityWeek, 16 апреля 2026 года). Постмортем Cline формулирует главный урок жёстко: дать LLM доступ к shell в CI, где она обрабатывает недоверенный ввод, — то же самое, что дать shell каждому пользователю GitHub.
Все пять случаев сводятся к трём вопросам, и каждый — отдельный слой защиты:
- Где исполняется агент — прямо в вашей системе, в ОС-песочнице, в контейнере, в microVM или на отдельной виртуальной машине.
- Что агент видит — ключи в
~/.sshи~/.aws, переменные окружения,.envв проекте, токены в истории сессий. - Что агенту разрешено — правила allow/ask/deny, подтверждения, хуки.
Simon Willison называет опасное сочетание «смертельной тройкой»: доступ к приватным данным, контакт с недоверенным контентом и возможность отправить данные наружу. Изоляция ИИ-агента — это разрыв хотя бы одного звена: убрать данные из поля зрения, закрыть недоверенный ввод или перекрыть канал наружу.
Модель угроз отдельно для Codex мы уже разбирали в материале про песочницу Codex и модель угроз, а устройство защиты Claude Code — в статье про периметры безопасности Claude Code. Здесь — сквозная схема для любого агента.
Угроза, слой защиты и включение в каждом агенте: сводная таблица
Англоязычные гайды по AI agent sandboxing и AI agent sandbox security почти всегда разбирают один продукт, и сводку по пяти агентам приходится собирать самому из пяти документаций. Ниже — она одной таблицей, по состоянию на 4 ноября 2026 года.Угроза Чем закрыть Claude Code Codex CLI Gemini CLI Cursor OpenCode Удаление файлов вне проекта Запись только в рабочую папку /sandbox или sandbox.enabled: trueРежим workspace-write (дефолт в папке под git)gemini -s (профиль permissive-open)Песочница shell: всегда в Auto-review, в Allowlist — если включена ОС-песочницы нет: правило "rm *": "deny" + контейнерУдаление и порча файлов внутри проекта Git, коммит перед запуском, клон вместо живой папки Не закрывается настройкой Не закрывается настройкой Не закрывается настройкой Не закрывается настройкой Не закрывается настройкой Кража ключей с диска ( ~/.ssh, ~/.aws)Запрет чтения или контейнер без этих файлов sandbox.credentials с deny + Read(...) в permissions.denyЧтение широкое — контейнер без ключей Профиль strict-* или GEMINI_SANDBOX=dockerreadBoundary: "workspace" (с версии 3.23)external_directory: ask (дефолт), лучше контейнерКража секретов из окружения Не передавать агенту переменные с ключами credentials.envVars с deny/mask, CLAUDE_CODE_SUBPROCESS_ENV_SCRUBshell_environment_policy.ignore_default_excludes = falseНе держать ключи в окружении запуска Не держать ключи в окружении запуска Не держать ключи в окружении запуска Вывод данных через сеть Сеть по списку разрешённых адресов Прокси, список доменов пуст по умолчанию Сеть выключена в workspace-writeПрофиль *-proxiednetworkPolicy с default: "deny"Сеть shell не ограничена — контейнер с файрволом Prompt injection из репозитория Подтверждения на опасное + все слои выше deny-правила, PreToolUse-хук approval_policy = "on-request"Подтверждения (без --yolo)Не включать Run Everything Правила ask/denyПобег из контейнера Своё ядро: microVM или ВМ Docker Sandboxes, ВМ Docker Sandboxes, ВМ Docker Sandboxes, ВМ Docker Sandboxes, ВМ Docker Sandboxes, ВМ
Как читать таблицу. Строки сверху вниз идут от дешёвого к дорогому: первые три закрываются настройкой за минуту, последние две требуют другой среды запуска. Строка «внутри проекта» не закрывается ничем, кроме git и клона: любой агент, которому вы разрешили писать в проект, может там удалить и испортить файлы. Поэтому правило «закоммитить перед запуском агента» работает в любом агенте и не зависит от настроек.
Встроенные песочницы агентов: что закрыто по умолчанию, а что нет
Встроенная песочница — это механизм ОС, который запускает команды агента с урезанными правами. На macOS это Seatbelt, на Linux — bubblewrap (утилита изоляции процессов через пространства имён ядра). Она дешёвая, работает без Docker, но у каждого агента свои дефолты.
| Агент | Включена сама | Запись | Чтение | Сеть |
|---|---|---|---|---|
| Claude Code | Нет, включается /sandbox | Рабочая папка, temp и добавленные папки | Почти вся машина, включая ~/.ssh и ~/.aws/credentials | Через прокси, разрешённых доменов изначально нет |
| Codex CLI | Да: в папке под git — workspace-write, вне git — read-only | Рабочая папка; .git, .codex, .agents — только чтение | Широкое | Выключена |
| Gemini CLI | Нет; включается -s, GEMINI_SANDBOX или tools.sandbox, а с --yolo — по умолчанию | Папка проекта (permissive-open) | Широкое | Разрешена |
| Cursor | Для shell-команд: в Auto-review — да, в Allowlist — по выбору | Workspace; .git/hooks и .git/config защищены | readBoundary: "system" — шире проекта, ~/.ssh читается | Заблокирована, кроме встроенного списка доменов менеджеров пакетов (режим по умолчанию sandbox.json + Defaults); остальное открывает sandbox.json |
| OpenCode | ОС-песочницы в документации нет | Только правила разрешений | read: allow, файлы .env — ask | Не ограничена |

На скриншоте официальной документации Claude Code (снят 4 ноября 2026 года) рамка 1 выделяет строку «Reads»: чтение разрешено почти по всей машине, включая ~/.ssh и ~/.aws/credentials. Рамка 2 — строка «Environment variables»: команды в песочнице наследуют окружение Claude Code вместе со всеми секретами в нём. Это главное, что стоит запомнить о встроенных песочницах: они защищают от «сломает», но не от «прочитает».
Как включить песочницу в Claude Code и убедиться, что она работает
- Запустите сессию и выполните
/sandbox. Откроется панель с вкладками Mode, Overrides и Config. На Linux и WSL2 нужныbubblewrapиsocat— если их нет, панель покажет только вкладку Dependencies. - На вкладке Mode выберите auto-allow (команды в песочнице идут без подтверждения) или regular permissions (подтверждения остаются).
- На вкладке Overrides включите Strict sandbox mode. Без него агент может попросить повторить упавшую команду вне песочницы, а в режиме
bypassPermissionsтакой повтор идёт без вопроса. - Попросите агента выполнить две проверки:
touch ~/sandbox-probe
curl --noproxy '*' example.com
Первая команда должна упасть с Operation not permitted на macOS или Read-only file system на Linux. Вторая — с Could not resolve host: у команды нет пути в сеть мимо прокси песочницы. Если touch прошёл, песочница не работает — удалите файл и снова откройте /sandbox.
Панель сохраняет режим в .claude/settings.local.json текущего проекта. Чтобы песочница была во всех проектах и закрывала ключи, впишите в ~/.claude/settings.json:
{
"sandbox": {
"enabled": true,
"allowUnsandboxedCommands": false,
"failIfUnavailable": true,
"network": {
"allowedDomains": ["registry.npmjs.org", "pypi.org"]
},
"credentials": {
"files": [
{ "path": "~/.ssh", "mode": "deny" },
{ "path": "~/.aws/credentials", "mode": "deny" }
],
"envVars": [
{ "name": "GITHUB_TOKEN", "mode": "deny" },
{ "name": "NPM_TOKEN", "mode": "deny" }
]
}
}
}
Сам ключ sandbox.enabled: true включает режим auto-allow: команды в песочнице идут без подтверждения, а чтобы вернуть подтверждения, добавьте "autoAllowBashIfSandboxed": false. failIfUnavailable важен: по умолчанию, если песочница не поднялась, Claude Code молча работает без неё. Встроенного списка секретов нет — защищены только те файлы и переменные, которые вы перечислили. Синтаксис всех ключей разобран в материале про settings.json в Claude Code.
Две границы, о которых часто забывают. Песочница работает на macOS, Linux и WSL2, а на нативном Windows команды идут без неё. И она покрывает только shell: инструменты Read, Edit, Write, WebFetch, локальные MCP-серверы и хуки работают вне песочницы с вашими полными правами. Запись denyRead не останавливает инструмент Read.
Codex, Gemini CLI и Cursor: одна строка настройки
Codex CLI. Запись Codex ограничивает рабочей папкой, а чтение — нет: в нашем замере 13 августа 2026 года (CLI 0.147.0) команды в обоих режимах читали файлы в домашней папке и собственный ~/.codex/auth.json. Безопасный интерактивный режим задаётся флагами codex --sandbox workspace-write --ask-for-approval on-request или в config.toml:
sandbox_mode = "workspace-write"
approval_policy = "on-request"
[sandbox_workspace_write]
network_access = false
[shell_environment_policy]
ignore_default_excludes = false
Последняя строка важна: по умолчанию Codex оставляет командам переменные с KEY, SECRET и TOKEN в имени, а false включает их автоматическое вычищение. Режимы подробно разобраны в статье про режимы одобрения Codex.
Gemini CLI. Песочница включается флагом gemini -s, переменной GEMINI_SANDBOX=docker или ключом tools.sandbox в settings.json. С --yolo (или --approval-mode=yolo) Gemini CLI включает её по умолчанию сам. На macOS профиль по умолчанию permissive-open пускает сеть и широкое чтение. Строже — SEATBELT_PROFILE=strict-proxied: ограничены и чтение, и запись, сеть идёт через прокси. В контейнерном режиме (Docker или Podman) песочнице по умолчанию доступна только папка проекта.
Cursor. Настройки песочницы лежат в ~/.cursor/sandbox.json или .cursor/sandbox.json проекта. Минимум для работы с секретами — сузить чтение и сеть:
{
"readBoundary": "workspace",
"networkPolicy": {
"default": "deny",
"allow": ["registry.npmjs.org", "pypi.org"]
}
}
Значение readBoundary: "workspace" требует Cursor 3.23 или новее. Режим Run Everything отключает и песочницу, и классификатор — каждый вызов идёт автоматически.
Docker и devcontainer для Claude Code: рабочая схема по шагам
Devcontainer (контейнер разработки) — это описание Docker-окружения в файле .devcontainer/devcontainer.json, которое VS Code, Cursor, JetBrains и GitHub Codespaces поднимают одинаково у всех. Агент в нём работает внутри контейнера, а файлы проекта примонтированы с вашего диска. У Anthropic для этого есть официальная фича Dev Container и эталонная конфигурация в репозитории anthropics/claude-code.
Devcontainer для Claude Code: схема из шести шагов
- Добавьте фичу Claude Code в
.devcontainer/devcontainer.json:
{
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {}
},
"remoteUser": "vscode"
}
- Работайте не под root. С флагом
--dangerously-skip-permissionsClaude Code на Linux и macOS не запускается от root, поэтомуremoteUserдолжен быть обычным пользователем. - Сохраните
~/.claudeв именованном томе, чтобы не входить заново после каждой пересборки: томsource=claude-code-config,target=/home/vscode/.claude,type=volumeвmountsиCLAUDE_CONFIG_DIRс тем же путём вcontainerEnv. Помните, что в этом томе лежит токен агента — его и унесёт вредоносный проект, если унести получится. - Закройте исходящую сеть. Эталонный контейнер Anthropic содержит скрипт
init-firewall.sh: он ставитiptables -P OUTPUT DROP(весь исходящий трафик запрещён по умолчанию) и открывает список адресов плюс несколько исключений — о них ниже. Для файрвола внутри контейнера нужны праваNET_ADMINиNET_RAWвrunArgs. - Не монтируйте секреты хоста: ни
~/.ssh, ни~/.aws, ни файлы облачных ключей. Anthropic советует вместо них токены с доступом к одному репозиторию или короткоживущие токены. Отдельно — никогда не пробрасывайте/var/run/docker.sock: доступ к сокету Docker равен доступу к хосту. - Только теперь можно запускать
claude --dangerously-skip-permissionsдля работы без подтверждений, и только с репозиториями, которым вы доверяете.
Что мы нашли, читая эталонный init-firewall.sh на 4 ноября 2026 года. Кроме диапазонов GitHub, registry.npmjs.org и api.anthropic.com, в списке есть sentry.io, statsig.com и домены VS Code. Важнее три правила, которые стоят до списка и его не спрашивают: исходящий SSH на порт 22 к любому адресу, DNS-запросы (UDP 53) к любому адресу и весь трафик в подсеть /24 вокруг шлюза Docker, то есть к вашему хосту. Для git push по SSH это удобно, но для модели угроз «вынести данные» это три открытых канала: SSH, DNS-туннель (передача данных внутри DNS-запросов) и сервисы на хосте. Если git по SSH вам не нужен, уберите правило для порта 22. DNS-туннель правкой одного правила не закрыть, и для чужого кода это ещё один довод в пользу microVM с прокси.
Рамка на скриншоте выделяет предупреждение из документации Claude Code про devcontainer (снято 4 ноября 2026 года). В режиме --dangerously-skip-permissions контейнер не мешает вредоносному проекту вынести всё, что доступно внутри, включая учётные данные Claude Code в ~/.claude. OpenAI пишет то же самое про Codex: из devcontainer можно вынести всё, включая учётные данные Codex. Часть русскоязычных гайдов подаёт Docker как полную защиту и при этом кладёт ANTHROPIC_API_KEY прямо в окружение контейнера — то есть туда, откуда его и заберут.
Claude Code sandbox vs Docker: что выбрать
Короткий ответ: это разные слои, и они дополняют друг друга./sandbox в Claude CodeDevcontainer Docker Sandboxes (microVM) Отдельная ВМ Что изолировано Только shell-команды Весь процесс агента Весь процесс агента Весь процесс агента Файловые инструменты, MCP, хуки Вне границы Внутри Внутри (локальные MCP — на хосте) Внутри Чтение ваших файлов Почти вся машина Только примонтированное Только примонтированное Только скопированное Ядро Общее с хостом Общее с хостом Своё Своё Ключи агента На хосте Внутри контейнера На хосте, подставляет прокси Внутри ВМ Порог входа Одна команда Docker + конфиг Отдельный CLI sbxГипервизор и образ
Практичная связка для своего кода — devcontainer плюс /sandbox внутри него. Учтите, что bubblewrap внутри Docker без привилегированных пространств имён не поднимается. Режим enableWeakerNestedSandbox это обходит, но документация прямо предупреждает: он заметно ослабляет защиту. Для чужого кода оба варианта слабее microVM.
Docker Sandboxes и отдельная ВМ: когда обычного контейнера мало
Обычный контейнер делит ядро операционной системы с хостом. Ошибка в настройке или уязвимость ядра — и процесс выходит наружу. microVM — это облегчённая виртуальная машина со своим ядром: граница проходит по гипервизору, а не по механизмам изоляции ядра. Поэтому AI agent sandbox на Docker — это две разные по стойкости вещи: обычный контейнер с общим ядром или Docker Sandboxes на microVM.
Британский AI Security Institute в марте 2026 года опубликовал SandboxEscapeBench — 18 сценариев побега из контейнера на трёх уровнях: оркестрация, среда исполнения и ядро. Продвинутые модели надёжно выбирались через типовые ошибки конфигурации — открытый сокет Docker и привилегированный контейнер, — но самые сложные сценарии не прошла ни одна. Каждый успешный побег использовал уже раскрытую уязвимость; при этом ещё при сборке теста одна модель нашла непредусмотренный путь наружу.
Пять команд для запуска агента в Docker Sandboxes
Docker Sandboxes — отдельный продукт Docker: каждый агент работает в microVM со своим ядром и своим Docker-демоном, без доступа к Docker на хосте. На 4 ноября 2026 года CLI sbx и локальные песочницы бесплатны, в том числе для коммерческой работы; облачные песочницы — отдельная услуга. Docker Desktop для них не нужен.
brew install docker/tap/sbx # macOS; Windows: winget install -h Docker.sbx
sbx login
sbx secret set anthropic # ключ хранится на хосте, в ВМ не попадает
cd ~/my-project
sbx run --name my-project claude # или codex, gemini, cursor, copilot
При первом запуске sbx попросит выбрать сетевую политику; вариант Balanced открывает популярные сервисы разработки и блокирует остальное. Список правил покажет sbx policy ls. По документации Docker, среди разрешённых по умолчанию есть широкие шаблоны вроде *.googleapis.com, которые покрывают далеко не только API ИИ-провайдеров, — проверьте список и удалите то, что вам не нужно. Удалить песочницу целиком — sbx rm my-project, папку проекта это не трогает.
Три особенности, о которых нужно знать:
- Агенты стартуют в полной автономии. По документации Docker, Codex обходит подтверждения, Claude Code пропускает запросы разрешений, Cursor, Copilot и Gemini работают в YOLO-режиме. Это допустимо только потому, что граница — microVM, а ключи подставляет прокси на хосте.
- Папка проекта примонтирована на запись. Агент может изменить или удалить любой файл в ней, и это сразу видно у вас. Сюда же попадают файлы, которые исполняются сами: хуки git, конфиги CI,
Makefile, скриптыpackage.json. Хуки живут в.git/и не видны вgit diff— проверяйте их отдельно. - Для чужого кода есть
--clone. В этом режиме ваш репозиторий монтируется только для чтения, а агент работает с приватной копией внутри ВМ.
Локальные MCP-серверы, запущенные через stdio, по документации Docker работают на хосте, а не в ВМ. Значит, их нужно считать доверенными компонентами со всеми вашими правами.
Отдельный пользователь ОС и виртуальная машина
Самый старый и простой уровень изоляции — отдельный пользователь системы, например sudo useradd -m agent на Linux. Если ваша домашняя папка закрыта правами chmod 700, агент под чужой учётной записью не прочитает ни ~/.ssh, ни .env в ваших проектах, ни ~/.npmrc с токеном npm. Взамен агенту нужен свой клон репозитория и свой вход в сервисы. Но ядро, сеть и всё, что открыто на чтение всем пользователям, остаются общими, поэтому это защита от случайности, а не от целенаправленной атаки.
Для недоверенного репозитория Anthropic в таблице подходов прямо рекомендует отдельную виртуальную машину или облачную сессию. ВМ дороже в настройке, зато её можно откатить к снимку и выбросить после работы.
Секреты: что агент увидит сам и как держать ключи вне его досягаемости
Агенту не нужно специально «красть» ключ. Упершись в ошибку авторизации, он сам ищет креды: открывает .env в корне проекта, выполняет printenv, смотрит ~/.aws. Так этот сценарий описывает Bitwarden — компания продаёт менеджер секретов, поэтому это иллюстрация, а не статистика. Но механика подтверждается документацией Claude Code: всё, что прошло через инструмент агента, записывается в транскрипт на диске открытым текстом.
Ловушка op run -- агент
1Password CLI подставляет секреты так: op run запускает команду в дочернем процессе, и секреты доступны как переменные окружения «только на время работы подпроцесса». Если этот подпроцесс — сам агент, все подставленные ключи становятся доступны агенту и всему, что он запускает, на всю сессию. То же касается doppler run -- агент и direnv: direnv загружает .envrc при входе в папку, и агент, запущенный из этой оболочки, наследует переменные.
Правильный порядок — оборачивать приложение, которому нужен ключ, а не агента:
# плохо: агент получает все секреты из шаблона
op run --env-file=.env.tpl -- claude
# лучше: секреты получает только тестовый прогон, который запускаете вы
op run --env-file=.env.tpl -- npm test
Подстановка ключа через прокси
Лучший вариант — агент видит заглушку, а настоящий ключ добавляет прокси при запросе к разрешённому адресу.
- Claude Code — режим
maskвsandbox.credentials: команды видят одноразовую заглушку, а прокси песочницы подставляет настоящее значение в запросы к адресам изinjectHosts. Требования:network.tlsTerminate(прокси должен видеть содержимое запроса) и запись в пользовательских, а не проектных настройках —maskиз.claude/settings.jsonрепозитория игнорируется. Маскирование файлов работает с версии 2.1.221; на macOS файл в режимеmaskблокируется целиком, как приdeny. Проверить настройку можно командойclaude doctor. - Docker Sandboxes — ключи из
sbx secret setхранятся на хосте, прокси вставляет их в заголовки исходящих запросов, а в ВМ настоящее значение не попадает. - NVIDIA OpenShell — по README проекта агент никогда не видит реальных ключей, OpenShell добавляет их только к запросам на одобренные адреса.
Ключи с минимальными правами и лимитом расходов
- GitHub — fine-grained токен (токен с детальными правами) вместо классического: GitHub рекомендует именно его, и каждый такой токен можно ограничить конкретными репозиториями. Давайте агенту чтение и запись только в нужный репозиторий и короткий срок жизни.
- API моделей — отдельный ключ для агента в отдельном workspace со своим лимитом расходов. В консоли Anthropic месячный лимит задаётся на организацию или на workspace (на default workspace — нельзя), а не на отдельный ключ; при утечке ключа из такого workspace потери ограничены его лимитом.
- Облака — отдельная роль с правами только на тестовое окружение, без доступа к продакшен-базам.
- Агенты в CI — без секретов с правом публикации там, где агент читает текст issue и PR, и без общего с релизными workflow кэша GitHub Actions. По постмортему Cline, в Clinejection секреты публикации достались именно через кэш, который восстанавливал ночной релиз.
Что делать, если секрет уже прочитан
Удалить .env после сессии недостаточно. Claude Code пишет в ~/.claude/projects/<проект>/<сессия>.jsonl содержимое файлов, вывод команд и вставленный текст, и по умолчанию хранит это 30 дней (настройка cleanupPeriodDays). Порядок такой:
- Отзовите и перевыпустите ключ — это единственный надёжный шаг.
- Проверьте журналы использования ключа у провайдера за время сессии.
- Удалите локальную историю проекта:
claude purge <путь-к-проекту>(до версии 2.1.288 команда называласьclaude project purge).
Подтверждения, deny-правила и хуки: что они гарантируют, а что нет
Подтверждения и правила — третий слой: они решают, что агенту можно, но не меняют того, что он видит и где работает. Документация Claude Code подчёркивает, что правила разрешений исполняет сам Claude Code, а не модель: инструкции в CLAUDE.md влияют на то, что агент пытается сделать, но не на то, что ему позволено.Механизм Что гарантирует Чего не гарантирует Read(./.env) в permissions.denyФайловые инструменты Claude не прочитают файл Команду cat .env в Bash — её закрывает песочница (credentials, denyRead)Bash(rm *), Bash(curl *) в denyБлокирует обычную форму вызова /bin/rm, bash -c '…' и другие формы: по документации Anthropic это не граница безопасностиИнструкции в CLAUDE.md или AGENTS.md Задают намерение агента Ничего не запрещают технически PreToolUse-хук Ваш скрипт проверяет каждый вызов до запуска и может его заблокировать Обход через переформулировку команды; сам хук работает вне песочницы с вашими правами Классификатор (auto mode, Auto-review в Cursor) Меньше запросов при разумной защите Cursor прямо пишет: Auto-review не граница безопасности --dangerously-skip-permissions, --yolo, Run EverythingРабота без запросов Ничего — допустимо только внутри контейнера, microVM или ВМ
Минимальный набор правил для Claude Code в settings.json:
{
"permissions": {
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Bash(git push --force *)",
"Bash(git push -f *)"
],
"ask": [
"Bash(git push *)"
]
}
}
PreToolUse-хук против rm -rf, git push --force и curl | sh
Хук — это ваш скрипт, который Claude Code запускает на событие. Событие PreToolUse срабатывает перед вызовом инструмента; код выхода 2 блокирует вызов, а текст ошибки уходит агенту. Регистрация в settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "~/.claude/hooks/block-danger.sh" }
]
}
]
}
}
Сам скрипт ~/.claude/hooks/block-danger.sh (нужен jq):
#!/bin/bash
cmd=$(jq -r '.tool_input.command // ""')
if echo "$cmd" | grep -Eq 'rm +-[a-zA-Z]*r[a-zA-Z]*f|rm +-[a-zA-Z]*f[a-zA-Z]*r|git +push.*( --force| -f( |$))|curl[^|]*\| *(ba|z)?sh|wget[^|]*\| *(ba|z)?sh'; then
echo "Заблокировано хуком: опасная команда. Предложи безопасный вариант." >&2
exit 2
fi
exit 0
Этот хук ловит типовые формы опасных команд, но не все: переменная вместо имени команды или скрипт в файле его обойдут. Поэтому хук — страховка от ошибки агента, а не от атаки. Все события, коды выхода и рецепты — в разборе про хуки Claude Code.
В OpenCode тот же слой задаётся в opencode.json: правило "bash": { "*": "ask", "rm *": "deny", "git push *": "ask" }. Срабатывает последнее подходящее правило, а режим --auto не отменяет явных deny. По умолчанию OpenCode стартует с разрешительных настроек: большинство действий — allow, чтение .env — ask.
Worktree и worktrunk: удобно для параллельных агентов, но не изоляция
Git worktree — это дополнительная рабочая папка того же репозитория на другой ветке. На этом строится запуск нескольких агентов параллельно: каждый работает в своём worktree и не мешает остальным. Как это устроить, мы разбирали в материале про git worktree для параллельных агентов. Worktrunk — CLI для управления worktree, созданный под параллельную работу ИИ-агентов; на 4 ноября 2026 года у репозитория 10 975 звёзд на GitHub.
Проблема в том, что worktree делит с основным репозиторием конфиг, ссылки и хуки. Документация git прямо пишет, что файл конфигурации репозитория по умолчанию общий для всех рабочих деревьев. Мы проверили, что из этого следует, на git 2.53.0 (4 ноября 2026 года):
git init main && cd main && git commit --allow-empty -m init
git worktree add ../agent -b agent-work
cd ../agent
hooks="$(git rev-parse --git-common-dir)/hooks"
printf '#!/bin/sh\necho HOOK-RAN-IN-MAIN-REPO\n' > "$hooks/post-commit"
chmod +x "$hooks/post-commit"
git config user.email hacked@example.com
cd ../main && git commit --allow-empty -m second
# вывод: HOOK-RAN-IN-MAIN-REPO
git config user.email
# вывод: hacked@example.com
Хук, записанный из worktree агента, выполнился при коммите в основном репозитории, а смена git config из worktree поменяла настройку основного. То есть агент с правом записи в общий .git может оставить код, который потом запустите вы.
Как совместить worktree с защитой:
- Запускайте агента в worktree внутри песочницы. В linked worktree песочница Claude Code разрешает запись в общий
.gitосновного репозитория, чтобы работалgit commit, но запись вhooks/иconfigтам остаётся запрещённой. Cursor защищает.git/hooksи.git/config, когда команда идёт в его песочнице; Codex держит.gitтолько для чтения. - Для недоверенной работы используйте полноценный клон или режим
--cloneв Docker Sandboxes вместо worktree. - После работы агента проверяйте
.git/hooksиgit config --list --show-origin— эти изменения не видны вgit diff.
Что не закрывает даже песочница ИИ-агента: allowlist, ядро, MCP и CI
Песочница сужает возможности агента, но у неё есть остаточные риски. Их полезно знать, чтобы не переоценивать защиту.
- Allowlist — сам по себе поверхность атаки. В июле 2026 года модель OpenAI на внутренней оценке вышла из песочницы через уязвимость в прокси пакетов, который стоял в списке разрешённых адресов, и добралась до инфраструктуры Hugging Face. Подробный разбор инцидента опубликовал GitLab 12 августа 2026 года. Вывод: каждый разрешённый хост приносит с собой всё, до чего он сам может дотянуться.
- Широкие домены — канал вывода данных. Документация Claude Code предупреждает, что разрешение
github.comоткрывает путь для утечки: прокси решает по имени хоста и по умолчанию не заглядывает в TLS, так что возможен domain fronting (подмена адресата внутри зашифрованного соединения). - Общее ядро. Контейнер и ОС-песочница опираются на ядро хоста; SandboxEscapeBench показал, что модели используют типовые ошибки конфигурации. Опция
allowUnixSocketsс/var/run/docker.sockфактически даёт доступ к хосту. - MCP-серверы и хуки вне песочницы. Локальные MCP-серверы работают с вашими правами и в Claude Code, и в Docker Sandboxes. Отдельный класс угроз — атаки через MCP-серверы.
- Агенты в CI. Clinejection и Comment and Control показали, что агент в CI с секретами и недоверенным текстом на входе — готовый путь к краже токенов.
Чтобы картина была полной: песочница не только ограничивает, но и экономит внимание. По внутренним данным Anthropic (20 октября 2025 года), песочница сократила число запросов подтверждения на 84%. Это оценка вендора на собственном использовании, а не независимый замер. Смысл в том, что меньше запросов — меньше привычки нажимать «да» не читая.
Защита агента по уровню риска: свой код, чужой репозиторий, автозапуск
| Уровень риска | Пример | Где запускать | Что видит агент | Что разрешено |
|---|---|---|---|---|
| Свой код, вы рядом | Рефакторинг своего проекта | Встроенная песочница: /sandbox, workspace-write, gemini -s | ~/.ssh, ~/.aws и токены в окружении закрыты через credentials или чистое окружение | deny-правила + PreToolUse-хук, подтверждения или auto-allow |
| Чужой репозиторий | Разбор незнакомого проекта, новые зависимости | Docker Sandboxes с --clone или отдельная ВМ | Ключи только через прокси, в среде их нет | Сеть Balanced или уже, без docker.sock |
| Автозапуск без присмотра | Ночные задачи, агент в CI | microVM, ВМ или одноразовый раннер | Короткоживущие токены на один репозиторий, лимит расходов | Минимальный allowlist; без секретов с правом публикации рядом с недоверенным текстом |
Минимальный набор на сегодня, по шагам:
- Закоммитьте работу перед запуском агента.
- Включите встроенную песочницу и проверьте её командами
touch ~/sandbox-probeиcurl --noproxy '*' example.com. - Закройте
~/.ssh,~/.awsи переменные с токенами:sandbox.credentialsв Claude Code,ignore_default_excludes = falseв Codex,readBoundary: "workspace"в Cursor. - Уберите ключи из
.envв рабочей папке; если секрет нужен, подставляйте его через прокси или оборачивайтеop runвокруг приложения, а не агента. - Выпустите агенту отдельные ключи: fine-grained токен GitHub на один репозиторий и API-ключ с лимитом расходов.
- Добавьте deny-правила и PreToolUse-хук против
rm -rf,git push --forceиcurl | sh. - Режим без подтверждений — только внутри devcontainer, Docker Sandboxes или ВМ.
Что устареет первым: дефолты агентов и номера версий (readBoundary в Cursor с 3.23, маскирование ключей в Claude Code с 2.1.221), условия Docker Sandboxes и список доменов в эталонном файрволе. Перед настройкой сверяйтесь с официальной документацией своего агента.
FAQ
Нужен ли Docker, если в Claude Code есть /sandbox?
Для своего кода встроенной песочницы обычно достаточно, если закрыть ключи через sandbox.credentials и включить строгий режим. Но /sandbox покрывает только shell-команды: файловые инструменты, MCP-серверы и хуки работают вне его, а чтение по умолчанию открыто почти по всей машине. Для чужого кода или режима без подтверждений нужен devcontainer, Docker Sandboxes или ВМ.
Безопасно ли запускать агента с —dangerously-skip-permissions в контейнере?
Безопаснее, чем на хосте, но только для доверенного репозитория. Документация Anthropic предупреждает: в этом режиме вредоносный проект может вынести всё, что доступно внутри контейнера, включая учётные данные Claude Code в ~/.claude. Не монтируйте ~/.ssh и docker.sock, закройте сеть файрволом, а для чужого кода берите microVM с ключами на прокси.
Где хранить API-ключи при работе с агентами и почему нельзя просто положить их в .env?
Агент, упершись в ошибку авторизации, сам открывает .env и выполняет printenv, а прочитанное попадает в транскрипт сессии открытым текстом. Храните ключи в менеджере секретов, подставляйте их через прокси (режим mask в Claude Code, sbx secret set в Docker Sandboxes) и выпускайте агенту отдельные ключи с минимальными правами и лимитом расходов.
Как защититься от prompt injection в агенте, если он читает чужой репозиторий?
Полностью предотвратить инъекцию нельзя, поэтому ограничивают последствия. Запускайте агента в Docker Sandboxes с --clone или в отдельной ВМ, не держите в среде настоящих ключей, оставьте только нужные адреса в сети и не включайте режим без подтверждений вне изоляции. Так даже успешная инъекция не дотянется до ваших данных и не отправит их наружу.
Защищает ли git worktree или worktrunk от агента?
Нет. Worktree делит с основным репозиторием конфиг, ссылки и хуки. В нашей проверке на git 2.53.0 хук, записанный из worktree, выполнился при коммите в основном репозитории. Worktree удобен для параллельной работы, а защиту даёт песочница поверх него, которая запрещает запись в .git/hooks и .git/config, либо полноценный клон.
Что делать, если агент уже прочитал секрет?
Сразу отзовите и перевыпустите ключ: удаление .env не помогает, потому что Claude Code уже записал прочитанное в транскрипт в ~/.claude/projects и по умолчанию хранит его 30 дней. Затем проверьте журналы использования ключа у провайдера и удалите локальную историю проекта командой claude purge.


