Bezpieczne narzędzia dla agentów: sandbox, allowlist i uprawnienia per-akcja (a nie per-bot)

Jak projektować bezpieczne narzędzia dla agentów AI: model zagrożeń, sandbox, allowlist, uprawnienia per-akcja, audyt oraz zatwierdzanie operacji wysokiego ryzyka z przykładami polityk.
26 kwietnia 2026
blog

1. Wprowadzenie: dlaczego narzędzia agentów muszą być projektowane jak interfejsy wysokiego ryzyka

Agent AI różni się od typowej aplikacji tym, że nie tylko odpowiada, ale coraz częściej działa: wysyła zapytania do systemów, modyfikuje zasoby, uruchamia procesy, a czasem inicjuje operacje finansowe lub administracyjne. W tym modelu „narzędzia” (funkcje, integracje, akcje) stają się jego rękami. To właśnie dlatego interfejsy narzędzi należy traktować jak powierzchnię wysokiego ryzyka — porównywalną z panelem administracyjnym, automatyzacją w produkcji czy API o krytycznych uprawnieniach.

Ryzyko nie wynika wyłącznie ze „złych” intencji użytkownika. Wynika z faktu, że agent działa na podstawie niepełnej informacji, może błędnie zinterpretować polecenie, ulec manipulacji treścią (np. w dokumentach, mailach czy na stronach) albo połączyć kilka pozornie niewinnych kroków w niebezpieczną sekwencję. W przeciwieństwie do klasycznego oprogramowania, w którym logika jest deterministyczna i wcześniej przetestowana, agent podejmuje decyzje dynamicznie, w kontekście i często w warunkach niepewności. To przesuwa ciężar bezpieczeństwa z „czy model odpowie poprawnie?” na „czy system przetrwa, nawet jeśli agent podejmie złą decyzję?”.

Projektowanie narzędzi dla agentów jak interfejsów wysokiego ryzyka oznacza kilka fundamentalnych założeń:

  • Załóż błąd jako stan normalny: pomyłki, halucynacje i nietrafione dopasowania intencji nie są wyjątkiem, tylko przewidywalnym trybem awarii.
  • Załóż wrogie lub skażone dane wejściowe: agent pracuje na treściach, które mogą zawierać ukryte instrukcje, zmanipulowane konteksty lub złośliwe „podpowiedzi”.
  • Załóż nadużycie narzędzi: nawet poprawne funkcje mogą zostać użyte w niewłaściwej kolejności, z niepożądanymi parametrami lub do niezamierzonego celu.
  • Oddziel „rozumienie” od „wykonywania”: fakt, że agent coś zasugerował, nie powinien automatycznie oznaczać, że ma możliwość to wykonać bez ograniczeń.

W praktyce oznacza to, że bezpieczeństwo agentów nie kończy się na filtrach treści czy politykach rozmowy. Kluczowe staje się to, jak wyglądają kontrakty narzędzi, jakie mają granice, jak są izolowane od reszty środowiska oraz jak precyzyjnie przyznawane są uprawnienia do działań. Szczególnie istotne jest odejście od modelu „bot ma stałe uprawnienia” na rzecz modelu, w którym uprawnienie jest przypisane do konkretnej akcji i kontekstu — bo w systemach agentowych to właśnie działania, a nie sama rozmowa, generują największe skutki.

Jeśli narzędzia potraktujemy jak zwykłe API, to każdy błąd interpretacji może stać się błędem operacyjnym: usuniętym plikiem, wysłanym mailem, zmienioną konfiguracją, wyciekiem danych lub nieautoryzowanym dostępem. Jeśli potraktujemy je jak interfejsy wysokiego ryzyka, projekt będzie od początku zakładał ograniczenia, weryfikacje i możliwość bezpiecznego „nie wykonania” akcji — nawet gdy agent jest przekonany, że powinien.

2. Model zagrożeń i granice zaufania: agent, narzędzia, dane, użytkownik, środowisko

Zanim włączysz agentowi jakiekolwiek narzędzie, potrzebujesz prostego modelu zagrożeń: kto może wpłynąć na zachowanie systemu, co może zostać wykorzystane jako wektor ataku oraz gdzie przebiegają granice zaufania. W przypadku agentów te granice są bardziej „ruchome” niż w klasycznych aplikacjach, bo agent potrafi łączyć wiele źródeł informacji i podejmować działania w imieniu użytkownika. Podczas szkoleń Cognity ten temat wraca regularnie – dlatego zdecydowaliśmy się go omówić również tutaj.

Najważniejsze założenie: agent nie jest stroną zaufaną sam z siebie. Jest wykonawcą instrukcji i optymalizatorem celu, ale może zostać nakierowany na błędne lub złośliwe działania przez dane wejściowe, kontekst oraz nieoczekiwane zachowania narzędzi. Dlatego projekt bezpieczeństwa zaczyna się od rozdzielenia odpowiedzialności i zdefiniowania, co uznajesz za zaufane, a co musi być traktowane jako potencjalnie wrogie.

  • Użytkownik: inicjuje zadanie i często ma najwyższe intencje, ale nie zawsze jest poprawnie uwierzytelniony, może działać pod presją lub popełnić błąd. Dodatkowo „użytkownik” bywa wieloma rolami (operator, administrator, klient), a ich uprawnienia powinny się różnić.
  • Agent (model + orkiestracja): interpretuje polecenia, planuje kroki i wybiera narzędzia. Ryzyko wynika z tego, że agent może błędnie zrozumieć intencję, ulec manipulacji treścią (np. w dokumentach, mailach, stronach) lub nieprawidłowo połączyć fakty. Agent jest też miejscem, w którym najłatwiej o „eskalację” skutków drobnej pomyłki na serię działań.
  • Narzędzia: to kanał sprawczy. Każde narzędzie jest osobnym systemem z własnymi błędami, zależnościami i semantyką. Granica zaufania przebiega na styku „agent → wywołanie narzędzia”, bo to moment, w którym tekstowa decyzja staje się realną operacją (np. zapisem, wysyłką, przelewem, zmianą konfiguracji).
  • Dane: obejmują zarówno dane wejściowe użytkownika, jak i kontekst pobrany z zewnątrz (pliki, bazy, treści WWW, wiadomości, logi). Kluczowe jest traktowanie wszystkich danych jako potencjalnie niebezpiecznych instrukcji — nawet jeśli wyglądają jak „tylko treść”. Dane mogą też zawierać sekrety (tokeny, klucze, dane osobowe), które agent może przypadkiem ujawnić lub użyć niezgodnie z intencją.
  • Środowisko wykonania: infrastruktura, sieć, system operacyjny, kontenery, uprawnienia procesu, integracje i magazyny sekretów. To tutaj konsekwencje są najdroższe: jeśli agent lub narzędzie uzyska zbyt szeroki dostęp do środowiska, skutki obejmą nie tylko jedną akcję, ale cały ekosystem.

