Teams Built Judikt: Płaszczyzna kontroli bezpieczeństwa i niezawodności dla agentów AI wykorzystujących MCP
Praktyczny przewodnik po Teams Built Judikt: płaszczyźnie kontroli bezpieczeństwa i niezawodności dla agentów AI wykorzystujących MCP – kontrakty, sprawdzania oraz gotowe elementy kodu dostępne dla zespołów tworzących rozwiązania oparte na MCP.
To przewodnik odtwarza proces od surowców aż do gotowego systemu w ramach projektu: I Built Judikt: A Security and Reliability Control Plane for AI Agents Using MCP. Skupia się on na krokach operacyjnych, wyraźnych sprawdzeniach oraz kodzie, który można bez problemu dodać do repozytorium, nie musząc zgadywać intencji twórcy. Aby uzyskać ogólny obraz, należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu systemu. Należy udokumentować zarówno prawidłowy przebieg procesu, jak i ścieżkę naprawczą. Próby ponownych działań, kontrola przez ludzi oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później.
Czym jest Judikt?
Gdy pracujesz nad „Co to jest Judikt?”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na jedną konkretne odpowiedzialność, a nie na skomplikowany łańcuch operacji. Zapisuj nazwę narzędzia, hash argumentów, opóźnienie oraz wynik każdego wywołania. Bez takich informacji debugowanie pętli agenta traci godziny.
Problem, który chciałeś rozwiązać
Gdy pracujesz nad problemem, który chcesz rozwiązać, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadania. Zapisuj nazwę narzędzia, hash argumentów, czas reakcji oraz wynik każdej wywołania. Bez takich informacji debugowanie trwa godzinami.
Jak żądanie przepływa przez Judikt
Gdy analizujesz, jak żądanie przepływa przez Judikt, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zapisz czasy wykonywania oraz koszt tokena lub zapytania obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy ścieżka przechodzi z wersji demo do środowisk współdzielonych. Zapisz nazwę narzędzia, hash argumentów, opóźnienie oraz wynik każdego wywołania. Bez takich informacji debugowanie pętli agenta marnuje godziny.
AI agent or MCP client
|
v
Authentication and actor binding
|
v
Tool allowlist and argument inspection
|
v
Risk scoring and environment checks
|
v
Rate limit, approval, rollback plan, kill switch
|
+---- DENY / REQUIRE_APPROVAL / DRY_RUN_ONLY
|
v
Pinned MCP tool-definition verification
|
v
JSON-RPC tools/call over stdio or Streamable HTTP
|
v
Operational backend or external MCP server
|
v
Prompt-injection inspection and secret redaction
|
v
Agent-visible result
|
v
Signed audit event, metrics, traces, and findings
Gdy analizujesz, jak żądanie przepływa przez Judikt, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Dokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Powtórne próby, mechanizmy ludzkiej kontroli oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później.
Co faktycznie działa w lokalnej demonstracji
To, co faktycznie działa w lokalnej demonstracji, najlepiej funkcjonuje, gdy traktuje się je jako mierzalną powierzchnię. Zapisz jeden idealny przypadek działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Używaj narzędzi o wąskich schematach oraz z wyraźnymi etykietami efektów ubocznych. Hostowie muszą wiedzieć, które wywołania zmieniają stan, zanim automatycznie je zatwierdzą.
runtime.call_tool(
"platform-ops",
"platform.health",
{"service": "payments-api"},
)
python -m judikt.cli backend platform-ops
JudiktRuntime.call_tool
-> PolicyEngine.evaluate
-> StdioMCPClient.call_tool
-> JSON-RPC tools/call
-> PlatformOpsBackend.call
-> ContentGuard.inspect
-> PolicyEngine.redact
-> AuditStore.record
-> Metrics.observe
-> ToolCallResult
Operacyjne backendy
Części operacyjne działają najlepiej, gdy traktuje się je jako mierzalną powierzchnię. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadań. Używaj narzędzi o wąskich schematach oraz z wyraźnymi etykietami opisującymi efekty uboczne. Hostowie muszą wiedzieć, które wywołania zmieniają stan systemu, zanim automatycznie je zatwierdzą.
Rządzenie po stronie żądania
Zarządzanie po stronie żądania działa najlepiej, gdy jest traktowane jako mierzalna struktura. Zanim rozszerzy się zakres, należy zarejestrować jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian. Obok wyników funkcjonalnych należy zapisywać czasy wykonywania oraz koszt tokenów lub zapytań. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy proces przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Należy udostępniać narzędzia o wąskich schematach oraz z wyraźnymi etykietami opisującymi efekty uboczne. Hostowie muszą wiedzieć, które wywołania zmieniają stan, zanim automatycznie je zatwierdzą. Zarządzanie po stronie żądania działa najlepiej, gdy jest traktowane jako mierzalna struktura. Zanim rozszerzy się zakres, należy zarejestrować jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian. Należy udokumentować zarówno prawidłowy przebieg działania, jak i ścieżkę naprawczą. Próby ponownych wysyłek, kontrola przez ludzi oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później.
Naprawa wymagająca zatwierdzenia
Dla napraw wymagających zatwierdzenia należy określić dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanej punktacji kontrolnej, bez konieczności zgadywania ukrytego stanu. Należy preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy dany krok zawiedzie, powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany proces. Autoryzuj się przy bramie wejściowej, a ponownie udziel uprawnień na poziomie warstwy danych. Sam token nośny nie stanowi granicy między usługami.
Próba bez faktycznej realizacji, tryb cieniowy i mechanizmy wyłączania
Dla trybu próbnego, trybu cienia oraz mechanizmów wyłączania należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzuć przypadkowe, częściowe ukończenie zadania. Zaloguj się przy bramie dostępu i ponownie udziel uprawnień na poziomie płaszczyzny danych. Sam token nie stanowi granicy między poszczególnymi usługami.
Obrona ścieżki odpowiedzi
Aby chronić ścieżkę odpowiedzi, należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić ten krok od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy rejestrować czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy ścieżka przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Należy uwierzytelniać się przy bramie wejściowej, a ponownie autoryzować w warstwie danych. Sam token nie stanowi granicy między poszczególnymi użytkownikami. Aby chronić ścieżkę odpowiedzi, należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić ten krok od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy udokumentować zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponownych działań, mechanizmy ludzkiej kontroli oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później.
Cenzura i tajemnice
Gdy pracujesz nad redakcją i sekretami, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Wolę małe, testowalne jednostki niż rozbudowane skrypty. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na jedną konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Zapisuj nazwę narzędzia, hash argumentów, opóźnienie oraz wynik każdego wywołania. Bez takich informacji debugowanie agenta trwa godzinami.
Dowody audytowe wskazujące na ingerencję
Gdy przeglądasz dowody audytowe odpornie na modyfikacje, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzuć możliwość cichego, częściowego ukończenia zadania. Zapisuj nazwę narzędzia, hash argumentów, czas opóźnienia oraz wynik każdego wywołania. Bez takich informacji debugowanie trwa godzinami.
Obserwowalność
Gdy zajmujesz się kwestiami związanymi z obserwowalnością, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego awarii. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zapisz czas wykonywania oraz koszt tokena lub zapytania obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy ścieżka przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Zapisz nazwę narzędzia, hash argumentów, opóźnienie oraz wynik każdego wywołania. Bez takich informacji debugowanie agentów trwa godzinami. Gdy zajmujesz się kwestiami związanymi z obserwowalnością, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego awarii. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Dokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Powtórne próby, mechanizmy ludzkiej kontroli oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później.
Co obejmuje demonstracja
To, co obejmuje demonstracja, działa najlepiej, gdy traktuje się to jako mierzalną powierzchnię. Zapisz jeden udany przypadek, jeden przypadek awarii oraz notatkę o cofnięciu zmian, zanim rozszerzysz zakres. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Używaj narzędzi o wąskich schematach oraz z wyraźnymi etykietami efektów ubocznych. Hostowie muszą wiedzieć, które wywołania zmieniają stan, zanim automatycznie je zatwierdzą.
Opcje wdrażania
Opcje wdrażania działają najlepiej, gdy traktuje się je jako mierzalną powierzchnię do analizy. Zapisz jeden idealny przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Traktuj tę fazę jako umowę pomiędzy wprowadzanymi danymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzuć przypadki częściowego ukończenia bez informacji.
Testowanie i weryfikacja bezpieczeństwa
Testowanie i weryfikacja bezpieczeństwa działają najlepiej, gdy traktuje się je jako mierzalną powierzchnię do analizy. Zapisz jeden idealny zapis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres testów. Zapisuj czasy wykonywania operacji oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy proces przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Używaj narzędzi o wąskich schematach i wyraźnych etykietach dotyczących efektów ubocznych. Hostowie muszą wiedzieć, które wywołania zmieniają stan systemu, zanim automatycznie je zatwierdzą. Testowanie i weryfikacja bezpieczeństwa działają najlepiej, gdy traktuje się je jako mierzalną powierzchnię do analizy. Zapisz jeden idealny zapis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres testów. Zdokumentuj zarówno optymalną ścieżkę działania, jak i ścieżkę przywracania do stanu poprzedniego. Próby ponownych wywołań, kontrola przez ludzi oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później.
Czego nadal nie rozwiązano
Dla problemów, które nadal nie zostały rozwiązane, należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy dany krok zawiedzie, powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Autoryzuj się przy bramie wejściowej, a ponownie udzielaj uprawnień na poziomie przesyłania danych. Sam token nie stanowi granicy między poszczególnymi użytkownikami.
Co się nauczyłeś
Zgodnie z tym, czego się nauczyłeś, przed modyfikacją kodu należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia. Operatorzy powinni móc ponownie uruchomić ten krok od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadania. Zaloguj się przy bramie dostępu i ponownie uzyskaj uprawnienia na poziomie warstwy danych. Sam token nośny nie stanowi granicy dzierżawy.
Próbuj projektu
Aby wypróbować projekt, zdefiniuj dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić ten krok od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Zapisz czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy ścieżka przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Zaloguj się przy bramce wejściowej i ponownie uzyskaj uprawnienia na poziomie warstwy danych. Sam token nie stanowi granicy między poszczególnymi użytkownikami.
git clone https://github.com/gaurav-gs7/Judikt.git
cd Judikt
./scripts/run_demo.sh --audit-db /tmp/judikt-demo.db
Aby wypróbować projekt, zdefiniuj dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić ten krok od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Zdokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponownych działań, mechanizmy ludzkiej kontroli oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później.
Lista kontrolna operacyjna
List kontrolny operacyjny działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię do analizy. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres.
Zachowaj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności przeglądania całej struktury.
Używaj narzędzi o wąskich schematach i wyraźnych etykietach dotyczących efektów ubocznych. Hostowie muszą wiedzieć, które wywołania zmieniają stan systemu, zanim automatycznie je zatwierdzą.
Zastosuj ludzką aprobatę w przypadku operacji, które wiążą się z wydawaniem pieniędzy lub modyfikacją danych produkcyjnych. Połączenia skompilowane w czasie kompilacji nie gwarantują pełnej kompletności biznesowej.
Napisz krótki podręcznik: jak rotować klucze, jak opróżnić kolejkę z zadań, jak cofnąć ostatnie operacje importu.
Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi danymi wyjściowymi. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadań.
Zanim zaczniesz promować tę architekturę, zamroź wersje, utwórz dokładny zapis dla kluczowych etapów realizacji oraz potwierdź kroki odwracania zmian. Środowiska współdzielone wymagają ograniczeń szybkości, weryfikacji przynależności użytkowników oraz wyraźnego właściciela odpowiedzialnego za rotację haseł. Wolimy nudną niezawodność od pomysłowych, jednorazowych demonstracji.
Uwaga dotycząca wersji 2580b5835abc: unikaj przechowywania kluczy dostawcy w repozytorium, ustaw ograniczenie liczby tokenów na sesję oraz przechowuj zapisy obok plików konfiguracyjnych, aby późniejsze zmiany modeli pozostawały porównywalne.