Security Blog

Вы разделили работу между тринадцатью агентами. Paperclip не разделил ключ.

#339

October 2, 2026 · By Marketing team

← All posts

При сканировании фреймворка агентов со 71 000 звёзд выяснилось, что двенадцать из тринадцати его агентов несут один и тот же токен в открытом виде. Как только Вы запускаете парк агентов, «секрет живёт в конфигурации» перестаёт быть обходным путём и становится множителем.

Вы поступили по-современному. Вместо одного большого агента Вы подняли парк — один разбирает тикеты, один пишет тексты, один ведёт конвейер дизайна, десяток агентов, у каждого своя задача и своя конфигурация. Так кажется безопаснее. Меньше радиус поражения. Больше минимальных привилегий.

Затем сканирование безопасности прошло по конфигурациям фреймворка агентов Paperclip со 71 000 звёзд и обнаружило, что двенадцать из тринадцати его агентов несли одни и те же учётные данные — идентичный токен, вставленный в открытом виде в конфигурацию каждого агента [1]. Ключ Anthropic API был жёстко зашит в конфигурации дизайн-агента в незашифрованном виде. Токен бота, предназначенный одному агенту, читался агентами, которым он был не нужен.

Тринадцать дверей. Один ключ, скопированный в двенадцать из них. Украдите его у самого слабого агента — и у Вас есть остальные одиннадцать.

Что на самом деле произошло

Paperclip выдаёт каждому агенту конфигурацию MCP-сервера — файл, который сообщает агенту, к каким инструментам и сервисам он может обращаться и как проходить аутентификацию. Где-то по пути секреты попадали в эти файлы буквально текстом: JWT для n8n, bearer-токен, ключ Anthropic API. Не по ссылке. Не подставлялись во время выполнения. Вводились вручную — а затем, поскольку поднять следующего агента означает скопировать и вставить, дублировались по всему парку.

Сканирование отметило три вещи. Общие токены в открытом виде у двенадцати агентов (оценка HIGH). Ключ Anthropic в незашифрованном виде в конфигурации дизайн-агента (оценка CRITICAL). И токен бота с областью доступа, распространявшейся на агентов, для которых он не предназначался, — обычное нарушение принципа минимальных привилегий [1]. В защиту команды Paperclip: они среагировали быстро — перешли на ссылки на учётные данные, редактировали конфигурацию при чтении между агентами и начали применять принудительную синхронизацию привязок [2]. Направление верное.

Это не безалаберность Paperclip

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

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

Ссылки на учётные данные — то, что внедрили в Paperclip, — действительно лучше. Но обратите внимание, что они меняют и чего не меняют. Ссылка по-прежнему разрешается в реальный секрет там, где работает агент; агент или всё, что его скомпрометировало, всё ещё может прочитать разрешённое значение. А собственный трекер ошибок фреймворка уже показывает следующий сценарий сбоя: ссылка рассинхронизируется со своей привязкой, и конфигурация выглядит заполненной, тогда как проверка молча не проходит [3]. Секрет отодвинулся на слой назад. Из здания он не вышел.

Дело не только в Paperclip

Та же неделя, та же первопричина, другие репозитории. На широко используемого кодового агента завели запись о том, что он выводит в чат необработанные значения .env — пароли, токены, ключи API. Другой раннер агентов обнаружили передающим дочерним процессам полное окружение родителя, так что каждый ключ провайдера был виден дочернему процессу [4]. Голосовой хук записывал расшифровки, вместе с учётными данными, в доступный всем /tmp [5]. Независимые команды, независимые модели угроз, одно общее допущение: что секрет может жить там, где его видит агент. Весь аргумент атакующего сводится к тому, что это не так.

Спроектировано для этого намеренно

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

Каждый агент получает доступ только к тому, для чего он назначен, — не ко всему хранилищу, — поэтому токен бота не может оказаться читаемым агентом, который его не запрашивал. И каждое действие фиксируется в журнале за конкретным действующим лицом, а не за общим токеном, который был у двенадцати агентов, — поэтому на вопрос «кто это сделал?» есть ответ.

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

Урок не в том, чтобы «ротировать токен»

Paperclip ротирует токены, завершит миграцию и закроет задачи. Хорошо — так и должно быть. Но ротация — не урок. Урок в том, что в момент, когда у Вас парк агентов вместо одного приложения, «секрет живёт в конфигурации» перестаёт быть обходным путём и становится множителем. Множитель не лечится тем, что секрет становится чуть труднее прочитать. Он лечится тем, чтобы секрета изначально не было в руках агента.

Мы записали правила, которым, на наш взгляд, должен следовать инструмент для учётных данных в эпоху агентов, — среди них: секрет никогда не живёт там, где выполняется код, и агент получает доступ только к тому, для чего он назначен. Проверьте свои по ним: clavitor.ai/rules.

Clavitor (@clavitorai) — хранилище учётных данных, созданное для ИИ-агентов и против них. clavitor.ai

Источники

[1] Фреймворк агентов Paperclip — результаты проверки гигиены учётных данных (CFG-H1 общие токены в открытом виде, CFG-C1 жёстко зашитый ключ Anthropic, CFG-H2 токен бота с неверной областью доступа): https://github.com/paperclipai/paperclip

[2] Paperclip — принудительная синхронизация привязки секретов агента на протяжении жизненного цикла (слито): https://github.com/paperclipai/paperclip/pull/8307

[3] Paperclip — записи secret_ref в окружении могут рассинхронизироваться со строками secret_bindings, конфигурация выглядит заполненной, но проверка молча не проходит (#8309): https://github.com/paperclipai/paperclip/issues/8309

[4] Chetter — runBatchAgent наследует полное окружение раннера, открывая ключи API провайдеров дочернему процессу (#56): https://github.com/flatout-works/chetter/issues/56

[5] Голосовой хук Claude Code — полные расшифровки (включая учётные данные) записываются в доступный всем /tmp (#58): https://github.com/rodlaneedu-hash/claude-code-voice-hook/issues/58