Model zagrożeń dla agentów powinien uwzględniać kilka typowych klas ryzyka, bez wchodzenia jeszcze w mechanikę zabezpieczeń:

  • Manipulacja instrukcjami przez treść: agent może potraktować dane jako polecenia, priorytetyzować je ponad intencję użytkownika lub włączyć je do planu działań.
  • Nadużycie narzędzi: jeśli interfejs narzędzia jest zbyt szeroki albo nieprecyzyjny, agent może wywołać operacje o wyższym ryzyku, niż wynika to z zadania (np. „usuń” zamiast „zarchiwizuj”).
  • Ujawnienie informacji: dane w kontekście (sekrety, PII, konfiguracje) mogą „wypłynąć” do wyników, logów, zewnętrznych usług albo do narzędzi, które nie powinny ich widzieć.
  • Nieintencjonalna eskalacja: seria poprawnych lokalnie kroków może prowadzić do globalnie niepożądanego efektu (np. automatyczna optymalizacja kosztów kończy się wyłączeniem krytycznych zasobów).
  • Ataki łańcuchowe: agent pobiera dane z A, używa ich do decyzji w B, a wynik zapisuje w C — błąd w jednym miejscu może „przeskoczyć” przez cały łańcuch integracji.

Granice zaufania warto narysować mentalnie jako punkty, w których wymagane jest wymuszenie kontraktu: co jest dozwolone, jak weryfikujesz tożsamość i kontekst, jakie dane mogą przepływać oraz co się dzieje w razie błędu. W praktyce najważniejsze granice to: użytkownik ↔ agent (intencja i autoryzacja), agent ↔ dane (sanityzacja i wrażliwość), agent ↔ narzędzia (zakres operacji) oraz narzędzia ↔ środowisko (realny wpływ na systemy).

Efektem tej sekcji ma być prosta lista elementów do ochrony i decyzja, które komponenty traktujesz jako nieufne domyślnie. Dzięki temu kolejne mechanizmy — izolacja wykonania, ograniczanie powierzchni API i uprawnienia zależne od konkretnej akcji — będą odpowiadały na jasno zdefiniowane ryzyka, zamiast być przypadkowym zestawem zabezpieczeń.

Sandbox i izolacja wykonania: ograniczanie skutków błędów i przejęć

Gdy agent dostaje narzędzia wykonawcze (np. uruchamianie kodu, dostęp do plików, sieci, systemów zewnętrznych), trzeba założyć, że prędzej czy później wykona niepożądaną akcję: przez błąd w rozumowaniu, podatność w zależnościach, wrogie dane wejściowe albo przejęcie przepływu (np. przez prompt injection w treści, którą agent analizuje). Sandbox i izolacja wykonania nie „naprawiają” inteligencji agenta — ich rolą jest zredukowanie promienia rażenia, czyli ograniczenie tego, co może się stać, nawet gdy agent zachowa się źle.

Co daje sandbox (i czego nie daje)

  • Ogranicza dostęp do zasobów: plików, sieci, procesów, urządzeń, sekretów.
  • Wymusza granice zasobów obliczeniowych: CPU, RAM, czas, liczba procesów/wątków, rozmiar dysku.
  • Izoluje skutki: błąd lub złośliwe zachowanie dotyczy tylko odizolowanego środowiska, a nie hosta i innych zadań.
  • Ułatwia sprzątanie: środowisko można łatwo wyzerować (ephemeral/„na chwilę”), co redukuje ryzyko trwałych zmian.

Sandbox nie zastępuje kontroli API ani polityk uprawnień. To warstwa techniczna, która zakłada porażkę i projektuje bezpieczny „upadek” systemu.

Izolacja: najczęstsze podejścia

Izolację można realizować na różnych poziomach. W praktyce często łączy się je warstwowo, dobierając do ryzyka konkretnego narzędzia.

Poziom Co izoluje Typowe zastosowanie dla agentów Uwagi
Proces Oddzielny proces, ograniczenia zasobów Lekkie narzędzia, krótkie zadania Najmniejszy narzut, ale najsłabsza granica bez dodatkowych mechanizmów
Kontener System plików, przestrzenie nazw, limity Uruchamianie skryptów, narzędzia CLI, parsowanie plików Dobre domyślne podejście; nadal wymaga ostrożnej konfiguracji
Maszyna wirtualna Pełna izolacja OS Akcje wyższego ryzyka, nieufne binaria Silniejsza bariera kosztem czasu startu i zasobów
Środowisko bez sieci / z filtrowaną siecią Łączność wychodząca/przychodząca Analiza nieufnych danych, ekstrakcja/transformacja Zmniejsza ryzyko eksfiltracji i „calloutów” do C2

