Security Blog

Pan podzielił pracę między trzynastu agentów. Paperclip nie podzielił klucza.

#455

October 2, 2026 · By Marketing team

← All posts

Skan frameworka agentów z 71 000 gwiazdek wykazał, że dwunastu z trzynastu agentów nosiło ten sam token w postaci zwykłego tekstu. Kiedy uruchamia Pan flotę agentów, „sekret żyje w pliku konfiguracyjnym” przestaje być skrótem, a staje się mnożnikiem.

Zrobił Pan rzecz nowoczesną. Zamiast jednego dużego agenta postawił Pan flotę — jeden segreguje zgłoszenia, drugi pisze teksty, trzeci prowadzi proces projektowy, tuzin agentów, każdy z własnym zadaniem i własną konfiguracją. To wydaje się bezpieczniejsze. Mniejszy promień rażenia. Więcej zasady najmniejszych uprawnień.

Potem skan bezpieczeństwa przeszedł przez pliki konfiguracyjne frameworka agentów o nazwie Paperclip, który ma 71 000 gwiazdek, i wykazał, że dwunastu z trzynastu agentów nosiło te same dane uwierzytelniające — identyczny token, wklejony jako zwykły tekst do konfiguracji każdego agenta [1]. Klucz API Anthropic był wpisany na sztywno w konfiguracji agenta projektowego, w formie jawnej. Token bota przeznaczony dla jednego agenta był czytelny dla agentów, które nie miały z nim nic do czynienia.

Trzynaście drzwi. Jeden klucz, skopiowany do dwunastu z nich. Wystarczy ukraść go najsłabszemu agentowi, żeby mieć pozostałe jedenaście.

Co właściwie się wydarzyło

Paperclip nadaje każdemu agentowi konfigurację serwera MCP — plik, który mówi agentowi, z jakich narzędzi i usług może korzystać oraz jak się do nich uwierzytelniać. W którymś momencie sekrety trafiły do tych plików jako zwykły tekst: JWT z n8n, token bearer, klucz API Anthropic. Nie przez odwołanie. Nie wstrzyknięte w czasie działania. Wpisane — a następnie, ponieważ uruchomienie kolejnego agenta to kopiuj-wklej, powielone w całej flocie.

Skan wskazał trzy rzeczy. Wspólne tokeny w postaci zwykłego tekstu u dwunastu agentów (ocena HIGH). Klucz Anthropic leżący w formie jawnej w konfiguracji agenta projektowego (ocena CRITICAL). I token bota z zakresem obejmującym agentów, dla których nigdy nie był przeznaczony — zwykłe naruszenie zasady najmniejszych uprawnień [1]. Trzeba przyznać, że zespół Paperclip zadziałał szybko: przeszedł na odwołania do danych uwierzytelniających, zaczął usuwać sekrety z konfiguracji przy odczytach międzyagentowych i zaczął wymuszać synchronizację powiązań [2]. Dobry kierunek.

To nie jest kwestia nieuwagi Paperclip

To jest ta część, nad którą warto się zatrzymać. Paperclip zrobił to, co robi niemal każdy framework. Umieszczenie sekretu w pliku konfiguracyjnym to sposób, w jaki oprogramowanie uwierzytelnia się od trzydziestu lat. Działało, bo była jedna aplikacja, jedna konfiguracja i jeden operator, który wiedział, gdzie żyje klucz.

Epoka zmieniła się pod tym nawykiem. System wieloagentowy to nie jedna aplikacja z jedną konfiguracją — to tuzin procesów, każdy z plikiem, każdy kopią poprzedniego. Zwykły tekst w konfiguracji był tolerowalnym skrótem, gdy istniało jedno miejsce, z którego mógł wyciec. Przy trzynastu ten sam skrót oznacza, że jeden wyciek to trzynaście wycieków — a na pytanie „który agent to zrobił?” nie ma odpowiedzi, ponieważ token w logach należał do wszystkich.

Odwołania do danych uwierzytelniających — poprawka, którą wdrożył Paperclip — są rzeczywiście lepsze. Ale warto zwrócić uwagę, co zmieniają, a czego nie zmieniają. Odwołanie nadal rozwiązuje się do prawdziwego sekretu w miejscu, gdzie działa agent; agent, albo cokolwiek, co go przejmie, nadal może odczytać rozwiązaną wartość. A w samym systemie zgłoszeń frameworka widać już kolejny tryb awarii: odwołanie wychodzi z synchronizacji ze swoim powiązaniem, więc konfiguracja wygląda na wypełnioną, podczas gdy walidacja cicho się nie udaje [3]. Sekret przesunął się o jedną warstwę wstecz. Nie wyszedł z budynku.

