Перейти к основному содержимому

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

Утечка 13 000 внутренних изображений через агентов для программирования — это провал гигиены репозитория и ограничения области действия агента: агенты наследуют всю историю и всю поверхность секретов рабочей копии, поэтому единицей изоляции является граница репозитория, а не инструкция.

Detailed view of automated machinery with warning signals in an industrial setting.

Репозиторий — это поверхность утечки

Когда агенту для программирования дают задачу, ему, как правило, предоставляют доступ к рабочему дереву. Это дерево не является нейтральной песочницей. Оно содержит всю историю коммитов, все ветки, все теги и любые неотслеживаемые или игнорируемые артефакты, которые там оказались. Агент читает то, что там есть. Если репозиторий когда-либо содержал изображение, учётные данные, дамп базы данных или бинарный блоб, агент может его прочитать, скопировать, преобразовать и записать обратно. Недавний отчёт об утечке 13 000 внутренних изображений через агентов для программирования — это не история про хитроумный промпт. Это история о том, что происходит, когда агент наследует репозиторий без границы изоляции.

Слой инструкций — неправильное место для поиска безопасности. Промпты носят рекомендательный характер. Их интерпретирует модель, которая оптимизируется под выполнение задачи, а не под вашу политику классификации данных. Промпт, который гласит «не читай каталог с секретами», — это предложение, а не контроль доступа. Граница репозитория — это контроль доступа. Она обеспечивается файловой системой, удалённым репозиторием и учётными данными, которые есть у агента. Именно там и должна быть инженерия.

Почему агенты для программирования — это отдельный класс утечек

Большинство развёртываний LLM-агентов взаимодействуют с API. Агенты для программирования взаимодействуют с системой контроля версий. Это различие меняет режимы отказа тремя способами.

Во-первых, агент работает внутри рабочего дерева с полным доступом на чтение к истории, веткам и неотслеживаемым артефактам. Рабочая копия — это не снимок текущего состояния; это полная запись всего, что когда-либо было закоммичено. Если секрет был закоммичен, а затем удалён, он всё ещё находится в хранилище объектов. Если изображение было добавлено в ветке функциональности, оно достижимо. Агенту не нужно давать инструкцию найти его. Стандартные инструменты — git log, git grep, git cat-file — выводят его в ходе обычного исследования.

Во-вторых, агенты для программирования регулярно выполняют команды, которые создают и коммитят бинарные артефакты. Результаты сборки, веса моделей, скриншоты, тестовые фикстуры, сгенерированные отчёты. Они не дают чистого диффа. Текстовый дифф бинарного файла — это либо одна строка «Binary files differ», либо стена нечитаемых байтов. Ревьюеры их пропускают. Артефакт попадает в историю, а как только он в истории, он есть в каждом последующем клоне.

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

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

Aerial photo of an industrial area with warehouses in Wilson, NC. Bright daylight view.

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

Единица изоляции — это граница репозитория. Из этого напрямую следуют приведённые ниже правила.

Клонируйте поверхностно и с ограничением области. Агент, которому нужен один пакет, не должен получать историю монорепозитория. Используйте поверхностный клон (--depth 1) и разреженный checkout (--filter=blob:none, --sparse), чтобы рабочее дерево содержало только те пути, которые требуются задаче. Это не оптимизация производительности; это сокращение поверхности чтения. Если агент не может увидеть объект, он не может его слить.

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

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

Честный компромисс: поверхностные клоны с ограниченной областью ломают некоторые рабочие процессы агентов. Агенты, которым нужно выполнить бисекцию регрессии, проследить изменение по истории или рассуждать о долгоживущей ветке, потерпят неудачу или дадут худшие результаты. Средство смягчения — предоставить отдельный, доступный только для чтения, аудируемый путь для доступа к истории, а не расширять клон по умолчанию. По умолчанию должна быть узкая поверхность; исключение должно быть явным и логируемым.

Обнаружение, не зависящее от поведения агента

Обнаружение не должно полагаться на то, что агент следует инструкциям.

Сканируйте подготовленные блобы до коммита, а не после пуша. Хук pre-commit, который проверяет подготовленное содержимое на строки с высокой энтропией и известные заголовки изображений, перехватывает этот класс утечки до того, как он попадёт в историю. Сканирование на высокую энтропию ловит учётные данные и ключи. Сканирование заголовков ловит магические байты PNG, JPEG, GIF и WebP. И то и другое дёшево и детерминированно. Смысл в том, чтобы запускать их на подготовленном объекте, а не на рабочем дереве, потому что именно подготовленный объект будет закоммичен.

Detailed view of a drone controller joystick, showcasing precision technology.

Диффьте инвентарь артефактов, а не только дифф исходников. Каждый коммит, созданный агентом, должен порождать манифест добавленных, изменённых и удалённых файлов с их типами и размерами. Ревьюеры должны видеть этот манифест рядом с диффом исходников. Коммит, который добавляет бинарный файл на 2 МБ в репозиторий, содержащий только исходники, — это сигнал, независимо от того, что содержит этот бинарный файл. Дифф инвентаря — это поверхность ревью для артефактов; дифф исходников — это поверхность ревью для логики.

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

Что это означает для проектирования инструментов агента

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

Инструмент коммита должен предоставлять объявленный манифест артефактов, а не выход в шелл. Вместо того чтобы давать агенту шелл и надеяться, что он выполнит git add для нужных файлов, инструмент должен требовать от агента объявить, что он намеревается закоммитить: список путей, их типы и их происхождение. Затем инструмент коммитит ровно этот набор. Это устраняет класс случайных коммитов, возникающих из широких вызовов git add . и из шагов сборки, которые сбрасывают артефакты в дерево.

Учётные данные репозитория должны быть короткоживущими и привязанными к ветке. Учётные данные, которые истекают через минуты и могут пушить только в одну ветку, ограничивают радиус поражения скомпрометированного агента. Это повторяет то, как работают учётные данные с ограниченной областью действия для платежей: область действия несёт учётные данные, а не вызывающая сторона. Агенту не нужно доверять; учётные данные ограничены.

Инструменты ревью нуждаются в поле авторства с атрибуцией агента. Коммиты, созданные агентом, должны отличаться от коммитов, созданных человеком, на уровне метаданных. Тогда ревьюеры могут применять разную степень scrutiny: коммит, созданный человеком, может получить обычное ревью, тогда как коммит, созданный агентом, получает проверку инвентаря артефактов и сканирование на секреты как само собой разумеющееся. Атрибуция не о вине; она о маршрутизации к правильному процессу ревью.

Граница, а не инструкция

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

ПоделитьсяXLinkedInПостоянная ссылка6 мин чтения

На какие вопросы это отвечает

Why is a prompt not a sufficient control for coding agents?

Prompts are advisory. They are interpreted by a model optimising for task completion, not for data-classification policy. The repository boundary — enforced by the filesystem, the remote, and the credential — is an actual access control.

What makes binary artifacts a special risk in agent-authored commits?

Binaries do not diff cleanly, so reviewers skip them. A build output, screenshot, or model weight can enter history unreviewed, and once it is in history it is in every subsequent clone.

How should agent credentials be scoped?

Short-lived, bound to a single repository and branch, with push rights to a staging remote only. Promotion to the canonical remote should be a separate, human-gated step.

What is the trade-off of shallow, scoped clones?

Agents that need to bisect regressions or trace changes across history will fail or produce worse results. The mitigation is a separate, read-only, audited path for history access, not a wider default clone.