Minimalny zestaw ograniczeń w sandboxie

Niezależnie od technologii, warto myśleć o sandboxie jako o zestawie konkretnych hamulców, które są przewidywalne i domyślnie restrykcyjne:

  • Ephemeral filesystem: środowisko uruchamiane „na czysto”, z możliwością zapisu tylko w określonych katalogach roboczych.
  • Read-only by default dla kodu narzędzi i zasobów bazowych, aby agent nie mógł ich modyfikować.
  • Brak dostępu do sekretów w środowisku wykonawczym, chyba że jest to absolutnie konieczne (a jeśli tak — tylko minimalny zakres i krótki czas życia).
  • Ograniczenia zasobów: limity czasu, pamięci, CPU, liczby procesów i rozmiaru wyjścia (aby bronić się przed pętlami, fork-bombami i „zalewaniem” logów).
  • Kontrola I/O: jawnie dozwolone ścieżki plików, rozmiary wejść, formaty, limity pobrań/wysyłek.
  • Sieć jako wyjątek: domyślnie brak sieci lub dostęp tylko do wybranych kierunków (np. do wewnętrznego proxy narzędzi).

Sandbox dla danych: nieufne wejścia i „strefa brudna”

W systemach agentowych częstym wektorem jest nie sam kod, ale dane: dokumenty, HTML, PDF-y, maile, logi, repozytoria, treści z sieci. Traktuj ich przetwarzanie jak pracę w „strefie brudnej”:

  • Parsowanie i konwersje uruchamiaj w izolacji, bo formaty plików i biblioteki parsujące bywają źródłem podatności.
  • Nie pozwalaj, by narzędzia przetwarzające nieufne dane miały jednocześnie dostęp do sekretów lub do systemów produkcyjnych.
  • Rozdzielaj etapy: pobierz → zbuforuj → znormalizuj → dopiero potem użyj, z jasnym miejscem, w którym dane przechodzą kontrolę i walidację.

„Ucieczki” z sandboxa i projektowanie na porażkę

Izolacja nie jest magiczna: błędna konfiguracja, zbyt szerokie uprawnienia systemowe, nadmiar zamontowanych wolumenów czy dostęp do socketów hosta potrafią zamienić kontener w pozorną barierę. Dlatego sandbox powinien być projektowany z założeniem, że:

  • agent może próbować wykonać niezamierzone polecenia,
  • narzędzie może mieć podatność,
  • środowisko może zostać źle użyte.

W praktyce oznacza to m.in. ograniczanie punktów styku z hostem, minimalizowanie uprawnień systemowych i trzymanie wykonania jak najbliżej modelu „jedno zadanie → jedno środowisko → utylizacja”.

Krótki przykład: uruchomienie komendy w środowisku z limitami

Poniższy przykład ma charakter poglądowy: pokazuje ideę timeoutu, limitu zasobów i separacji katalogu roboczego. Konkretna implementacja zależy od stosu (kontener/VM/system operacyjny).

# Pseudokod
run_in_sandbox(
  cmd=["python", "task.py"],
  workdir="/workspace",
  filesystem="ephemeral",
  network="disabled",
  limits={"cpu_ms": 2000, "memory_mb": 256, "wall_time_s": 5, "max_output_kb": 256}
)

Kluczowe jest to, że nawet jeśli agent wygeneruje błędną lub złośliwą komendę, środowisko wykonania ma wbudowane bezpieczniki, które ograniczają skutki do małego, kontrolowanego obszaru.

4. Allowlist i kontrola powierzchni API: kontrakty narzędzi, walidacja parametrów, limity

Im więcej agent „może”, tym większa szansa, że wykona niepożądaną akcję: przez błąd, niejednoznaczne polecenie, podatność w narzędziu albo celową manipulację treścią wejściową. Dlatego zamiast udostępniać agentowi szerokie, ogólne interfejsy (np. dowolne żądania HTTP, dowolny SQL, dowolne wywołania systemowe), warto zawężać powierzchnię API do jasno zdefiniowanych, wąskich operacji. Rdzeniem tego podejścia jest allowlist (lista dozwolonych działań) oraz kontrakty narzędzi, które formalizują: co wolno, w jakiej formie i w jakich granicach. Zespół trenerski Cognity zauważa, że właśnie ten aspekt sprawia uczestnikom najwięcej trudności — szczególnie przejście od „uniwersalnych” integracji do świadomie zaprojektowanych, ograniczonych operacji.

Allowlist vs „otwarty” dostęp

Allowlist to nie tylko lista endpointów. To polityka: agent może wywołać tylko te operacje, które zostały zaprojektowane jako bezpieczne, wraz z ograniczeniami ich parametrów i skutków. W praktyce oznacza to, że agent nie dostaje „uniwersalnego pilota”, tylko zestaw wyspecjalizowanych przycisków.

Podejście Charakterystyka Typowe ryzyko
Open-ended (np. dowolny HTTP/SQL) Duża elastyczność, mało ograniczeń na wejściu Łatwe eskalacje: SSRF, exfiltracja, destrukcyjne operacje, „prompt injection” kierujące na złośliwe cele
Allowlist + wąskie narzędzia Z góry określone operacje i format danych Niższe ryzyko, ale wymaga projektu kontraktów i konsekwentnej walidacji
Allowlist warunkowa (operacje zależne od kontekstu) Zestaw dozwolonych akcji zależy od stanu/etapu zadania Błędy w logice warunków; zbyt szerokie „wyjątki”

Kontrakty narzędzi: wąskie operacje zamiast „kombajnu”