To nie tylko Paperclip

Ten sam tydzień, ta sama przyczyna źródłowa, inne repozytoria. Wobec szeroko używanego agenta kodującego zgłoszono, że wypisuje surowe wartości .env — hasła, tokeny, klucze API — wprost do swojego wyjścia czatu. Innego runnera agentów przyłapano na przekazywaniu pełnego środowiska procesu nadrzędnego procesom potomnym, więc każdy klucz dostawcy był widoczny dla procesu potomnego [4]. Hook głosowy zapisywał transkrypcje, wraz z danymi uwierzytelniającymi, do /tmp z dostępem dla wszystkich [5]. Niezależne zespoły, niezależne modele zagrożeń, jedno wspólne założenie: że sekret może żyć tam, gdzie agent go widzi. Cały argument, który musi przedstawić atakujący, sprowadza się do tego, że nie może.

Zbudowane z myślą o tym, celowo

Clavitor wychodzi od przeciwnego założenia: agent nigdy nie posiada danych uwierzytelniających. Zgłasza żądanie wykonania akcji; żądanie jest przechwytywane, uwierzytelniane względem sekretu, którego agent nie może odczytać, i wykonywane. Nie ma konfiguracji, do której można wkleić token, ponieważ w konfiguracji nie ma tokena. Nie ma nic do skopiowania do trzynastu agentów, ponieważ środowisko agenta nigdy nie trzyma rzeczy, którą warto ukraść.

Każdy agent sięga tylko po to, do czego został naznaczony — nie do całego magazynu — więc token bota nie może trafić do czytelności agenta, który o niego nigdy nie prosił. I każda akcja jest logowana na konkretnego wykonawcę, który ją podjął, nigdy na wspólny token, który miało dwunastu agentów — więc na pytanie „który to zrobił?” istnieje odpowiedź.

Uczciwe zastrzeżenie: to nie czyni agenta niehackowalnym. Przejęty agent nadal może w danej chwili robić to, do czego został upoważniony. Czego nie może zrobić, to odejść z kluczem i stać się pozostałymi dwunastoma — ponieważ nie ma w jego rękach klucza, z którym można by odejść.

Lekcja nie brzmi „zrotuj token”

Paperclip wykona rotację tokenów, dokończy migrację i zamknie zgłoszenia. Dobrze — powinien. Ale rotacja nie jest lekcją. Lekcja brzmi tak: w chwili, gdy ma Pan flotę agentów zamiast jednej aplikacji, „sekret żyje w konfiguracji” przestaje być skrótem, a staje się mnożnikiem. Mnożnika nie naprawia się, czyniąc sekret trochę trudniejszym do odczytu. Naprawia się go, upewniając się, że sekret nigdy nie znalazł się w rękach agenta.

Zapisaliśmy reguły, które naszym zdaniem powinno spełniać narzędzie do danych uwierzytelniających w epoce agentów — między innymi to, że sekret nigdy nie żyje tam, gdzie uruchamia się kod, oraz że agent sięga tylko po to, do czego został naznaczony. Proszę sprawdzić swoje rozwiązanie wobec nich: clavitor.ai/rules.

Clavitor (@clavitorai) to skarbiec danych uwierzytelniających zbudowany dla agentów AI — i przeciwko nim. clavitor.ai

Źródła

[1] Framework agentów Paperclip — ustalenia dotyczące higieny danych uwierzytelniających (CFG-H1 wspólne tokeny w postaci zwykłego tekstu, CFG-C1 klucz Anthropic wpisany na sztywno, CFG-H2 token bota o błędnym zakresie): https://github.com/paperclipai/paperclip

[2] Paperclip — wymuszanie synchronizacji powiązań sekretów agentów w przepływach cyklu życia (scalono): https://github.com/paperclipai/paperclip/pull/8307

[3] Paperclip — wpisy env secret_ref mogą wypaść z synchronizacji z wierszami secret_bindings, konfiguracja wygląda na wypełnioną, ale walidacja cicho się nie udaje (#8309): https://github.com/paperclipai/paperclip/issues/8309

[4] Chetter — runBatchAgent dziedziczy pełne środowisko runnera, ujawniając klucze API dostawców procesowi potomnemu (#56): https://github.com/flatout-works/chetter/issues/56

[5] Hook głosowy Claude Code — pełne transkrypcje (w tym dane uwierzytelniające) zapisywane do /tmp z dostępem dla wszystkich (#58): https://github.com/rodlaneedu-hash/claude-code-voice-hook/issues/58