Łańcuch delegacji i zdezorientowany zastępca w tożsamości agentów: bezpieczne podszywanie, wymiana tokenów i ślad audytowy
Jak agenty AI bezpiecznie działają w cudzym imieniu: łańcuch delegacji, problem zdezorientowanego zastępcy, wymiana tokenów (RFC 8693) i czytelny ślad audytowy.
Agent AI rzadko działa sam. Czyta kalendarz jednego użytkownika, sięga do bazy w imieniu zespołu, wywołuje inne narzędzie, które z kolei woła kolejne. Powstaje łańcuch delegacji — i to właśnie w nim rodzą się najgroźniejsze błędy tożsamości. W tym tekście pokazuję, czym jest zdezorientowany zastępca tożsamości, jak wymiana tokenów pozwala na bezpieczne podszywanie i dlaczego bez porządnego śladu audytowego cały system staje się nierozliczalny.
Czym jest łańcuch delegacji i dlaczego stwarza ryzyko?
Łańcuch delegacji to sytuacja, w której uprawnienie do działania przechodzi przez kilku pośredników: użytkownik upoważnia agenta, agent upoważnia narzędzie, narzędzie sięga do usługi zaplecza. Ryzyko polega na tym, że na każdym ogniwie tożsamość pierwotnego inicjatora może zostać zgubiona, podmieniona albo nadmiernie rozszerzona. Jeśli usługa na końcu łańcucha widzi tylko „przyszedł zaufany agent“, a nie „działa w imieniu użytkownika Anny z jej uprawnieniami“, to przyznaje dostęp na podstawie zaufania do pośrednika, nie do prawdziwego nadawcy zlecenia.
Krótka, samodzielna odpowiedź na pytanie z tytułu: zdezorientowany zastępca to uprzywilejowany komponent (np. agent lub usługa pośrednicząca), którego mniej uprzywilejowany podmiot nakłania do wykonania działania z użyciem nie swoich, lecz cudzych — wyższych — uprawnień. Lekarstwem są trzy rzeczy razem: jawna delegacja zamiast cichego podszywania, wymiana tokenów zgodna z RFC 8693 oraz ślad audytowy, który dla każdego wywołania zapisuje, kto był prawdziwym inicjatorem i kto działał w jego imieniu.
W świecie agentów AI łańcuchy bywają długie i dynamiczne. Agent planujący wywołuje agenta wykonawczego, ten sięga po narzędzie MCP, narzędzie odpytuje API z danymi klienta. Każde przejście to moment, w którym trzeba odpowiedzieć na jedno pytanie: czyimi uprawnieniami właśnie się posługujemy i czy ten konkretny krok mieści się w pierwotnym upoważnieniu?
Na czym polega problem zdezorientowanego zastępcy?
Termin „confused deputy“ pochodzi z pracy Norma Hardy’ego z 1988 roku i opisuje klasyczną słabość systemów opartych na tożsamości pośrednika zamiast na przekazanym uprawnieniu. „Zastępca“ to program z szerokimi prawami; „zdezorientowany“ — bo wykonuje polecenie napastnika, sądząc, że realizuje zwykłe, legalne żądanie. Napastnik nie łamie zabezpieczeń wprost — pożycza cudzą władzę.
Przykład bez fikcyjnych liczb: agent ma uprawnienie do odczytu dowolnego pliku w przestrzeni roboczej, bo musi obsługiwać wielu użytkowników. Użytkownik o niskich uprawnieniach prosi go: „streść plik raporty/zarzad/wynagrodzenia.csv“. Jeśli agent nie sprawdzi, czy ten konkretny użytkownik ma prawo do tego pliku, a działa własnymi, szerokimi prawami — odda treść, do której proszący nie powinien mieć dostępu. Zastępca został zdezorientowany.
W systemach agentowych problem zaostrza prompt injection. Złośliwa instrukcja ukryta w treści dokumentu albo na stronie WWW potrafi przekonać agenta, by użył swoich uprawnień do czegoś, czego użytkownik nigdy nie zlecił — wysłał dane na zewnątrz, skasował rekord, zmienił konfigurację. Agent staje się zastępcą napastnika. Dlatego sama autoryzacja „czy agent jest zaufany“ to za mało; liczy się „czy ten krok mieści się w uprawnieniach prawdziwego inicjatora“.
Delegacja czy podszywanie — która droga jest bezpieczna?
To dwa różne wzorce przekazania tożsamości i warto je rozróżniać precyzyjnie.
Podszywanie (impersonation) oznacza, że pośrednik występuje jako użytkownik. Usługa na końcu widzi tożsamość użytkownika i nic więcej — ślad po pośredniku znika. Jest to wygodne, bo nie wymaga zmian w usługach docelowych, ale niebezpieczne: traci się informację, że działanie wykonał agent, a nie człowiek. Audyt pokazuje „Anna usunęła rekord“, choć zrobił to bot w jej imieniu.
Delegacja (delegation) oznacza, że pośrednik działa w imieniu użytkownika, ale zachowuje też własną tożsamość. Token niesie obie informacje: kto jest podmiotem (subject — użytkownik) i kto działa za niego (actor — agent). Usługa widzi pełny obraz: „agent X działa w imieniu Anny“. To bezpieczniejsze, bo pozwala egzekwować zasadę najmniejszych uprawnień osobno dla człowieka i osobno dla agenta oraz daje rozliczalny ślad.
Reguła praktyczna brzmi: preferuj delegację, podszywanie traktuj jako wyjątek. Bezpieczne podszywanie jest możliwe, ale tylko gdy jest wąsko ograniczone w czasie, zakresie i celu — i gdy mimo wszystko zapisujesz w logu prawdziwego wykonawcę. Inaczej tracisz właśnie to, czego najbardziej potrzebujesz przy autonomicznych agentach: odpowiedź na pytanie „kto naprawdę to zrobił“.
| Cecha | Podszywanie | Delegacja |
|---|---|---|
| Tożsamość widziana przez usługę | tylko użytkownik | użytkownik + agent (subject + actor) |
| Rozliczalność w logu | słaba (znika pośrednik) | pełna (oba podmioty) |
| Najmniejsze uprawnienia | trudne do wyegzekwowania osobno | egzekwowalne per podmiot |
| Ryzyko przy długim łańcuchu | wysokie | ograniczone |
| Kiedy stosować | wąski, krótkotrwały wyjątek | domyślnie |
Jak wymiana tokenów rozwiązuje problem łańcucha?
Wymiana tokenów to mechanizm, w którym podmiot oddaje serwerowi autoryzacji jeden token i otrzymuje w zamian inny — o zawężonym zakresie, innym odbiorcy albo wzbogacony o informację o delegacji. Standardem jest RFC 8693 (OAuth 2.0 Token Exchange), opublikowany w 2020 roku przez IETF. To on daje słownik do opisania całego łańcucha w sposób, który usługi potrafią zweryfikować.
Kluczowe parametry żądania wymiany według RFC 8693 to:
subject_token— token reprezentujący podmiot, w którego imieniu ma nastąpić działanie (np. token użytkownika).actor_token— token reprezentujący stronę działającą w imieniu podmiotu (np. token agenta).requested_token_typeorazaudience/scope— pozwalają poprosić o token węższy i przeznaczony dla konkretnej usługi docelowej.
W odpowiedzi serwer wystawia nowy token, w którym pole act (actor) opisuje, kto działa za podmiot. Pola act można zagnieżdżać — i to jest sedno: długi łańcuch delegacji zapisuje się jako zagnieżdżone act, gdzie najgłębszy poziom to najświeższy pośrednik, a podmiot pozostaje na górze. Usługa końcowa odczytuje całą sekwencję i podejmuje decyzję autoryzacyjną świadoma, kto był inicjatorem, a kto tylko wykonawcą.
Dlaczego to gasi zdezorientowanego zastępcę? Bo każde ogniwo wymienia token na węższy, przypisany do konkretnego odbiorcy (audience) — to ta sama zasada najmniejszych uprawnień per wywołanie. Token wystawiony agentowi do wywołania usługi A nie zadziała w usłudze B. Nawet jeśli napastnik przejmie token w połowie łańcucha, jego zasięg jest zawężony do jednego celu i jednego zakresu, a nie do pełnej władzy pośrednika. To realizacja zasady najmniejszych uprawnień na poziomie pojedynczego wywołania.
Jak budować ślad audytowy dla łańcucha delegacji?
Ślad audytowy to zapis, który dla każdego działania pozwala odtworzyć pełen łańcuch: kto był pierwotnym inicjatorem, którzy pośrednicy brali udział, jakim tokenem posłużono się na każdym kroku i czy działanie mieściło się w przyznanych uprawnieniach. Bez tego autonomiczny agent jest nierozliczalny — a nierozliczalność to nie tylko problem bezpieczeństwa, lecz także zgodności z przepisami.
Dobry ślad audytowy w systemie agentowym powinien zapisywać:
- Inicjatora i pełen łańcuch aktorów — odwzorowanie zagnieżdżonych pól
actz RFC 8693: podmiot na górze, kolejni pośrednicy poniżej. - Identyfikator tokena i jego pochodzenie — który token wymieniono na który, z jakim
audienceiscope, z jakim czasem ważności. - Korelację całej sesji — wspólny identyfikator wiążący wszystkie wywołania w ramach jednego zadania agenta, tak by dało się odtworzyć przebieg od polecenia użytkownika po ostatnie API.
- Wynik decyzji autoryzacyjnej — czy dostęp przyznano, na jakiej podstawie i które uprawnienie było wymagane.
Z praktyki warto pilnować trzech rzeczy. Po pierwsze, log autoryzacyjny ma być niezmienialny i przechowywany osobno od komponentu, który go tworzy — inaczej przejęty agent zaciera własne ślady. Po drugie, nie wkładaj surowych tokenów ani danych wrażliwych do logów; zapisuj identyfikatory i skróty. Po trzecie, projektuj log tak, by odpowiadał na pytanie śledcze „pokaż wszystko, co zrobił agent w imieniu Anny między 14:00 a 15:00“ — to ono pada po incydencie.
Standaryzacja tożsamości maszynowej idzie w tę stronę. Specyfikacja SPIFFE/SPIFFE Verifiable Identity Document (SVID) nadaje usługom i procesom kryptograficznie weryfikowalną tożsamość, którą można powiązać z tokenami delegacji. To dobry fundament, gdy agent i jego narzędzia działają jako osobne procesy lub usługi i każde z nich potrzebuje własnej, sprawdzalnej tożsamości w łańcuchu.
Jakie zasady projektowe ograniczają nadużycia delegacji?
Kilka reguł, które warto traktować jako twardy kanon przy budowie agentów działających w cudzym imieniu:
- Domyślnie delegacja, podszywanie tylko świadomie i wąsko. Zawsze zachowuj tożsamość agenta obok tożsamości użytkownika.
- Zawężaj przy każdym przejściu. Token wymieniany na kolejne ogniwo ma mieć węższy
scopei konkretnyaudience. Nigdy nie przekazuj dalej tokena „uniwersalnego“. - Krótki czas życia i jednorazowość tam, gdzie się da. Im krótsze okno ważności, tym mniejsza szkoda po przechwyceniu.
- Autoryzuj na uprawnieniach inicjatora, nie pośrednika. Usługa końcowa sprawdza, czy prawdziwy podmiot ma prawo do działania, a nie czy agent jest „zaufany“.
- Traktuj wejście agenta jako niezaufane. Prompt injection potrafi zamienić zastępcę w narzędzie napastnika; bramki autoryzacyjne muszą działać niezależnie od tego, do czego uda się nakłonić model.
- Loguj zawsze prawdziwego wykonawcę. Nawet przy podszywaniu zapisz w śladzie audytowym, że działał agent.
Te zasady nie są egzotyczne — to przeniesienie dobrze znanej zasady najmniejszych uprawnień i rozliczalności na nowy grunt, na którym podmiotem działającym coraz częściej jest oprogramowanie, a nie człowiek. Agent, który potrafi udowodnić, w czyim imieniu i na jakiej podstawie coś zrobił, jest agentem, któremu można powierzyć więcej.
Podsumowanie
Łańcuch delegacji jest nieunikniony w architekturach agentowych, a wraz z nim wraca trzydziestoletni problem zdezorientowanego zastępcy — tyle że teraz uprzywilejowanym pośrednikiem bywa model językowy podatny na prompt injection. Trzy filary trzymają to w ryzach: jawna delegacja zamiast cichego podszywania, wymiana tokenów według RFC 8693 zawężająca uprawnienia przy każdym ogniwie oraz ślad audytowy odtwarzający, kto był prawdziwym inicjatorem działania. Zaprojektuj te trzy elementy razem, a tożsamość w Twoim systemie agentowym przestanie być najsłabszym ogniwem.
Najczęstsze pytania
Czym różni się podszywanie od delegacji w tożsamości agentów?
Przy podszywaniu pośrednik występuje jako użytkownik i jego własna tożsamość znika — usługa widzi tylko użytkownika. Przy delegacji token niesie obie tożsamości: podmiot (użytkownik) oraz aktora (agent), dzięki czemu można egzekwować uprawnienia osobno dla każdego i zachować rozliczalny ślad. Domyślnie wybieraj delegację.
Co to jest problem zdezorientowanego zastępcy?
To słabość, w której uprzywilejowany komponent (np. agent) zostaje nakłoniony przez mniej uprzywilejowany podmiot do wykonania działania z użyciem swoich szerokich uprawnień zamiast uprawnień prawdziwego zlecającego. Termin pochodzi z pracy Norma Hardy'ego z 1988 roku. W systemach agentowych typowym wyzwalaczem jest prompt injection.
Jaki standard opisuje wymianę tokenów?
RFC 8693 (OAuth 2.0 Token Exchange) opublikowany przez IETF w 2020 roku. Definiuje parametry subject_token i actor_token oraz roszczenie act opisujące, kto działa w imieniu podmiotu. Roszczenia act można zagnieżdżać, co pozwala zapisać cały łańcuch delegacji.
Jak wymiana tokenów ogranicza ryzyko przy długim łańcuchu?
Na każdym przejściu token jest wymieniany na węższy, przypisany do konkretnego odbiorcy (audience) i zakresu (scope) oraz o krótkim czasie życia. Dzięki temu przechwycony token działa tylko wobec jednej usługi i jednego uprawnienia, a nie daje pełnej władzy pośrednika.
Co powinien zawierać ślad audytowy dla agenta działającego w cudzym imieniu?
Pierwotnego inicjatora i pełen łańcuch aktorów (odwzorowanie zagnieżdżonych act), identyfikator i pochodzenie użytych tokenów wraz z audience i scope, wspólny identyfikator korelujący całą sesję zadania oraz wynik decyzji autoryzacyjnej. Log powinien być niezmienialny i nie zawierać surowych tokenów.
Czy bezpieczne podszywanie w ogóle istnieje?
Tak, ale jako wąski wyjątek: ograniczone w czasie, zakresie i celu. Nawet wtedy w śladzie audytowym należy zapisać prawdziwego wykonawcę, czyli agenta. Inaczej tracisz rozliczalność, która jest kluczowa przy autonomicznych systemach.
Jak prompt injection wiąże się z problemem zastępcy?
Złośliwa instrukcja ukryta w danych wejściowych (dokumencie, stronie WWW) może przekonać agenta, by użył swoich uprawnień do działania, którego użytkownik nie zlecił. Agent staje się zdezorientowanym zastępcą napastnika. Dlatego autoryzacja musi opierać się na uprawnieniach prawdziwego inicjatora i działać niezależnie od decyzji modelu.