Kontrakt narzędzia to formalny opis operacji, jej parametrów, typów danych, ograniczeń i semantyki skutków. Dobre kontrakty są konkretne i niedomówne:

  • Jednoznaczna intencja: nazwy operacji typu create_invoice, search_customers, schedule_meeting zamiast run_query czy request.
  • Minimalny zestaw parametrów oraz jasne typy (np. identyfikatory jako UUID, daty jako ISO-8601, kwoty jako liczby z walutą).
  • Opis efektów ubocznych: czy operacja zapisuje, usuwa, wysyła, publikuje.
  • Stabilne i przewidywalne odpowiedzi: zdefiniowane pola, brak „dowolnego blobu tekstu” jako jedynej odpowiedzi.

Wąski kontrakt redukuje przestrzeń nadużyć: agent nie ma jak „wymyślić” nowej, nieprzewidzianej operacji, bo jej po prostu nie ma w interfejsie.

Walidacja parametrów: twarde granice na wejściu

Allowlist bez walidacji jest pozorna: agent może próbować obejść intencję narzędzia przez „sprytne” wartości parametrów (np. wstrzyknięcia, nietypowe kodowania, długie payloady, linki do niepożądanych hostów). Walidacja powinna działać przed wykonaniem akcji i obejmować:

  • Walidację typów i formatów (np. email, URL, daty, liczby, enumeracje).
  • Walidację zakresów (np. limit wyników, maksymalna kwota, dopuszczalne przedziały dat).
  • Walidację semantyczną (np. czy identyfikator zasobu należy do bieżącego użytkownika/kontekstu; czy status może przejść w dany stan).
  • Normalizację (np. trim, kanonizacja URL) i odrzucanie niejednoznacznych reprezentacji.
  • Odrzucanie danych „nadmiarowych”: jeśli kontrakt nie przewiduje pola, nie powinno być akceptowane „na wszelki wypadek”.

Ważne: walidacja musi być realizowana po stronie narzędzia/serwera, nie „w promptcie”. Tekstowe instrukcje dla modelu są pomocne, ale nie są mechanizmem bezpieczeństwa.

Limity i bezpieczne „bezpieczniki” (rate limits, quotas, timeouts)

Nawet poprawne wywołania mogą stać się problemem, jeśli agent wykona ich za dużo albo zbyt długo będzie próbował „dopiąć” rezultat. Limity są prostą, skuteczną kontrolą szkód oraz kosztów:

  • Rate limiting: maksymalna liczba wywołań na minutę/godzinę (na użytkownika, sesję, narzędzie, akcję).
  • Quotas: dzienne/tygodniowe limity wolumenów (np. liczba wysłanych wiadomości, liczba utworzonych rekordów).
  • Timeouty i limity zasobów: maksymalny czas wykonania, rozmiar odpowiedzi, liczba zwracanych elementów.
  • Idempotencja i deduplikacja: klucze idempotencyjne ograniczające skutki powtórzeń (np. ponowne wysłanie tego samego żądania).
  • Backoff i circuit breaker: kontrolowane wycofanie przy błędach zamiast „młócenia” API w pętli.

Limity powinny być dobierane do rodzaju akcji: inne dla odczytów, inne dla zapisów, a najbardziej restrykcyjne dla operacji nieodwracalnych.

Minimalny przykład kontraktu + walidacji (uzupełniająco)

{
  "tool": "search_customers",
  "input_schema": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "query": {"type": "string", "minLength": 1, "maxLength": 120},
      "limit": {"type": "integer", "minimum": 1, "maximum": 25}
    },
    "required": ["query"]
  },
  "guards": {
    "rate_limit_per_minute": 30,
    "timeout_ms": 1500
  }
}

Istotne elementy to: additionalProperties=false (brak „ukrytych” pól), krótkie zakresy oraz limit wyników. To nie zastępuje pełnego projektu, ale pokazuje kierunek: kontrakt + walidacja + limity w jednym miejscu.

Najczęstsze błędy w praktyce

  • „Jedno narzędzie do wszystkiego” (np. dowolny HTTP/SQL) udostępnione agentowi dla wygody integracji.
  • Walidacja tylko po stronie klienta lub oparta na zaufaniu do modelu.
  • Brak ograniczeń rozmiaru (payloadów, odpowiedzi, liczby rekordów), co ułatwia nadużycia i generuje koszty.
  • Niejawne rozszerzenia kontraktu („przyjmijmy każde pole, może się przyda”) prowadzące do niekontrolowanych ścieżek wykonania.
  • Nadmierne uprawnienia endpointów (np. endpoint „update” pozwala modyfikować zbyt wiele pól naraz).

Dobrze zaprojektowana allowlist i kontrola powierzchni API nie eliminują wszystkich ryzyk, ale znacząco redukują klasę problemów: agent ma mniej „możliwości do improwizacji”, a system ma więcej twardych, wymuszanych barier.

💡 Pro tip: Zamiast dawać agentowi „uniwersalne” HTTP/SQL, udostępnij mu wyłącznie allowlistę wąskich operacji z twardym kontraktem (typy, zakresy, additionalProperties=false) i serwerową walidacją. Dodaj bezpieczniki (rate limit, quota, timeout, idempotencja), aby nawet poprawne wywołania nie mogły eskalować w kosztowne lub destrukcyjne serie.

5. Uprawnienia per-akcja zamiast per-bot: minimalny zakres, role, tokeny krótkotrwałe, kontekst

Najczęstszy błąd w projektowaniu narzędzi dla agentów polega na nadawaniu uprawnień „na stałe” całemu botowi. To wygodne operacyjnie, ale w praktyce oznacza, że każda pomyłka modelu, podatność w narzędziu, czy skuteczny prompt injection może zostać użyty z pełną mocą przyznanych uprawnień. Alternatywą jest podejście per-akcja: uprawnienia są przyznawane na konkretną czynność, w konkretnym kontekście, na możliwie krótki czas i z minimalnym zakresem.

Per-bot vs per-akcja: o co chodzi

