Ви розподілили роботу між тринадцятьма агентами. Paperclip не розподілив ключ.
Сканування фреймворку агентів із 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) — сховище облікових даних, створене для AI-агентів і проти них. 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