Twój agent AI w Elevare Digital przeszedł w stan bezczynności, ponieważ nowo dodana polityka bezpieczeństwa na poziomie wiersza (RLS) w PostgreSQL odfiltrowała wszystkie wiersze z zadaniami, przez co kolejka wydawała się pusta. Błąd pozostał niezauważony, dopóki zadania nie zaczęły się piętrzyć, co zmusiło zespół do zaprojektowania na nowo sposobu, w jaki orchestrator wykrywa pustą kolejkę.
Ukryta martwa strefa
ARIA, autonomiczny system AI firmy Elevare, odpytuje tabelę PostgreSQL w poszukiwaniu oczekujących zadań. Zapytanie zakończyło się sukcesem, zwróciło zero wierszy, a agent „zasnął”. W rzeczywistości tabela była pełna. Polityka RLS ograniczyła dostęp SELECT do konkretnego zestawu użytkowników. Orchestrator połączył się przy użyciu roli serwisowej (service role), która nie posiadała uprawnienia do omijania polityk (bypass privilege), więc baza danych po cichu usunęła każdy wiersz z zestawu wyników. PostgreSQL traktuje odczyt przefiltrowany tak samo jak pustą tabelę, więc nie pojawił się żaden błąd, ostrzeżenie ani kod błędu. Regularny sygnał heartbeat od bezczynnego agenta nie dawał żadnej wskazówki, że coś jest nie tak.
Jak RLS zamieniło pełną kolejkę w ciszę
RLS dodaje predykat do każdego wiersza podczas operacji SELECT. Jeśli predykat jest fałszywy, wiersz znika z wyniku. Klient widzi tylko te wiersze, które spełniają politykę; nigdy nie dowiaduje się, że inne wiersze zostały ukryte. Dla procesora kolejki (queue worker) pusty zestaw wyników wygląda dokładnie tak samo, jak faktycznie pusta kolejka. Orchestrator założył, że „brak wierszy = brak pracy” i przeszedł w pętlę bezczynności, podczas gdy zadania gromadziły się w tle.
Zespół odkrył, że polityka, która miała ograniczać odczyty do poszczególnych użytkowników, nieumyślnie objęła również samą rolę serwisową. Ponieważ rola ta nie posiadała specjalnego atrybutu „bypass RLS”, polityka została zastosowana do każdego zapytania wysyłanego przez orchestrator. Ilustruje to klasyczny kompromis między bezpieczeństwem a obserwowalnością (observability): RLS chroni dane przed nieuprawnionymi użytkownikami, ale jednocześnie usuwa przydatny sygnał o błędzie dla komponentów systemu, które polegają na widoczności danych.
Wzorzec „canary check”
Aby przerwać zależność od cichego, pustego wyniku, Elevare dodało sprawdzanie typu „canary” (kanarek). Nowy przepływ wygląda następująco:
- Odpytaj tabelę oczekujących zadań.
- Jeśli zwrócone zostaną wiersze, przetwórz je jak dotychczas.
- Jeśli wynik jest pusty, wykonaj drugie zapytanie do dedykowanego wiersza typu „canary”, który musi zawsze istnieć.
- Jeśli zapytanie „canary” zwróci oczekiwany wiersz, kolejka jest naprawdę pusta; zaloguj sygnał bezczynności (idle heartbeat).
- Jeśli zapytanie „canary” również nie zwróci niczego, agent jest „ślepy”; wygeneruj natychmiastowy alert.
Teraz orchestrator rozróżnia trzy stany:
- Jobs found – normalne przetwarzanie.
- No jobs, canary OK – rzeczywisty okres bezczynności.
- No jobs, canary failed – ukryte blokowanie przez RLS, uruchom alert.
Tabela „canary” to pojedynczy wiersz, który nigdy się nie zmienia. Jej konfiguracja zajęła około godziny, ale eliminuje ona całą klasę cichych awarii.
Co powinny robić zespoły
Jeśli uruchamiasz procesory kolejki w oparciu o PostgreSQL lub usługę hostowaną na jego bazie (taką jak Supabase), postępuj zgodnie z poniższymi krokami:
- Używaj poświadczeń roli serwisowej (service-role) z flagą „bypass RLS”. Pozwala to komponentom systemu widzieć wszystkie wiersze, niezależnie od polityk na poziomie użytkownika.
- Audytuj polityki RLS pod kątem braku uprawnień do omijania (bypass) dla ról serwisowych. Polityka, która wydaje się poprawna dla użytkowników końcowych, może nieumyślnie blokować usługi wewnętrzne.
- Dodaj tabelę „canary” (lub odpowiedni, stale obecny wiersz) i włącz sprawdzanie „canary” do logiki bezczynności procesora. Dodatkowe zapytanie jest tanie i zapewnia jasną siatkę bezpieczeństwa.
Kompromis
RLS pozostaje potężnym narzędziem do wymuszania szczegółowego dostępu do danych. Zapobiega przypadkowym wyciekom danych i wspiera architektury wielonajemne (multi-tenant) bez konieczności rozpraszania filtrów na poziomie aplikacji w całym kodzie źródłowym. Wadą jest to, że może on ukrywać awarie przed komponentami, które oczekują, że prosty sygnał „brak wierszy” oznacza „brak pracy do wykonania”. Wzorzec „canary” nie osłabia RLS; dodaje on lekki krok weryfikacji, który przywraca obserwowalność.
Podsumowanie
Ukryta polityka RLS może zamienić zajętą kolejkę w cichy ślepy zaułek, pozostawiając agentów AI w bezczynności, podczas gdy praca się piętrzy. Nadaj rolom serwisowym odpowiednie uprawnienia do omijania (bypass) i łącz każdy odczyt pustej kolejki ze sprawdzaniem „canary”; dzięki temu zespoły mogą zapewnić rzetelność swoim autonomicznym pracownikom i uniknąć kosztownych martwych stref.