Uprawnienia per-bot przypominają klucz uniwersalny: agent „ma dostęp” i korzysta z niego, gdy uzna to za potrzebne. Uprawnienia per-akcja przypominają jednorazową przepustkę: agent musi uzyskać autoryzację dla danego działania, a przepustka jest ważna tylko w tym przypadku.

Cecha Uprawnienia per-bot Uprawnienia per-akcja
Zakres Szeroki, „na zapas” Minimalny, dopasowany do działania
Czas życia Długi (stałe klucze / tokeny) Krótki (tokeny krótkotrwałe, jednorazowe)
Bezpieczeństwo przy błędach agenta Błąd może eskalować do pełnych uprawnień Błąd ogranicza się do małego wycinka możliwości
Rozliczalność Trudniej powiązać uprawnienie z intencją Łatwiej audytować „kto i po co” dla danej akcji
Wygoda wdrożenia Prostsze na start Wymaga zaprojektowania procesu autoryzacji

Minimalny zakres (least privilege) jako domyślna strategia

W podejściu per-akcja uprawnienia nie wynikają z tożsamości „bota”, tylko z konkretnej potrzeby. Dobrą praktyką jest projektowanie narzędzi tak, aby mogły przyjmować ograniczenia wprost w parametrach i politykach, np.:

  • tylko odczyt zamiast zapisu, jeśli agent ma „sprawdzić” stan;
  • ograniczenie do zasobu (konkretne konto/rekord/projekt) zamiast dostępu globalnego;
  • ograniczenie do operacji (np. „utwórz szkic”, a nie „publikuj”);
  • limity wartości (np. maksymalna kwota przelewu, liczba rekordów do modyfikacji, brak masowych operacji).

Role i delegowanie zamiast „super-bota”

Zamiast tworzyć jednego agenta z szerokim zestawem uprawnień, lepiej myśleć o rolach i delegowaniu. Agent może działać jako „koordynator”, ale realne operacje wykonują narzędzia w ramach ról, które są przydzielane na czas pojedynczego zadania. Przykładowo:

  • rola viewer dla odczytu danych,
  • rola editor dla zmian w wąskim zakresie,
  • rola approver wyłącznie do zatwierdzania, a nie do inicjowania operacji.

Kluczowa idea: agent nie powinien „mieć” roli na stałe — powinien otrzymywać ją, gdy jest to uzasadnione działaniem i kontekstem.

Tokeny krótkotrwałe: dostęp, który sam wygasa

Uprawnienia per-akcja najłatwiej egzekwować, gdy autoryzacja ma formę krótkotrwałych tokenów (np. ważnych minuty, a nie dni). Taki token powinien być:

  • ściśle związany z akcją (np. „wykonaj operację X”),
  • związany z zasobem (np. konkretny identyfikator obiektu),
  • związany z czasem (krótkie TTL) i najlepiej jednorazowy,
  • nieprzydatny poza kontekstem (próba użycia w innym scenariuszu powinna zostać odrzucona).

Efekt praktyczny: nawet jeśli agent „wypisze” token w logu, albo token wycieknie w wyniku błędu, jego użyteczność jest ograniczona czasowo i zakresem.

Kontekst jako część uprawnienia (a nie tylko promptu)

W systemach agentowych „kontekst” bywa traktowany wyłącznie jako informacja tekstowa. Dla bezpieczeństwa powinien być także twardym ograniczeniem autoryzacji. Oznacza to, że decyzja o przyznaniu uprawnień per-akcja uwzględnia m.in.:

  • tożsamość użytkownika (kto zleca zadanie),
  • cel działania (deklarowana intencja/typ zadania),
  • klasyfikację danych (czy operacja dotyczy danych wrażliwych),
  • środowisko (np. produkcja vs test),
  • stan procesu (np. czy to etap „analizy” czy „wykonania”).

Dzięki temu agent nie może „przeskoczyć” z niewinnego zadania do działania destrukcyjnego tylko dlatego, że potrafi wywołać narzędzie — musi spełnić warunki kontekstu zapisane w polityce dostępu.

Minimalny przykład: żądanie uprawnienia dla pojedynczej akcji

// Pseudokod: agent prosi o token do konkretnej operacji
requestPermission({
  action: "invoice.send",
  resource: { invoiceId: "INV-123" },
  scope: ["send"],
  constraints: { maxRecipients: 1 },
  context: { userId: "u-456", env: "prod" },
  ttlSeconds: 120
}) -> { token: "..." }

// Narzędzie akceptuje wyłącznie token przypięty do tej akcji i zasobu
invoiceSend({ invoiceId: "INV-123", recipient: "a@b.com" }, { token: "..." })

Najważniejsza różnica: narzędzie nie ufa „agentowi” jako bytowi. Ufa konkretnemu, ograniczonemu uprawnieniu dostarczonemu wraz z wywołaniem.

Kiedy per-akcja jest szczególnie istotne

  • Gdy agent ma dostęp do systemów z realnymi skutkami: finanse, zasoby produkcyjne, publikacje, usuwanie danych.
  • Gdy narzędzia operują na danych wrażliwych lub regulowanych.
  • Gdy agent wykonuje złożone plany (wiele kroków), gdzie pojedynczy krok może zostać „przechwycony” przez złośliwy kontekst.
  • Gdy wielu użytkowników korzysta z jednego agenta — uprawnienia muszą być ściśle powiązane z konkretnym zleceniem.

Uprawnienia per-akcja zmieniają filozofię projektowania: zamiast próbować uczynić agenta „zawsze bezpiecznym”, zakładamy, że agent może się pomylić, a nawet zostać zmanipulowany — i dlatego maksymalnie ograniczamy skutki każdego pojedynczego wywołania narzędzia.

6. Audyt i rozliczalność: logi, ślady decyzyjne, identyfikatory żądań, retencja i monitoring

