Najmniejsze uprawnienia (least-privilege) to jedna z najstarszych i najbardziej niezawodnych idei w bezpieczeństwie. Nadaj tożsamości dokładnie taki dostęp, jakiego potrzebuje, i nic ponadto, a zasięg rażenia każdego naruszenia pozostaje niewielki. W przypadku kont użytkowników i długowiecznych kont usługowych model ten sprawdza się całkiem dobrze: role są przeglądane, nadania są ograniczone do potrzebnego zakresu, a certyfikacje dostępu odbywają się w cyklu kwartalnym.
Agenci AI po cichu rozbijają ten model. Agent otrzymuje poświadczenie, narzędzie, połączenie z serwerem MCP i od tej chwili jego zachowanie jest dynamiczne. To on decyduje w czasie działania, które zasoby odczytać, do których zapisać, które narzędzie wywołać jako następne. Nadanie, które spisano pierwszego dnia, opisuje pułap, a nie to, co agent faktycznie robi. A ponieważ agenci są produktywni, pułap ten bywa zazwyczaj hojny: szerokie role bazodanowe, dostęp do zapisu „na wszelki wypadek”, jedno konto usługowe współdzielone przez pół tuzina przepływów pracy. W efekcie powstaje środowisko, w którym dostęp nadany i dostęp faktycznie wykorzystywany rozjeżdżają się, po cichu, każdego dnia.
Niezależne badania branżowe oddają skalę tego ślepego punktu: około 82% organizacji zgłasza, że działają u nich agenci AI, o których istnieniu nie wiedziały (CSA/Token Security, n=418). Nie da się egzekwować najmniejszych uprawnień w środowisku, którego się nie widzi.
Definicja dryfu najmniejszych uprawnień
Dryf najmniejszych uprawnień to rosnąca różnica między dostępem, który agentowi nadano, a dostępem, który u niego zaobserwowano. Ma on dwa kierunki awarii i tylko jeden z nich jest oczywisty.
Kierunkiem oczywistym jest niewykorzystanie: agent posiada dostęp do zapisu w tabeli, do której nigdy nic nie zapisał. To martwe uprawnienie i ryzyko, które ponosisz bez żadnej korzyści. Kierunkiem niebezpiecznym jest odwrotny sygnał, który z tego wynika: gdy zbiór zaobserwowany zawiera coś, czego zbiór nadany nigdy świadomie nie przyznał, mamy do czynienia z działaniem, którego nikt nie przejrzał. Zadanie eksportu, które nagle zapisuje do kubełka, z którego dotąd jedynie odczytywało. Agent, którego polityka ograniczyła do jednego schematu, sięgający do innego. To nie są przypadki egzotyczne; to codzienna tkanka agentów połączonych ze sobą za pomocą zbyt szerokich nadań.
Powód, dla którego jest to trudne, i powód, dla którego dotyczy to agentów, a nie ludzi, jest taki, że zachowanie jest generowane, a nie konfigurowane. Człowiek z nadmiernym dostępem w większości przypadków z niego nie korzysta. Agent z nadmiernym dostępem wykorzysta wszystko, co pomoże mu wykonać postawione przed nim zadanie, łącznie ze ścieżkami, których nikt nie przewidział. Statyczny przegląd polityki nie nadąża za zachowaniem, które zmienia się przy każdym uruchomieniu.
Zamiana dryfu w sygnał możliwy do przeglądu
Dryf jest groźny tylko dopóty, dopóki pozostaje niewidoczny. Zadanie polega na uczynieniu z niego sygnału, który człowiek może przejrzeć, a to wymaga współdziałania dwóch elementów: nieprzerwanej obserwacji tego, czego agenci faktycznie dotykają, oraz stabilnego zapisu tego, co wolno im było dotknąć.
Obserwacja musi działać w trybie read-first. Kolektor, który obserwuje na podstawie logów, śladów OpenTelemetry i sygnałów jądra eBPF, znajduje się poza ścieżką danych agenta. Nie jest proxy, nie bramkuje wywołań, a jeśli ulegnie awarii, to zawodzi w sposób bezpieczny (fail open): agent działa dalej, a ty tracisz widoczność, a nie dostępność. Ta asymetria ma znaczenie: mechanizm bezpieczeństwa, który może położyć produkcję, to mechanizm, który zespoły po cichu wyłączają. Warstwa eBPF działa w szczególności jako prawda absolutna na poziomie jądra (kernel-level ground truth), czyli ta część, której agent nie może obejść (przechwytywanie na poziomie jądra pochodzi z czujnika Tetragon, który sam wdrażasz; Olivares AI odczytuje eksport z Tetragona i sam nie ładuje programów eBPF) — i dlatego wskazówki na poziomie protokołu, takie jak adnotacje narzędzi MCP (readOnlyHint, destructiveHint), są z nią weryfikowane krzyżowo, a nie traktowane jako wiarygodne. Sama specyfikacja MCP mówi, że te adnotacje są niezaufane; to sygnały jądra sprawiają, że weryfikacja krzyżowa staje się realna.
Tym, co produkuje obserwacja, jest mapa dostępu: dla każdego agenta — do których zasobów sięgnął oraz czy odczytywał (R), czy odczytywał/zapisywał (RW). Mapa przechowuje relacje dostępu, a nie ładunki danych, sekrety ani dane osobowe. Najciekawsza jest różnica:
| Agent | Zasób | Nadane | Zaobserwowane | Dryf |
|---|---|---|---|---|
| data-export-job | prod-postgres | R | R | brak |
| data-export-job | s3://billing-exports | R | RW | nieprzejrzany zapis |
| report-builder | analytics-db | R | (niewykorzystane) | martwe uprawnienie |
Wierszem, który ma znaczenie, jest ten środkowy. Polityka nadała odczyt na kubełku eksportu; kolektor zaobserwował zapis. Ta jedna linia to sztandarowe ryzyko, które dryf najmniejszych uprawnień ma ujawniać: uprawnienie wykorzystane, którego nikt nie przejrzał, przypisane do konkretnego agenta, a nie do współdzielonego konta usługowego — ponieważ to właśnie tożsamość przypisana do pojedynczego agenta sprawia, że atrybucja i audyt są w ogóle możliwe.
Egzekwowanie w momencie dostępu, a nie tylko logowanie
Wykrywanie mówi ci, że dryf wystąpił. Aby domknąć pętlę, chcesz, by nieprzejrzany zapis był ścieżką zablokowaną, a nie zalogowaną. I tu wkracza polityka oceniana w momencie dostępu.
Olivares AI ocenia Cedar jako nakładkę forbid na role domyślnie odmawiające, więc reguła może tylko odebrać dostęp; ta odmawia każdego żądania dotyczącego tajnego poświadczenia, cokolwiek mówi rola.
permit(principal, action, resource);
forbid(principal, action, resource)
when { resource.kind == "credential" && resource.sensitivity == "secret" };
Pisanie własnych reguł Cedar wymaga Business; Community egzekwuje wbudowane role, natywną nakładkę odmowy i kill switch; role niestandardowe i zawężone uprawnienia należą do Business.
Prześledźmy konkretnie stan przed i po.
Przed. Agent kodujący, posiadający szeroką rolę, wywołuje narzędzie MCP, które zapisuje do s3://billing-exports. Nic go nie zatrzymuje. Działanie kończy się powodzeniem, wtapia się w normalny ruch i pojawia się dni później, o ile w ogóle, jako anomalia na mapie dostępu. Różnica między uprawnieniami nadanymi a zaobserwowanymi powiększyła się, a jedynym artefaktem jest linia w logu, której nikt nie przeczytał.
Po. To samo wywołanie narzędzia trafia do bramki MCP. Rola agenta nie pozwala na ten zapis, więc bramka odrzuca wywołanie, zanim zostanie wykonane (deny-closed), i zapisuje odmowę w podpisanym dzienniku audytu, w którym manipulacje są wykrywalne. Nieprzejrzany zapis nigdy nie staje się nieprzejrzaną zmianą. Olivares AI blokuje działanie wyłącznie w czterech punktach egzekwowania: wewnątrz Claude Code, w proxy modelu, przy każdym wywołaniu narzędzia MCP oraz między agentami. Zadanie zapisujące do S3 bezpośrednio, poza tymi punktami, nie jest blokowane: mapa dostępu rejestruje zapis i oznacza go jako dryf do przeglądu.
Dwie właściwości pozwalają zachować uczciwość tego rozwiązania. Po pierwsze, każdy uprzywilejowany wgląd w mapę dostępu sam podlega audytowi — kto co oglądał — ponieważ mapa jest wrażliwa, a narzędzie bezpieczeństwa, które nie potrafi rozliczyć własnych operatorów, nie jest godne zaufania. Po drugie, poziom pewności jest pokazywany wprost: krawędź, której źródło niesie tożsamość per agent, jest oznaczana jako attributed, a widziana wyłącznie przez jądro jako approximate, ponieważ sygnały jądra wskazują proces, cgroup lub kontener, a nie agenta. Nigdy nie zostaniesz poproszony o działanie na podstawie sfabrykowanej pewności.
Wniosek
Najmniejsze uprawnienia nie zawiodły w przypadku agentów AI; zawiódł cykl przeglądów. Nadania są zbyt szerokie, zachowanie jest dynamiczne, a kwartalne certyfikacje nie są w stanie śledzić powierzchni dostępu, która zmienia się przy każdym uruchomieniu. Rozwiązaniem nie jest cięższe proxy na ścieżce krytycznej. Jest nim nieprzerwana obserwacja w trybie read-first, która produkuje porównanie uprawnień nadanych z zaobserwowanymi, oraz policy-as-code, które egzekwuje skorygowaną granicę w momencie dostępu — tak aby nadmiernie uprzywilejowany agent został wychwycony jako sygnał możliwy do przeglądu na długo zanim przerodzi się w incydent.
Jeśli chcesz zobaczyć, jak kolektor, mapa dostępu i egzekwowanie w momencie dostępu współgrają ze sobą bez tkwienia na ścieżce danych Twoich agentów, strona architektura prowadzi przez projekt rozwiązania, a produkt pokazuje, jak widok uprawnień nadanych w zestawieniu z zaobserwowanymi wygląda w realnym środowisku.