Краткий ответ
Считайте, что любой агентный ИИ-инструмент для кода (из тех, что читают ваши файлы и правят код) может передать ваш репозиторий своему вендору. Некоторые делают это при запуске, до любого промпта. Чтобы защититься: (1) никогда не запускайте интерактивный агентный CLI внутри репо с секретами или кодом, который нельзя разглашать; (2) держите секреты вне отслеживаемого дерева (.gitignore) и вне файлов, которые агент читает; (3) предпочитайте headless-режимы одного вызова или REST API интерактивной сессии; (4) если необходимо — в одноразовой папке без ничего чувствительного. Проверяйте прежде чем доверять — метод ниже.
Что только что произошло — случай Grok Build
12 июля 2026 независимые тестировщики сообщили, что Grok Build (агентный CLI от xAI, v0.2.93) выгружает весь git-репозиторий пользователя — как bundle, включающий полную историю и файлы, которые агент ни разу не открывал — в Google Cloud Storage от xAI. Тесты зафиксировали, как машину покидают несколько гигабайт данных репозитория.
На прямой вопрос официальный аккаунт @grok от xAI подтвердил это своими словами: «Независимый анализ на уровне сети (захваты mitmproxy + тесты canary-файлов) подтверждает, что Grok Build CLI по умолчанию выгружает ваш полный Git-репозиторий как bundle — включая полную историю и файлы, которые агент никогда не читает — в Google Cloud Storage от xAI. Прочитанные файлы вроде секретов .env также отправляются дословно. Это не останавливается тумблером 'Улучшать модель'.» Добавив, что выгрузка — это «текущий дизайн ради надёжной агентной работы», а гранулярные средства контроля «в активной разработке».
Важнейшее для вашей модели угроз: выгрузка срабатывает при запуске инструмента, а не когда вы просите его что-то сделать. Пользователь, открывший его и не набравший ничего, всё равно увидел свой репо отправленным.
Почему агентные инструменты так делают
Это (не обязательно) злой умысел — это дизайн. Агент, рассуждающий по всей вашей кодовой базе, хочет полный, согласованный контекст: каждый файл, git-историю, связи между модулями, чтобы его субагенты и worktree не работали из битого частичного вида. Быстрейший способ дать это облачной модели — сразу отправить весь репо. Удобство для агента, экспозиция для вас.
Этот компромисс невидим, пока вы не посмотрите. Инструмент «просто работает», а несколько гигабайт, покидающих вашу сетевую карту, не появляются в окне чата. Это ровно тот тип дефолта, который privacy-ориентированный оператор обязан считать присутствующим, пока не доказано обратное.
Что на самом деле утекает
- Весь отслеживаемый исходник — каждый закоммиченный в git файл, читал его агент или нет.
- Полная история коммитов — не только текущее дерево. Всё, что когда-либо коммитили и потом «удалили», живёт в истории и уходит с bundle. Удаление секрета в позднем коммите не удаляет его из репозитория.
- Файлы, которые агент читает — отправляются дословно. Если он открывает
.env, чтобы понять конфиг, содержимое этого файла уходит с ним, даже если файл в gitignore. - Не регулируется очевидным тумблером — в случае Grok опт-аут «Улучшать модель» не остановил выгрузку. Опт-ауты, от которых вы ждёте помощи, могут не касаться этого пути.
Арифметика риска — что спасает, а что нет
Два механизма определяют вашу экспозицию:
- Git-bundle несёт отслеживаемые файлы + историю. Так что секрет, который никогда не коммитили — в gitignore-файле вроде
.env/.dev.vars— не попадает в bundle. Вот почему дисциплина.gitignore— ваша первая и самая дешёвая линия защиты. - Захват читаемых файлов несёт всё, что агент открывает, в gitignore оно или нет. Так что одного
.gitignoreнедостаточно, если вы затем даёте агенту прочитать файл секретов. Держите секреты полностью вне досягаемости агента.
Реальный пример: мы проверили собственную экспозицию после запуска агентного CLI в настоящем репо. Наши боевые секреты лежали в gitignore-нутом, никогда не коммиченном .dev.vars — так что их не было в выгруженном bundle. Единственный отслеживаемый env-файл содержал публичный site-ключ (безопасный по дизайну). Итог: исходник и история ушли; секреты — нет. Границу провёл .gitignore. Для репо, коммитящего свой .env, всё могло бы пойти наоборот.
Дело не только в репо — сессия забирает всё ваше окружение
Вот часть, которая делает .gitignore ложным утешением. Когда разработчик заставил второй ИИ-агент (CLI OpenAI Codex) проверить, что интерактивный инструмент на самом деле сделал на его Mac, аудит обнаружил, что утёкший контекст ушёл далеко за пределы отслеживаемого репо. Вместе с git-bundle сессия захватила:
- дерево каталогов соседнего проекта — раскладку исходников, файлы пакетов, имена ассетов и зависимостей, о которых её не спрашивали;
- текст документа передачи / заметок, лежавшего в том проекте;
- вывод терминала с именем пользователя macOS, именами локальных аккаунтов и адресом email — реальную идентичность, а не код;
- пути к локальным проектным и сессионным файлам другого ИИ-инструмента — по сути карту остального стека разработчика.
Ничто из этого не входит в ведение .gitignore. Gitignore держит файлы вне git-bundle; он ничего не делает с выводом терминала, файлами в соседних папках или отпечатками ваших других инструментов, которые интерактивная сессия читает и вплетает в свой контекст. В момент, когда вы открываете агентную сессию в рабочем окружении, окружение и есть поверхность атаки — ваше имя пользователя, email, соседние репо, ваши заметки. Для псевдонимного оператора пара «имя-плюс-email» — это всё: одна выгрузка может свести на нет месяцы компартментализации.
Урок не «gitignore-ить сильнее». А в том, что единственная надёжная граница — это каталог, в котором вы запускаете инструмент, и всё, до чего этот каталог и ваш shell могут дотянуться. Считайте, что интерактивный агентный CLI фотографирует всю комнату, а не только файл на столе.
Проверьте свой инструмент — метод, что переживёт новость
Не верьте блогу вендора или скриншоту незнакомца, включая этот. Проверяйте на своей машине. Три техники, от самой дешёвой:
- Canary-файлы. Бросьте в тестовый репо файл с уникальным именем и уникальной случайной строкой (напр.
CANARY-9f2c4a.txt). Запустите инструмент. Затем ищите эту строку в хранилище вендора, в экспорте данных вашего аккаунта или просто следите, появится ли она в теле запроса. Если файл, на который вы не ссылались, покинул машину — вот ваш ответ. - Захват на уровне сети. Пропустите инструмент через локальный перехватывающий прокси (
mitmproxy) и прочтите, что он реально шлёт. Ищите multipart-выгрузки, полезную нагрузкуbundle/tar/gitи размеры запросов, намного превышающие ваш промпт. Так и доказали поведение Grok; воспроизводимо за вечер. - Объём исходящего. Даже не расшифровывая TLS, следите за суммарными отправленными байтами сразу после запуска (по-приложенческий сетевой монитор или
nettop/iftop). Однострочный вопрос, запускающий многогигабайтную выгрузку, говорит всё.
Сделайте это раз на инструмент и повторяйте после крупных обновлений — поведение тихо меняется между версиями.
Изолируйте — практическая политика
- Никогда не запускайте интерактивный агентный TUI внутри настоящего репо. Этот bundle при старте сессии — худший нарушитель. Если нужен интерактивный опыт — делайте это в одноразовом каталоге, содержащем только файлы, которыми вы готовы поделиться.
- Предпочитайте headless / одноразовые режимы. У многих инструментов есть неинтерактивный режим «ответь на этот промпт», который не упаковывает репо. В наших тестах одного такого инструмента headless-вызов
-pне выгрузил ничего, а открытие интерактивного TUI в репо — выгрузило. Проверьте свой так же — различие важно. - Используйте REST API вместо CLI, где возможно — API-вызовы обычно шлют лишь переданный вами контекст, а не всё дерево.
- Религиозно gitignore-йте секреты и никогда не направляйте агент на файл секретов. Держите
.env/ ключевой материал вне отслеживаемого дерева и вне зоны чтения агента. - Корпоративные уровни «нулевого хранения данных» существуют для некоторых инструментов — но это договорное обещание, а не проверяемая техническая гарантия. Относитесь соответственно.
- Разверните модель локально для по-настоящему чувствительной работы. Локальная модель (см. наш гайд по локальным моделям) не шлёт ничего никому. Это единственный вариант, полностью убирающий вендора из вашей модели угроз.
Итог
Агентные ИИ-инструменты для кода — по-настоящему новая поверхность эксфильтрации: программа, которую вы впустили, читающая всё и по умолчанию способная отправить это наверх — тихо, при старте сессии, минуя тумблеры, от которых вы ждали защиты. Раскрытие Grok Build примечательно лишь тем, что вендор подтвердил его вслух; предполагайте ту же позицию от каждого агентного инструмента, пока не проверите обратное. Держите секреты вне дерева и вне рук агента, запускайте интерактивные сессии в одноразовых каталогах, предпочитайте headless-режимы, а для действительно важного — запускайте модель локально. Удобные дефолты настроены под вендора. Ваша модель угроз — ваша работа.