W systemach z agentami kluczowe pytanie brzmi nie tylko czy akcja była dozwolona, ale też kto, kiedy, dlaczego i na jakiej podstawie ją wykonał. Audyt i rozliczalność domykają projekt bezpieczeństwa: umożliwiają wykrywanie nadużyć, analizę incydentów, ograniczanie strat oraz udowodnienie zgodności z wymaganiami wewnętrznymi i regulacyjnymi. Co istotne, logowanie i monitoring muszą obejmować nie tylko warstwę infrastruktury, ale także interakcje modelu z narzędziami i decyzje podejmowane w toku wykonywania zadań.

Logi ≠ audyt: różne cele, różna jakość danych

Logi operacyjne często odpowiadają na pytanie „co się zepsuło?”, a audyt na „co się wydarzyło i kto za to odpowiada?”. W praktyce oznacza to inne wymagania dot. kompletności, integralności i kontekstu.

Obszar Cel Typowa zawartość Wymagania
Logi operacyjne Diagnoza awarii i wydajności Błędy, czasy odpowiedzi, kody statusu Przydatność w debugowaniu, agregacja
Logi bezpieczeństwa Detekcja nadużyć i anomalii Nieudane autoryzacje, przekroczenia limitów Szybkość alertów, korelacja zdarzeń
Audyt Rozliczalność i dochodzenie Tożsamości, decyzje, parametry akcji, źródło danych Integralność, pełny kontekst, retencja

Co logować przy narzędziach agentów (minimum użyteczne)

Aby odtworzyć przebieg zdarzeń, potrzebujesz spójnych wpisów dla: żądania użytkownika, planu/wyboru narzędzia, wywołań narzędzi oraz skutków (np. zapisów). Minimalny zestaw pól zwykle obejmuje:

  • Tożsamość i kontekst: identyfikator użytkownika/klienta, kanał, tenant/workspace, rola, środowisko (prod/test).
  • Identyfikatory korelacyjne: request_id (wejściowe), trace_id (przez cały przepływ), tool_call_id (per wywołanie narzędzia).
  • Opis akcji: nazwa narzędzia/endpointu, typ operacji (odczyt/zapis/usunięcie), wynik (success/fail), kod błędu.
  • Parametry i dane wejściowe: zapisane w formie zminimalizowanej (maskowanie/haszowanie), z podaniem schematu i wersji kontraktu.
  • Źródła danych: jakie dokumenty/rekordy były podstawą decyzji (identyfikatory, wersje), bez konieczności przechowywania pełnej treści.
  • Skutek: jakie obiekty zostały zmienione (ID zasobu), zakres zmian (np. liczba rekordów), idempotency key.
  • Metadane polityk: która reguła/guardrail zezwoliła/odrzuciła akcję, wraz z powodem.

Najczęstszy błąd to logowanie „wszystkiego” (w tym wrażliwych promptów i danych), a potem brak możliwości bezpiecznego udostępnienia logów lub ich długotrwałego przechowywania. Lepszym podejściem jest projekt logów jako produktu: pola są celowe, ustandaryzowane i poddane redakcji.

Ślady decyzyjne: dlaczego agent zrobił to, co zrobił

Ślad decyzyjny nie musi oznaczać zapisu pełnego „łańcucha myśli”. Wystarczy praktyczny zapis uzasadnienia na poziomie audytowym: jakie cele i ograniczenia obowiązywały, jakie narzędzie wybrano i na podstawie jakich źródeł. Taki zapis wspiera analizę incydentów bez ujawniania wrażliwych szczegółów.

  • Cel: skrócony opis zadania (np. „wygeneruj raport i wyślij do X”).
  • Przesłanki: identyfikatory dokumentów/rekordów użytych jako podstawa.
  • Ograniczenia: zastosowane reguły (np. limit kwoty, zakres dozwolonych domen).
  • Decyzja: wybrane narzędzie i typ operacji + wynik walidacji.

Identyfikatory żądań i korelacja zdarzeń

Bez konsekwentnych identyfikatorów korelacyjnych audyt jest fragmentaryczny: masz osobno logi aplikacji, narzędzi i infrastruktury, ale nie potrafisz poskładać ich w jedną historię. Wymagane jest propagowanie identyfikatorów przez cały przepływ:

  • request_id — generowany na wejściu (API gateway / backend) i zwracany klientowi.
  • trace_id — wspólny dla wszystkich usług w transakcji (telemetria rozproszona).
  • tool_call_id — unikalny dla wywołania narzędzia; pomaga rozliczać koszt, limity i skutki.
  • actor_id — kto inicjuje: użytkownik, system, harmonogram; opcjonalnie „delegowany kontekst” (działanie w imieniu kogo).

Warto także logować wersje: wersję narzędzia/kontraktu oraz konfigurację polityk. Ułatwia to zrozumienie, czemu ta sama akcja wczoraj była dozwolona, a dziś już nie.

Retencja i minimalizacja danych: ile, jak długo i w jakiej formie

Retencja to kompromis między potrzebami audytu a ryzykiem ekspozycji danych. Dobre praktyki koncentrują się na: (1) minimalizacji, (2) rozdzieleniu danych wrażliwych, (3) kontroli dostępu do logów.

  • Minimalizacja: przechowuj identyfikatory i metadane zamiast pełnych treści (np. ID dokumentu zamiast jego zawartości).
  • Redakcja: maskowanie pól (np. e-mail, tokeny, numery), skracanie i haszowanie.
  • Segmentacja: oddziel logi audytowe od debugowych; inne uprawnienia i inne okresy retencji.
  • Integralność: zabezpieczenia przed modyfikacją wpisów (np. WORM/append-only), kontrola spójności.
  • Dostęp: restrykcyjny dostęp „need-to-know”, z własnym audytem dostępu do audytu.

Monitoring i alertowanie: wykrywanie nadużyć w czasie zbliżonym do rzeczywistego

