Claude Code: кнопка "больше не спрашивать" увозит пароль в git

Автономный прогон упирается в одно и то же: агент останавливается и спрашивает, можно ли выполнить команду. В чате это выглядит как тормоз, и рука сама жмёт "Yes, and don't ask again" - пусть запомнит и идёт дальше. 9 ноября 2026 Apiiro показала, чем такая настройка ИИ-агента заканчивается в Claude Code: команда сохраняется целиком, вместе с паролем или ключом, в файл .claude/settings.local.json внутри репозитория. Тому, кто занимается внедрением ИИ-агентов в разработку, это снимает лишний круг: не переписывать промпт и не менять модель, а запретить кнопку на строках с доступом и не коммитить сам файл.
Что клиент кладёт рядом с кодом
Речь не про модель, которая "запомнила" секрет и сама выложила его в интернет. Apiiro пишет прямо: так устроен клиент Claude Code, и это повторили на Opus 5.5 и Fable 5.1. Кнопка согласия без повторного вопроса записывает команду так, как её вызвали.
Если в строке был пароль, токен или строка подключения к базе, в файл попадает не шаблон "можно вызывать клиент базы". Попадает живой вызов. Файл задуман как локальный. Репозиторий от этого не помечает его приватным. Нет исключения в git - обычный коммит увозит настройку вместе с кодом.
На публичном GitHub у Apiiro 104 185 копий .claude/settings.local.json в 103 617 репозиториях. В 1 122 файлах, это 1,1%, нашёлся секрет известного формата: ключ провайдера или пароль и токен рядом с публичным хостом. Среди них 379 паролей баз. Если добавить историю git, общий settings.json и сохранённые записи чатов агента, счётчик вырастает до 2 539 различных секретов в 1 994 репозиториях.
Долю в один с небольшим процент легко прочитать как "почти никого". Для автономных ИИ-агентов это слабое утешение: они как раз просят запомнить команду, чтобы не вставать на каждом доступе. Один пароль базы в публичном файле работает, пока его не сменят.
Что проверить до следующего коммита
В своей организации на GitHub откройте поиск по path:.claude/settings.local.json и отдельно по settings.json внутри каталога .claude. Файл в текущей ветке - смотрите, нет ли в правиле пароля, ключа или адреса базы. Файл только в истории - секрет всё равно считайте утёкшим и перевыпустите. Убрать его из последней ветки историю не чистит.
Дальше порядок жёсткий. Сначала перевыпуск, если строка с секретом уже уехала. Потом .gitignore: добавьте .claude/settings.local.json, чтобы следующий коммит не повторил то же самое. И только затем договорённость в команде: "don't ask again" нельзя на командах, где в строке пароль, строка подключения или токен.
Разрешение должно называть программу и безопасные флаги, а не полную строку вызова. Секрет живёт в окружении. В правиле его значения быть не должно: агент видит, что переменная задана, и не видит её в тексте команды.
Мы в Интеллект Технологии на стенде сначала закрыли вопрос исключением в git. Казалось, локальный файл в репозиторий не попадёт, и настраивать ИИ-агента дальше незачем. Не сработало. Файл уже был в истории, а кнопку продолжали жать: без неё длинный прогон останавливался. Сработало другое. Секрет остался только в окружении, правило помнит класс команды, рядом записан владелец вызова - кто меняет ключ, если файл снова всплывёт.
Где отчёт вас не прикрывает
Apiiro смотрела публичный GitHub и этот механизм Claude Code. Это не вывод про всех агентов и не про приватные репозитории, которые в отчёт не входили. Сканеры общего назначения там прогоняли, но в тексте нет обещания, что они ловят тот же набор. Зелёный отчёт сканера не заменяет поиск по пути .claude и просмотр правил глазами.
Не переносите вывод и на журнал другой формы. Отчёт про разрешение, которое клиент пишет в локальный json. Если свой агент складывает сырой аргумент инструмента в базу или в лог сборки, утечка будет без этого файла. Искать нужно то место, куда у вас реально записывается вызов.
Что заложить в систему ИИ-агентов
Почти у любого агента, который сам вызывает инструменты, есть список "можно без спроса". Опасна не автономность, а способ её записать. Если система ИИ-агентов сохраняет удачный вызов целиком и кладёт его рядом с кодом, секрет из аргумента становится файлом репозитория.
Разрешение храним отдельно от значения. В правиле - имя команды и маска аргументов. Значение - в окружении или в хранилище секретов, которое в чат и в файл настройки не печатают.
"Запомнить выбор" оставляем на командах без доступов: тесты, линтер, чтение файла. Всё, что ходит в базу, почту или облако, либо подтверждает человек, либо идёт коротким доступом, которого нет в тексте команды.
Перед сдачей внедрения ИИ-агентов в поиск по репозиторию добавляем файл настроек и кусок журнала с аргументами инструментов. Секрет нашёлся - сначала перевыпуск, потом разбор, кто нажал "больше не спрашивать". Промпт в этот момент чинить незачем. Модель тут ни при чём.
Та же ловушка живёт и там, где исполнитель не Claude Code, а свой воркер. Кнопки с этим текстом нет, зато есть соблазн положить удачный вызов в пример для следующего запуска. Пример с живым ключом в репозитории - та же утечка, только без чужого отчёта. На своём контуре, в том числе на GigaChat Pro, это особенно обидно ловить после запуска: модель наша, а ключ уже в истории git.
Если завтра попросят "пусть агент больше не спрашивает, мы теряем вечер", спросите, что попадёт в сохранённую строку. Команда без секрета - можно. Строка, в которой уже есть пароль, - нет, даже если шаг придётся подтвердить руками.
Ваш .claude/settings.local.json уже в истории или вы ещё успеваете поймать его до первого коммита?
Похожие статьи
- ИИ-агент Алисы не кликает баннер: что открыть в карточке до кодекса ИИ-агента
- ИИ-агент Гермес 0.23.1: один шлюз держит чат, платный инструмент спрашивает до потолка
- Tether в Open WebUI 0.13.1: локальный ИИ-агент берёт файлы с вашей машины, а не с копии на сервере
- MTGBench Яндекса: семь игр вместо рейтинга, пока модель ещё не в агенте
