Tożsamość kryptograficzna agentów AI: mTLS, JWT i SPIFFE/SPIRE w praktyce
Dlaczego agenty AI potrzebują weryfikowalnej tożsamości nieosobowej i jak ją nadawać za pomocą mTLS, tokenów JWT oraz SPIFFE/SPIRE. Przewodnik wdrożeniowy.
Agenty AI przestały być pokazem na konferencji. Dziś czytają skrzynki, wywołują API, podejmują decyzje zakupowe i rozmawiają z innymi agentami bez człowieka w pętli. Każda z tych czynności to żądanie do jakiegoś systemu — a system po drugiej stronie musi odpowiedzieć na proste pytanie: kto to właściwie pyta. Przez dekadę odpowiadaliśmy na nie statycznym kluczem API wklejonym do zmiennej środowiskowej. Dla agenta, który uruchamia się i znika w ciągu sekund, skaluje się do tysięcy instancji i działa po stronie nieufnej sieci, ten model się rozpada.
Ten artykuł pokazuje, dlaczego agentom potrzebna jest tożsamość kryptograficzna zamiast współdzielonego sekretu, i jak ją realnie nadać — krok po kroku przez mTLS, tokeny JWT oraz standard SPIFFE wraz z jego implementacją SPIRE.
Czym jest tożsamość kryptograficzna agenta AI?
Tożsamość kryptograficzna agenta to weryfikowalne, krótkożyciowe poświadczenie kryptograficzne — certyfikat X.509 albo podpisany token — które jednoznacznie identyfikuje konkretny proces (agenta) wobec innych usług i które druga strona może sprawdzić matematycznie, bez odpytywania jakiejkolwiek bazy haseł. W odróżnieniu od klucza API, którego posiadanie samo w sobie jest „dowodem“, tożsamość kryptograficzna opiera się na parze kluczy: agent posiada klucz prywatny, którego nigdy nie ujawnia, a poświadczenie potwierdza, że ten klucz należy do nazwanej tożsamości w danej domenie zaufania.
To jest tożsamość nieosobowa (non-human identity) — nie należy do pracownika, lecz do obciążenia: kontenera, funkcji, agenta. Różnica jest fundamentalna. Tożsamość człowieka loguje się raz dziennie, ma drugi składnik uwierzytelnienia i ma za sobą żywą osobę, którą można zapytać. Tożsamość agenta odnawia się co kilka minut, działa całą dobę i nie ma kogo zapytać, gdy coś pójdzie nie tak. Próba zarządzania nią tymi samymi narzędziami co kontami ludzi to droga donikąd — i to właśnie tutaj większość zespołów się potyka.
Krótko: jeśli nie potrafisz odpowiedzieć kryptograficznie na pytanie „czy ten agent jest tym, za kogo się podaje“, nie masz kontroli nad tym, co dzieje się w twojej infrastrukturze. Masz nadzieję.
Dlaczego klucz API nie wystarcza agentowi?
Klucz API to długi ciąg znaków, który mówi tylko jedno: „kto to trzyma, ten ma dostęp“. To wystarczało, gdy integracji było kilka, żyły latami i pilnował ich człowiek. Agenty łamią każde z tych założeń naraz.
Po pierwsze, sekret statyczny to sekret wieczny. Klucz API zwykle nie wygasa albo wygasa po roku. Jeśli wycieknie — z logu, z repozytorium, z przejętego kontenera — napastnik korzysta z niego dopóki ktoś nie zauważy i ręcznie nie unieważni. Przy agentach, które mnożą integracje i kopiują konfigurację między środowiskami, powierzchnia wycieku rośnie wykładniczo.
Po drugie, klucz nie mówi nic o tym, kto naprawdę pyta. Nie wiesz, czy żądanie przyszło od właściwego agenta na właściwym węźle, czy od skopiowanego klucza uruchomionego na laptopie napastnika. Sam fakt posiadania jest jedynym dowodem, a posiadanie da się ukraść.
Po trzecie, klucze się nie skalują operacyjnie. Sto agentów to sto sekretów do wygenerowania, rozdystrybuowania, rotacji i odwołania. Robione ręcznie — staje się źródłem wycieków. Robione przez „jeden klucz dla wszystkich“ — jeden wyciek kompromituje całą flotę.
Tożsamość kryptograficzna odwraca te trzy problemy. Poświadczenie żyje minuty, nie lata. Weryfikuje się je matematycznie, więc skradziona kopia bez klucza prywatnego jest bezużyteczna. A wydawanie i rotacja są zautomatyzowane, bo opierają się na tym, czym obciążenie jest, a nie na tym, co zostało mu wcześniej wręczone.
| Cecha | Klucz API / sekret statyczny | Tożsamość kryptograficzna |
|---|---|---|
| Czas życia | Miesiące/lata (lub bezterminowo) | Minuty/godziny, automatyczna rotacja |
| Dowód tożsamości | Posiadanie ciągu znaków | Podpis kluczem prywatnym |
| Skutek kradzieży poświadczenia | Pełny dostęp aż do unieważnienia | Bezużyteczne bez klucza prywatnego |
| Skala (setki obciążeń) | Ręczna dystrybucja, źródło wycieków | Automatyczne wydawanie per obciążenie |
| Powiązanie z tożsamością obciążenia | Brak (klucz „lata luzem“) | Wbudowane w poświadczenie |
Czym tożsamość nieosobowa różni się od tożsamości obciążenia?
Te dwa terminy często padają zamiennie, ale warto je rozdzielić. Tożsamość nieosobowa to szeroka kategoria: wszystko, co nie jest człowiekiem, a potrzebuje się uwierzytelniać — konta usługowe, klucze API, tokeny botów, certyfikaty maszyn. Tożsamość obciążenia (workload identity) to jej nowocześniejszy, węższy podzbiór: tożsamość przypisana konkretnemu działającemu procesowi w czasie jego życia, nadawana dynamicznie na podstawie tego, czym ten proces jest i gdzie działa.
Agent AI najlepiej pasuje do modelu tożsamości obciążenia. Nie jest stałym kontem, które tworzysz raz w katalogu. Jest efemerycznym procesem, który startuje, robi swoje i znika. Chcesz, żeby jego tożsamość pojawiała się i wygasała razem z nim — bez ręcznego zakładania konta, bez sekretu do skopiowania, bez sprzątania po jego śmierci.
To rozróżnienie ma praktyczne konsekwencje. Jeśli potraktujesz agenta jak konto usługowe ze statycznym sekretem, dziedziczysz wszystkie problemy z poprzedniej sekcji. Jeśli potraktujesz go jak obciążenie, którego tożsamość jest wynikiem atestacji (sprawdzenia, czym proces faktycznie jest), wchodzisz w świat, w którym tożsamość nadaje się automatycznie i krótkoterminowo. To właśnie świat SPIFFE.
Jak mTLS daje agentowi weryfikowalną tożsamość?
mTLS, czyli wzajemny TLS, to najprostszy fundament tożsamości agenta. W zwykłym TLS tylko serwer przedstawia certyfikat — przeglądarka sprawdza, że łączy się z właściwym bankiem, ale bank nie wie kryptograficznie, kto puka. W mTLS obie strony przedstawiają certyfikat i obie się nawzajem weryfikują. Agent dowodzi, kim jest, zanim wymieni choćby bajt danych aplikacyjnych.
Działa to tak. Agent dostaje certyfikat X.509 oraz odpowiadający mu klucz prywatny. Podczas nawiązywania połączenia (handshake) agent przedstawia certyfikat, a serwer sprawdza dwie rzeczy: czy certyfikat został podpisany przez zaufany urząd certyfikacji (CA) oraz czy agent faktycznie posiada klucz prywatny do tego certyfikatu (dowodzi tego podpisem w trakcie handshake). Posiadanie samego certyfikatu nie wystarcza — bez klucza prywatnego skradziona kopia jest martwa. To rozwiązuje problem „kradzież poświadczenia = pełny dostęp“, który gnębi klucze API.
Tożsamość siedzi wtedy w polu certyfikatu — zwykle w nazwie podmiotu lub, w podejściu SPIFFE, w polu Subject Alternative Name jako URI. Serwer odczytuje ją z certyfikatu i na tej podstawie podejmuje decyzję autoryzacyjną: ten agent może czytać tę kolejkę, tamten nie.
mTLS świetnie sprawdza się przy połączeniach usługa-do-usługi: agent łączy się z bazą, z brokerem wiadomości, z inną usługą wewnętrzną. Ma jednak dwa ograniczenia. Działa na poziomie połączenia, więc tożsamość nie „podróżuje“ naturalnie przez kilka skoków (agent → brama → usługa). I jest niewygodny tam, gdzie tożsamość trzeba przekazać w nagłówku żądania HTTP zamiast w warstwie transportowej. Tu wchodzi JWT.
Kiedy używać tokenów JWT zamiast mTLS?
JWT (JSON Web Token) to podpisany, samodzielny token, który niesie twierdzenia (claims) o tożsamości w swojej zawartości. Inaczej niż mTLS, który wiąże tożsamość z połączeniem, JWT wiąże tożsamość z żądaniem. Agent dołącza token w nagłówku Authorization, a odbiorca weryfikuje podpis kluczem publicznym wystawcy i ufa twierdzeniom w środku.
Token składa się z trzech części: nagłówka (algorytm podpisu), ładunku (twierdzenia — kto, dla kogo, do kiedy ważny) i podpisu. Kluczowa zaleta: odbiorca weryfikuje token offline, bez odpytywania wystawcy przy każdym żądaniu — wystarczy, że zna jego klucz publiczny. To czyni JWT naturalnym wyborem dla architektur HTTP/REST oraz dla scenariuszy, w których tożsamość musi przejść przez wiele warstw.
JWT bije mTLS w kilku sytuacjach typowych dla agentów:
- Przez bramy i pośredników — token przechodzi przez API gateway czy kolejkę, zachowując tożsamość źródła, podczas gdy mTLS kończy się na pierwszym skoku.
- Komunikacja agent-do-agenta — gdy jeden agent woła drugiego przez HTTP, token niesie jego tożsamość w żądaniu.
- Delegacja i ograniczanie zakresu — twierdzenia w tokenie mogą zawęzić uprawnienia („ten token tylko do odczytu, ważny 5 minut, dla tej jednej usługi“).
Cena za tę elastyczność: token, który wycieknie, jest ważny aż do wygaśnięcia, bo weryfikuje się go offline. Dlatego przy JWT dla agentów obowiązuje żelazna zasada — krótki czas życia. Token ważny minuty, nie godziny. I tu pojawia się problem operacyjny: kto ma wydawać te tokeny co kilka minut, dla tysiąca agentów, automatycznie? Odpowiedzią — wspólną dla mTLS i JWT — jest SPIFFE.
Czym jest SPIFFE i co rozwiązuje?
SPIFFE (Secure Production Identity Framework for Everyone) to otwarty standard nadawania tożsamości obciążeniom, rozwijany pod skrzydłami CNCF. Nie jest produktem — to specyfikacja, która mówi, jak powinna wyglądać tożsamość obciążenia, niezależnie od chmury, języka czy platformy. Rozwiązuje dokładnie ten problem, który wynika z poprzednich sekcji: skąd obciążenie ma wziąć swoją tożsamość kryptograficzną, skoro nie chcemy mu wręczać żadnego sekretu na starcie.
SPIFFE opiera się na trzech filarach.
SPIFFE ID to nazwa tożsamości w formacie URI: spiffe://domena-zaufania/ścieżka, na przykład spiffe://acme.example/agent/research-bot. To globalnie jednoznaczny identyfikator obciążenia — czytelny dla człowieka i nadający się do reguł autoryzacji.
SVID (SPIFFE Verifiable Identity Document) to nośnik tej tożsamości w postaci kryptograficznej. Występuje w dwóch wariantach, które łączą wszystko, co omówiliśmy: X.509-SVID to certyfikat X.509, w którym SPIFFE ID jest wpisany w pole Subject Alternative Name jako URI — wprost pod mTLS. JWT-SVID to podpisany token JWT z SPIFFE ID w twierdzeniach — wprost pod nagłówek Authorization. Ten sam standard tożsamości, dwa formaty pod dwa różne scenariusze.
Workload API to lokalny interfejs, przez który obciążenie pobiera swój SVID — bez żadnego sekretu, bez tokenu startowego. Agent po prostu pyta lokalny punkt końcowy „jaka jest moja tożsamość“, a infrastruktura odpowiada, automatycznie odnawiając poświadczenie, zanim wygaśnie.
Magia jest w tym ostatnim punkcie. SPIFFE eliminuje problem zerowego sekretu (bootstrap secret) — odwieczne pytanie „jak bezpiecznie wręczyć obciążeniu pierwszy sekret, skoro żeby wręczyć sekret, trzeba mieć sekret“. Zamiast wręczać cokolwiek, SPIFFE atestuje obciążenie: sprawdza, czym ono faktycznie jest, i na tej podstawie wydaje tożsamość. Jak to robi — to już rola SPIRE.
Jak SPIRE wydaje tożsamość agentom w praktyce?
SPIRE to referencyjna, produkcyjna implementacja standardu SPIFFE. To ona zamienia specyfikację w działający system wydawania SVID. Architektura jest dwuczęściowa: serwer i agenty.
SPIRE Server to kotwica zaufania dla całej domeny. Pełni rolę urzędu certyfikacji (lub deleguje ją do zewnętrznego CA), podpisuje X.509-SVID i JWT-SVID oraz trzyma rejestr wpisów rejestracyjnych (registration entries) — reguł mówiących, które cechy obciążenia mapują się na który SPIFFE ID.
SPIRE Agent działa na każdym węźle, na którym uruchamiają się obciążenia. To on udostępnia lokalne Workload API, do którego puka agent AI, pobiera SVID od serwera i buforuje je dla obciążeń na swoim węźle.
Sekret zaufania kryje się w dwóch etapach atestacji.
Atestacja węzła (node attestation) — zanim SPIRE Server zacznie ufać jakiemukolwiek SPIRE Agentowi, musi się upewnić, że ten agent działa tam, gdzie twierdzi. Robi to na podstawie dowodu z platformy: tożsamości instancji w chmurze, tokenu projekcji konta usługowego w Kubernetes, modułu TPM. Serwer weryfikuje ten dowód u źródła, a nie na słowo.
Atestacja obciążenia (workload attestation) — gdy agent AI pyta lokalne Workload API o swoją tożsamość, SPIRE Agent nie wierzy mu na słowo. Sprawdza właściwości pytającego procesu poprzez system operacyjny: jego UID, ścieżkę binarki, etykiety poda w Kubernetes, identyfikator kontenera. Dopiero gdy te właściwości pasują do wpisu rejestracyjnego, agent dostaje odpowiedni SVID.
Efekt: tożsamość wynika z tego, czym proces jest, a nie z tego, co mu wcześniej wręczono. Żaden sekret nie krąży w obrazie kontenera ani w zmiennej środowiskowej. Skradziony obraz nie da napastnikowi tożsamości, bo nie przejdzie atestacji na obcym węźle.
Jak to wygląda krok po kroku?
- Wdrażasz SPIRE Server jako kotwicę zaufania domeny i konfigurujesz w nim metodę atestacji węzłów.
- SPIRE Agent na każdym węźle przechodzi atestację węzła i nawiązuje zaufanie z serwerem.
- Tworzysz wpis rejestracyjny wiążący selektory (np. konto usługowe
research-botw przestrzeni nazwagents) z SPIFFE IDspiffe://acme.example/agent/research-bot. - Agent AI woła Workload API przez lokalne gniazdo i prosi o swój SVID — bez żadnego sekretu w konfiguracji.
- SPIRE Agent atestuje proces, sprawdza zgodność z wpisem i zwraca X.509-SVID (do mTLS) lub JWT-SVID (do żądań HTTP).
- Poświadczenie odnawia się automatycznie na długo przed wygaśnięciem — agent nie musi się tym zajmować.
To samo działa, gdy jeden agent woła drugiego: każdy ma własny SVID, każdy weryfikuje drugiego po SPIFFE ID, a reguły autoryzacji operują na czytelnych nazwach tożsamości, nie na nieprzejrzystych ciągach kluczy.
mTLS, JWT czy SPIFFE/SPIRE — co wybrać?
To nie jest wybór „albo-albo“. To warstwy, które się uzupełniają. SPIFFE/SPIRE jest mechanizmem wydawania tożsamości; mTLS i JWT to dwa formaty jej użycia. Poniższa tabela porządkuje, kiedy sięgać po co.
| Wymiar | mTLS (X.509-SVID) | JWT-SVID | SPIFFE/SPIRE jako całość |
|---|---|---|---|
| Co to jest | Wzajemne uwierzytelnienie w warstwie transportowej | Podpisany token w żądaniu | System wydawania i rotacji obu powyższych |
| Najlepszy do | Połączeń usługa-do-usługi, baz, kolejek | HTTP/REST, agent-do-agenta, przez bramy | Automatyzacji tożsamości w całej flocie |
| Weryfikacja | W trakcie handshake TLS | Offline, kluczem publicznym wystawcy | Atestacja węzła + obciążenia |
| Przez wiele skoków | Słabo (kończy się na 1. skoku) | Dobrze (token podróżuje) | — |
| Ryzyko wycieku poświadczenia | Niskie (potrzebny klucz prywatny) | Średnie (ważny do wygaśnięcia) | Minimalizowane krótkim czasem życia |
| Koszt wdrożenia | Średni | Niski | Wyższy start, niski koszt skali |
W praktyce dojrzała architektura agentowa łączy wszystko: SPIRE wydaje krótkożyciowe SVID-y, agenty używają X.509-SVID do mTLS między usługami wewnętrznymi i JWT-SVID tam, gdzie tożsamość musi przejść przez bramę albo do innego agenta przez HTTP. Decyzja sprowadza się do jednego pytania: czy uwierzytelniam połączenie (mTLS), czy żądanie wędrujące przez warstwy (JWT).
Od czego zacząć wdrożenie tożsamości agentów?
Nie zaczynaj od przepisywania wszystkiego. Zacznij od jednej ścieżki, która boli najbardziej — zwykle jest to agent trzymający długożyciowy klucz API do wrażliwej usługi.
Sensowna kolejność wygląda tak. Najpierw zinwentaryzuj tożsamości nieosobowe: ile masz agentów, jakie trzymają sekrety, gdzie te sekrety leżą i kiedy ostatnio je rotowano. Ta lista zwykle zawstydza i jest najlepszym argumentem za zmianą. Potem wybierz jeden klaster (np. środowisko Kubernetes z kilkoma agentami) i postaw na nim SPIRE — to środowisko ma najwygodniejszą atestację węzła i obciążenia. Następnie zmigruj jedną ścieżkę: zamień jeden statyczny klucz na SVID i sprawdź, że agent działa na automatycznie rotowanym poświadczeniu. Dopiero gdy ta pętla się domknie, rozszerzaj ją na kolejne agenty i wprowadzaj reguły autoryzacji oparte na SPIFFE ID.
Trzy zasady, które oszczędzą bólu. Po pierwsze, traktuj tożsamość agenta jak obciążenie, nie jak konto człowieka — krótki czas życia, automatyczna rotacja, brak drugiego składnika logowania. Po drugie, autoryzuj po SPIFFE ID, nie po adresie IP ani sieci — w świecie efemerycznych agentów adres jest przypadkowy, a tożsamość stała. Po trzecie, loguj, kto się uwierzytelnił — czytelny SPIFFE ID w logach jest bezcenny, gdy trzeba zbadać, który agent zrobił co i kiedy, a reguły dostępu egzekwuj przy każdym wywołaniu w modelu zero trust.
Tożsamość kryptograficzna nie jest luksusem dla największych. Jest minimalnym warunkiem panowania nad infrastrukturą, w której coraz więcej decyzji podejmują procesy bez człowieka w środku. Klucz API odpowiadał na pytanie „czy ktoś ma sekret“. mTLS, JWT i SPIFFE/SPIRE odpowiadają na właściwe pytanie: „czy ten agent naprawdę jest tym, za kogo się podaje“ — i robią to matematycznie, automatycznie i w skali.
Źródła techniczne: dokumentacja projektu SPIFFE/SPIRE (spiffe.io, koncepcje SPIRE, praca z SVID), samoocena bezpieczeństwa SPIFFE/SPIRE w CNCF TAG Security oraz opracowanie Red Hat: What are SPIFFE and SPIRE?.
Najczęstsze pytania
Czym różni się tożsamość nieosobowa od tożsamości człowieka?
Tożsamość człowieka loguje się okazjonalnie, ma drugi składnik uwierzytelnienia i stoi za nią żywa osoba, którą można zapytać. Tożsamość nieosobowa należy do procesu — agenta, kontenera, funkcji — działa bez przerwy, odnawia się co kilka minut i nie ma kogo zapytać przy incydencie. Dlatego wymaga innych narzędzi: krótkożyciowych poświadczeń i automatycznej rotacji zamiast haseł i drugiego składnika.
Czy mogę używać samego klucza API zamiast tożsamości kryptograficznej?
Dla pojedynczej, stabilnej integracji pilnowanej przez człowieka klucz API bywa wystarczający. Dla floty agentów nie jest: sekret statyczny żyje za długo, jego kradzież daje pełny dostęp, a ręczna rotacja setek kluczy sama staje się źródłem wycieków. Tożsamość kryptograficzna rozwiązuje wszystkie trzy problemy naraz.
Kiedy wybrać mTLS, a kiedy JWT dla agenta?
mTLS uwierzytelnia połączenie i najlepiej pasuje do komunikacji usługa-do-usługi: agent łączy się z bazą, kolejką czy inną usługą wewnętrzną. JWT uwierzytelnia żądanie i sprawdza się, gdy tożsamość musi przejść przez bramę lub trafić do innego agenta przez HTTP, bo token podróżuje przez kolejne skoki. Dojrzałe wdrożenia używają obu, a SPIFFE/SPIRE wydaje oba formaty jako X.509-SVID i JWT-SVID.
Czym jest SPIFFE ID i jak wygląda?
SPIFFE ID to nazwa tożsamości obciążenia w formacie URI: spiffe://domena-zaufania/ścieżka, na przykład spiffe://acme.example/agent/research-bot. Jest globalnie jednoznaczny, czytelny dla człowieka i nadaje się wprost do reguł autoryzacji, które operują na nazwach tożsamości zamiast na nieprzejrzystych kluczach czy adresach IP.
Jak SPIRE wydaje tożsamość bez wręczania agentowi żadnego sekretu?
SPIRE opiera się na atestacji, nie na wręczaniu sekretu. Najpierw atestuje węzeł (potwierdza dowodem z platformy, gdzie działa SPIRE Agent), a potem atestuje obciążenie (sprawdza przez system operacyjny właściwości pytającego procesu — UID, ścieżkę binarki, etykiety poda). Tożsamość wydaje na podstawie tego, czym proces faktycznie jest, więc żaden sekret nie musi krążyć w obrazie kontenera.
Czy SPIFFE/SPIRE działa tylko w Kubernetes?
Nie. Kubernetes jest najwygodniejszym środowiskiem startowym, bo dostarcza gotowych selektorów do atestacji (konta usługowe, etykiety podów), ale SPIRE obsługuje też maszyny wirtualne, instancje w chmurach, bare metal i moduły TPM. Standard SPIFFE jest z założenia niezależny od platformy.
Co dzieje się, gdy SVID agenta wygaśnie w trakcie pracy?
Nic — i o to chodzi. SVID-y są celowo krótkożyciowe, a SPIRE Agent odnawia je automatycznie na długo przed wygaśnięciem i buforuje dla obciążeń na swoim węźle. Agent AI nie musi się tym zajmować; pobiera aktualne poświadczenie przez Workload API. Krótki czas życia jest cechą, nie problemem: ogranicza okno użyteczności ewentualnie skradzionego poświadczenia.