Audyt „po fakcie” nie wystarczy, jeśli agent może wykonywać operacje kosztowne lub nieodwracalne. Monitoring powinien wykrywać anomalie i sygnały naruszeń na poziomie narzędzi:

  • Nietypowa częstotliwość wywołań danego narzędzia lub skoki wolumenu (np. masowe odczyty/eksporty).
  • Wzrost odrzuceń walidacji/allowlist/limitów — może wskazywać na próby obejścia polityk.
  • Zmiana profilu działań: nowy typ operacji, nowy zakres zasobów, nowe regiony/IP.
  • Próby dostępu do zasobów spoza typowego kontekstu użytkownika/tenantu.
  • Powtarzalne błędy narzędzi (mogą maskować próby enumeracji lub ataki na integracje).

Alerty powinny być powiązane z identyfikatorami korelacyjnymi, aby z poziomu jednego sygnału (np. „nietypowe masowe operacje”) dało się odtworzyć pełen przebieg: od wejścia użytkownika, przez wybór narzędzi, po skutki w systemach docelowych.

Krótki przykład struktury wpisu audytowego

{
  "timestamp": "2026-03-25T10:15:30Z",
  "request_id": "req_...",
  "trace_id": "trace_...",
  "tool_call_id": "tool_...",
  "actor": { "type": "user", "id": "user_...", "tenant": "t_..." },
  "action": { "tool": "payments.create", "operation": "write" },
  "policy": { "decision": "allow", "rule_id": "limit_amount_v2" },
  "inputs": { "amount": 2500, "currency": "PLN", "recipient_id": "rec_..." },
  "effects": { "resource_type": "payment", "resource_id": "pay_..." },
  "result": { "status": "success" }
}

W praktyce pola inputs i effects wymagają redakcji i standaryzacji, ale już sam szkielet pokazuje, jak łączyć rozliczalność (kto/co) z korelacją (trace/tool_call) i z polityką (dlaczego).

Akcje wysokiego ryzyka: zatwierdzanie (human-in-the-loop), polityki i „dry-run + confirm”

Nawet przy dobrych zabezpieczeniach narzędzi agent może podjąć decyzję, która jest nieodwracalna, kosztowna lub narusza zasady organizacji. Dlatego dla wybranych operacji należy traktować wykonanie jak proces dwuetapowy: najpierw propozycja, potem świadoma zgoda. Celem nie jest spowalnianie wszystkiego, tylko ograniczenie ryzyka tam, gdzie skutki błędu są największe.

Akcje wysokiego ryzyka to takie, które spełniają przynajmniej jedno z poniższych kryteriów: są trudne do cofnięcia, wpływają na wiele zasobów, ujawniają wrażliwe dane, generują koszty lub zmieniają stan systemu w sposób mogący wywołać efekt domina.

  • Nieodwracalność: usunięcia, nadpisania, resetowanie dostępu, masowe migracje.
  • Wrażliwość danych: eksport, udostępnianie, wysyłka na zewnątrz, dostęp do tajemnic i danych osobowych.
  • Skutki finansowe: płatności, zakupy, uruchamianie zasobów w chmurze, zmiany planów/budżetów.
  • Zasięg: operacje masowe, działania na produkcji, zmiany konfiguracji bezpieczeństwa.

W praktyce stosuje się trzy uzupełniające się mechanizmy:

  • Human-in-the-loop (HITL): agent przygotowuje plan i konkretne parametry operacji, ale wykonanie następuje dopiero po zatwierdzeniu przez człowieka. Zatwierdzający powinien zobaczyć jasne „co, gdzie, na jaką skalę i z jakim skutkiem”, a nie jedynie ogólny opis.
  • Polityki: z góry określone reguły mówią, które działania wymagają zatwierdzenia, które są blokowane, a które dozwolone automatycznie. Polityka powinna uwzględniać kontekst (np. środowisko, zakres, typ danych), a nie tylko nazwę akcji.
  • „Dry-run + confirm”: najpierw symulacja lub podgląd skutków (lista obiektów, które zostaną zmienione, przewidywany koszt, potencjalne konsekwencje), a dopiero potem potwierdzenie wykonania tej samej operacji w niezmienionej postaci. To ogranicza ryzyko, że agent lub użytkownik „zatwierdzi w ciemno”.

Kluczowe jest, by zatwierdzanie nie było fasadowe. Dobra bramka ryzyka:

  • rozróżnia propozycję od wykonania i nie pozwala agentowi „przeskoczyć” etapu zgody,
  • wymusza jednoznaczne parametry (konkretne identyfikatory zasobów, zakres, limity),
  • zapewnia, że potwierdzenie dotyczy dokładnie tej symulowanej operacji (bez podmiany celu po drodze),
  • preferuje małe kroki dla działań masowych (np. potwierdzenie partii zamiast całości).

Warto też przewidzieć tryby awaryjne: gdy polityka blokuje wykonanie, agent powinien umieć zaproponować bezpieczniejszą alternatywę (mniejszy zakres, wersja tylko do odczytu, przygotowanie raportu zamiast modyfikacji), zamiast eskalować do ryzykownego działania.

💡 Pro tip: Dla akcji nieodwracalnych/kosztownych stosuj model dwuetapowy: dry-run pokazujący dokładny zakres i skutki, a potem confirm tego samego, niezmienionego żądania. Zaszyj w politykach, co wymaga HITL lub jest blokowane, i wymuszaj małe kroki (partie) zamiast „zatwierdzania w ciemno” masowych operacji.

8. Przykłady polityk i implementacji: wysyłka maila, przelew, usunięcie rekordu oraz ograniczenia danych

