Долго сопротивлялся тому факту, что Claude Code имеет полный доступ к моему терминалу (не открытие, но я всегда на эту часть знаний закрывал глаза). Может запускать любые bash-команды. Читать ~/.ssh, переменные окружения с токенами. Всё.
Галлюки тоже с ростом проекта и его сложностью – возрастают. Например, он пытался запустить несуществующую команду. Безобидно, конечно. Но мысль осталась: а что если следующая галлюцинация будет с rm -rf или curl с моими секретами куда-нибудь не туда? Тем более что обнаруженные промпт-инъекции всё чаще находят уже те, кто пострадал.
Проблема: AI-агенты – это не просто чатботы
Есть принципиальная разница между ChatGPT в браузере и Claude Code / Cursor Agent. Первый может только текст генерировать. Вторые – выполняют команды. Реальные команды на твоей машине.
Что видит AI-агент в типичном сетапе:
Полный доступ к файловой системе (включая ~/.ssh, ~/.config)
Все переменные окружения (SERVER_1_API_KEY, BLA_BLA_ACCESS_KEY, всё что ты там экспортируешь)
Возможность запускать любые shell-команды
Историю bash с твоими прошлыми командами
Git-коммиты, хронологию и тд
Галлюцинации + shell = потенциальный риск. Как ранее говорил, AI иногда выдумывает команды, путает синтаксис, или пытается сделать «лучше» без спроса. Особенно когда контекст уже перевалил за 90% в допустимом буфере.
Пара реальных сценариев, которые могут случиться:
AI решает «почистить» временные файлы и промахивается с путём
Отправляет диагностику куда-то через curl (видел такое в логах у другого блогера)
Добавляет вредоносный MCP в конфигуратор (а supply chain атаки – уже не теория)
Читает .env файл и включает его содержимое в ответ, который уходит в API
Не то чтобы это происходит каждый день. Но когда работаешь с чем-то важным – хочется подстраховаться. Да и параноик я по жизни.
А ещё с ростом проекта ты начинаешь обзаводиться тех. долгом и сессия работы агента начинает растягиваться (у меня стабильно 10+ минут на каждую таску) + уже работаю в двух терминалах, знаю людей, у которых их уже 6+. Хочется в момент ожидания не тиктоки листать и в телеге залипать, а следующие таски запускать. Это та самая дофаминовая петля – мозг требует ещё и ещё результатов. Но такой подход ломается, если ты не запускаешь Claude в режиме без ограничений (чтобы каждый чих не апрувить и согласовывать).
Решение: Dev Containers как песочница
Использую: Dev Container. Это способ запускать окружение разработки внутри Docker-контейнера. VS Code (или Cursor) подключается к нему, и ты работаешь как обычно. Только изолированно от хост-системы.
Почему именно devcontainer, а не просто Docker:
Интеграция с IDE из коробки – расширения, терминал, отладка работают прозрачно
Стандартизированный формат – devcontainer.json понимают VS Code, Cursor, Antigravity
Удобное управление секретами через remoteEnv
Можно настроить один раз и забыть
Философия простая: AI в контейнере. Сломает что-то – пересоздашь за минуту. Хост-система в безопасности.
Чем не угодили автору изолированные git-ветки и просто deny в настройках агентов?
Я и так пользуюсь изолированными ветками для всех задач (и сессий, в которых понимаю, что будут изменения в нескольких файлах). Вернуться на пару коммитов раньше и начать заново намного быстрее, чем заново контейнер поднимать.
Deny можно замутить, но я за месяцы работы так и не смог толком сформировать глобальный файл конфигурации, чтобы его можно было ctrl+c / ctrl+v из одного проекта в другой. А ещё, поверьте, если он захочет получить доступ к файлу – он этот deny найдёт как обойти. У меня до абсурда кейс был: когда он не смог получить доступ, пошёл написал shell-скрипт, не смог его запустить, пошёл в python, сделал py-скрипт и там всё-таки добрался до нужного.
Что из себя представляет devcontainer
Дисклеймер: я очень, подчеркну, очень мало работал с контейнерами, но мне эта тема интересна. И если я где-то в чём-то перемудрил или наоборот сделал хуже – можете кинуть какашку в комментарии, но я буду безмерно благодарен, если дадите конструктивный совет 🔥
Вот примитивная конфигурация, которую использую (это проект по выгрузке постов из телеги в md-формате).
{ "name": "my-project", "build": { "dockerfile": "Dockerfile" }, "features": { "ghcr.io/devcontainers/features/node:1": { "version": "20" } }, "remoteEnv": { "TELEGRAM_API_ID": "${localEnv:TELEGRAM_API_ID}", "TELEGRAM_API_HASH": "${localEnv:TELEGRAM_API_HASH}", "ANTHROPIC_API_KEY": "${localEnv:ANTHROPIC_API_KEY}" }, "mounts": [ "source=project-data,target=/workspaces/project/data,type=volume" ], "runArgs": [ "--cap-drop=ALL", "--security-opt=no-new-privileges" ], "postCreateCommand": "bash .devcontainer/post-create.sh", "remoteUser": "vscode" }
--cap-drop=ALL – сбрасываем все Linux capabilities. Контейнер не может менять сетевые настройки, монтировать файловые системы, работать с устройствами. Только базовые операции.
--security-opt=no-new-privileges – процессы внутри контейнера не могут повышать привилегии. Даже если AI найдёт какой-то эксплойт – не сможет им воспользоваться.
remoteEnv – секреты передаются из хост-системы в контейнер, но не записываются в образ. Если кто-то получит доступ к образу – секретов там не будет.
Named volume для данных – персистентные данные (например, сессии) хранятся в Docker volume, а не в bind mount. Изоляция от хост-файловой системы.
remoteUser: vscode – работаем от непривилегированного пользователя, не от root.
Dockerfile – минимальный:
FROM mcr.microsoft.com/devcontainers/python:3.12 RUN apt-get update && apt-get install -y --no-install-recommends \ libffi-dev \ libssl-dev \ && rm -rf /var/lib/apt/lists/* WORKDIR /workspaces/project USER vscode
post-create.sh – инициализация после создания контейнера:
#!/bin/bash set -e # Node.js доступен здесь (установлен через features) sudo npm install -g @anthropic-ai/claude-code # Python окружение python -m venv .venv source .venv/bin/activate pip install -r requirements.txt
Всё это дело можно упростить следующим образом:
Открываете любого AI-агента и проект, который раньше у вас запускался не в контейнере.
Создаёте ему задачу следующего типа:
Данный проект должен иметь возможность запускаться в devcontainer. Создай необходимые файлы конфигурации. Конфигурацию создай на основе описания проекта, зависимостей. По необходимости создай скрипты по установке дополнительных инструментов после сборки образа.
Во что я вляпался, пока всё это отлаживал
Показать только результат – скучно же.
npm недоступен при сборке образа. Пу-пу-пу. Хотел установить Claude Code CLI прямо в Dockerfile через npm install -g. Получил ошибку: npm not found.
Причина: Features (включая Node.js) применяются ПОСЛЕ сборки Dockerfile. Это, видимо, особенность архитектуры devcontainers. Dockerfile собирается первым, потом накатываются features, потом запускается postCreateCommand. Ну либо я рукожоп.
Решение: перенёс установку CLI в post-create.sh. Там Node.js уже доступен.
Кэширование PATH в bash. После установки Claude Code и других CLI-полезностей через npm новый путь добавляется в PATH. Но если терминал уже открыт (а я делаю это всё внутри Cursor) – bash помнит старый PATH. Получаешь «claude: command not found», хотя всё установлено.
Решение: перезапустить терминал или выполнить hash -r для сброса кэша команд.
Секреты не пробрасываются. Настроил remoteEnv, но переменные пустые внутри контейнера.
Причина: переменные должны быть экспортированы на хосте ДО запуска контейнера. Если добавил export TELEGRAM_BLA_BLA_KEY=... после – нужно пересоздать контейнер.
Чего этот подход НЕ решает
Важно понимать ограничения.
AI всё ещё видит код проекта. Сам ору с этого тезиса, но следующая мысль важна. Если в коде есть захардкоженные секреты (не делайте так) – AI их увидит. Вычищайте всё заранее.
Сетевой доступ есть. Контейнер может делать запросы в интернет. Можно ограничить через --network none, но тогда сломается npm install, pip install, git clone и вообще всё полезное. Возиться с white-списком мне лень.
Секреты в remoteEnv доступны AI внутри контейнера. Внутри контейнера AI может прочитать эти переменные (если захочет). Разница в том, что он не видит ВСЕ секреты хост-системы – только те, что явно пробросили.
Первый запуск = сборка образа. Готовьтесь ждать несколько минут. У меня две минуты на чистую сборку. Потом кэш спасает.
Не защищает от логических ошибок. Если AI сгенерирует код с SQL-инъекцией – devcontainer никак не поможет. Это про изоляцию окружения, не про code review.
Когда это нужно, а когда overkill
Используй devcontainer, если:
У тебя на устройстве корпоративные проекты
Работаешь с реальными API-ключами и секретами
Проект связан с продакшн-инфраструктурой
Есть доступ к чувствительным данным (клиентские данные, финансы)
Хочешь воспроизводимое окружение для команды
Паранойя – твоё второе имя
Pet-проект без секретов
Личный комп, на котором ничего важного нет
Учебный код
Публичный open-source без credentials
Доверяешь AI больше, чем я
Как сделать такое же у себя?
Если решил попробовать, вот что нужно:
Установи Docker Desktop и Dev Containers (расширение для Cursor).
Создай папку .devcontainer в проекте
Добавь devcontainer.json с базовой конфигурацией
Добавь runArgs с --cap-drop=ALL и --security-opt=no-new-privileges
Пробрось только нужные секреты через remoteEnv
Установи AI-инструменты в postCreateCommand, не в Dockerfile
Проверь что всё работает: Cmd+Shift+P → «Reopen in Container» в IDE
Занимает 15-20 минут на первую настройку.
AI-агенты – новая категория инструментов, и практики безопасности для них ещё формируются. Dev Containers – один из возможных подходов, который лично мне даёт спокойствие при работе с Claude Code на проектах с секретами.
А вы как защищаете систему от AI-агентов? Или просто доверяете и не паритесь? Делитесь опытом.