Polityki bezpieczeństwa dla narzędzi agentów warto opisywać w formie krótkich, sprawdzalnych reguł: kto może wykonać jaką akcję, na jakich danych, w jakim kontekście i z jaką kontrolą (limity, zatwierdzenia, ślad audytowy). Poniższe przykłady pokazują różne klasy ryzyka i typowe zabezpieczenia, bez wchodzenia w szczegóły mechanizmów wykonania.

Wysyłka maila (ryzyko: wyciek danych, phishing, reputacja)

  • Ograniczenia odbiorców: domyślnie allowlista domen/odbiorców; wysyłka na zewnątrz organizacji tylko po spełnieniu dodatkowych warunków (np. uzasadnienie celu, ręczne zatwierdzenie lub ograniczenie do określonych szablonów).
  • Ograniczenia treści: zakaz wysyłki danych wrażliwych (np. dane płatnicze, identyfikatory, dane medyczne) lub wymóg automatycznego maskowania; blokada linków/załączników o wysokim ryzyku.
  • Tryb „podgląd przed wysyłką”: agent przygotowuje wersję roboczą, a faktyczna wysyłka następuje dopiero po potwierdzeniu użytkownika, jeśli spełnione są kryteria ryzyka (nowy odbiorca, treść zawiera dane zewnętrzne, nietypowy temat).
  • Limity i tempo: limity dzienne i minutowe, aby ograniczyć skutki błędów (np. pętli) lub przejęcia.
  • Ślad audytowy: rejestrowanie metadanych (kto zainicjował, do kogo, temat, klasyfikacja danych), z minimalizacją przechowywania pełnej treści, jeśli nie jest to konieczne.

Przelew / płatność (ryzyko: bezpośrednia strata finansowa, oszustwo)

  • Zasada dwóch kroków: agent może przygotować dyspozycję, ale wykonanie wymaga osobnego potwierdzenia (np. przez użytkownika lub dodatkowy kanał autoryzacji) dla każdej transakcji lub powyżej progów kwotowych.
  • Ograniczenia beneficjenta: przelewy tylko do zaufanych odbiorców (z listy zatwierdzonych), a dodanie nowego odbiorcy to osobna akcja o wyższym poziomie kontroli.
  • Progi i reguły ryzyka: twarde limity kwotowe per transakcja i per okres, wykrywanie nietypowych wzorców (np. nagły wzrost kwot, wiele przelewów do nowych odbiorców).
  • Silne powiązanie kontekstu: dyspozycja musi być związana z konkretnym celem biznesowym (np. numer faktury) i zestawem danych źródłowych; brak możliwości „dowolnego przelewu” bez uzasadnienia i walidacji.
  • Minimalizacja danych: agent widzi tylko te informacje, które są potrzebne do przygotowania dyspozycji (np. nie pełną historię rachunku, jeśli nie jest to wymagane).

Usunięcie rekordu (ryzyko: utrata danych, naruszenie zgodności, nieodwracalność)

  • Preferencja dla operacji odwracalnych: zamiast trwałego usunięcia — archiwizacja, oznaczenie jako nieaktywne, kosz z możliwością przywrócenia; trwałe usunięcie zarezerwowane dla wyjątków.
  • Zakres działania: usuwanie tylko w obrębie jasno określonych zasobów (np. jeden rekord, jedna kolekcja), z blokadą masowych operacji bez osobnego trybu i autoryzacji.
  • Warunki wstępne: wymagane sprawdzenie zależności (np. rekord powiązany z rozliczeniami), zgodność z retencją oraz polityką przechowywania.
  • Potwierdzenie z podsumowaniem skutków: przed wykonaniem agent przedstawia, co dokładnie zostanie usunięte i jakie są konsekwencje; potwierdzenie jest obowiązkowe dla działań nieodwracalnych.
  • Dowód wykonania: logowanie identyfikatorów rekordów, podstawy prawnej/uzasadnienia oraz osoby zatwierdzającej, przy jednoczesnym ograniczeniu ekspozycji danych treściowych.

Ograniczenia danych (ryzyko: wyciek, nadmierne uprawnienia, niekontrolowane użycie)

Niezależnie od typu akcji, polityki danych powinny definiować, jakie informacje agent może zobaczyć, przetwarzać i przekazać dalej. Praktyczne ograniczenia to:

  • Klasyfikacja i etykiety: dane oznaczone jako wrażliwe nie mogą trafiać do narzędzi wyjściowych (np. e-mail, eksport) bez dodatkowych zabezpieczeń.
  • Minimalny zakres: agent otrzymuje tylko fragmenty danych potrzebne do danej czynności (np. identyfikator i status zamiast pełnego rekordu), a nie „pełny dostęp na wszelki wypadek”.
  • Granice między źródłami: zakaz łączenia wybranych kategorii danych (np. danych osobowych z danymi finansowymi) w jednym wyjściu, jeśli nie ma ku temu uzasadnienia.
  • Reguły eksportu: limity wielkości i liczby rekordów, blokada masowego pobierania, kontrola formatów wyjściowych oraz wymóg anonimizacji/pseudonimizacji tam, gdzie to możliwe.
  • Polityki retencji i widoczności: ograniczenie przechowywania treści w logach i narzędziach pośrednich; preferowanie metadanych i skrótów tam, gdzie pełna treść nie jest konieczna.

Wspólnym mianownikiem tych przykładów jest to, że agent nie dostaje „jednego, szerokiego uprawnienia”. Zamiast tego każda akcja ma własne, mierzalne ograniczenia: dopuszczalny cel, zakres danych, progi ryzyka, wymagane potwierdzenia oraz wymagany ślad rozliczalności.

Jeśli chcesz poznać więcej takich przykładów, zapraszamy na szkolenia Cognity, gdzie rozwijamy ten temat w praktyce.

icon

Formularz kontaktowyContact form

Imię *Name
NazwiskoSurname
Adres e-mail *E-mail address
Telefon *Phone number
UwagiComments