Blog JSystems - uwalniamy wiedzę!
Blog JSystems - uwalniamy wiedzę!
Z tego artykułu dowiesz się:
/sandbox i jak wygląda tryb auto-allow (mniej pytań, twarda granica)@anthropic-ai/sandbox-runtime (polecenie srt) i jak izolować nim dowolny proces czy serwer MCPsettings.json--dangerously-skip-permissions i gdzie ma ograniczeniaKażdy, kto puścił Claude Code na dłuższe zadanie, zna dylemat. Zostawiasz agenta w domyślnym trybie i co chwilę zatrzymuje się z pytaniem, czy może uruchomić testy albo zapisać plik. Włączasz --dangerously-skip-permissions i agent przestaje pytać, ale razem z pytaniami znika każdy hamulec: od tej chwili może zrobić w systemie dosłownie wszystko. Przez długi czas była to więc realna wymiana: albo spokój i przerywanie co kilkanaście sekund, albo tempo i pełne ryzyko.
Piaskownica przecina ten dylemat. Zamiast wybierać między „pytaj o wszystko" a „nie pytaj o nic", stawiasz wokół agenta granicę, której pilnuje system operacyjny, a nie dobra wola modelu. Wewnątrz tej granicy agent pracuje swobodnie i bez pytań. Poza nią po prostu nie sięgnie: zapis w cudze pliki i połączenie z niedozwoloną domeną są odrzucane, zanim cokolwiek się wydarzy. W Claude Code korzystasz z niej na dwa sposoby: komendą /sandbox wewnątrz sesji oraz osobnym narzędziem @anthropic-ai/sandbox-runtime. Oba opisujemy poniżej, na realnych zrzutach i z działającą konfiguracją.
Zacznijmy od rozróżnienia, które porządkuje cały temat. Claude Code ma dwa niezależne mechanizmy bezpieczeństwa i łatwo je pomylić.
System uprawnień decyduje o tym, których narzędzi agent może użyć i na jakich zasobach: pozwól na Bash, zabroń odczytu .env, pytaj przed git push. Reguły sprawdzane są na poziomie decyzji modelu, zanim akcja w ogóle ruszy. Ich składnię, hierarchię plików i hooki opisaliśmy osobno w artykule Claude Code Permissions - system uprawnień, settings.json i hooki.
Piaskownica działa piętro niżej. Nie interesuje jej, co postanowił model; ogranicza to, do czego dobrać się może już uruchomiony proces powłoki (shella) i wszystkie jego procesy potomne. Jeśli komenda Bash odpali skrypt Pythona, a ten wywoła curl, granica obejmuje całą tę kaskadę. Wymusza ją jądro systemu, więc obowiązuje niezależnie od tego, czy agent sam próbował ją przekroczyć, czy podsunięto mu do tego ukryte polecenie. Taka pułapka to tzw. wstrzyknięcie poleceń (ang. prompt injection): złośliwa instrukcja schowana w pliku albo na stronie, którą agent czyta i bierze za polecenie do wykonania.
W skrócie: uprawnienia mówią „tego narzędzia nie wolno użyć". Piaskownica mówi „nawet jeśli użyjesz, i tak nie zapiszesz poza projektem ani nie połączysz się z tą domeną". Pierwsze to zamek w drzwiach, drugie to mur wokół działki. Najlepiej działają razem.
Konfigurację piaskownicy w bieżącej sesji otwierasz komendą /sandbox. To nie polecenie, które coś uruchamia, tylko panel ustawień z zakładkami. Najważniejsza z nich, Mode, decyduje o całej logice:
/sandbox (Claude Code 2.1.168): trzy tryby pracy, od pełnej autonomii w piaskownicy (auto-allow) po całkowicie wyłączoną piaskownicę (No Sandbox)Do wyboru są trzy tryby, a różnica między nimi sprowadza się do tego, co dzieje się z pytaniami o zgodę:
W trybie auto-allow obowiązuje jeszcze jedna, ważna zasada, widoczna wprost w opisie na panelu: reguły ask i deny są zawsze respektowane. Innymi słowy piaskownica nie znosi Twoich twardych blokad. Jeśli w settings.json oznaczysz git push jako wymagający pytania, Claude i tak zapyta, nawet gdy komenda mieści się w granicach piaskownicy. Piaskownica dodaje kolejną warstwę, nie usuwa poprzednich.
Pozostałe zakładki panelu to Overrides (tu decydujesz między innymi, czy komenda, która nie zmieściła się w piaskownicy, może spróbować uruchomić się poza nią, parametr allowUnsandboxedCommands) oraz Config (podgląd reguł, które faktycznie obowiązują). Zmiany z panelu dotyczą bieżącej sesji; trwałą konfigurację zapisujesz w settings.json, do czego wrócimy w sekcji 6.
Piaskownica Claude Code nie jest kontenerem ani maszyną wirtualną. Wykorzystuje natywne mechanizmy izolacji wbudowane w system operacyjny, dzięki czemu narzut jest minimalny, a startuje natychmiast. Na Linuksie jest to bubblewrap, czyli lekkie narzędzie systemowe, które zamyka proces w ograniczonym widoku dysku i sieci; na macOS to wbudowany Seatbelt. Granica ma dwie warstwy:
bubblewrap, a ruch sieciowy przechodzi wyłącznie przez pośrednika (proxy), który sprawdza listę dozwolonych stronSystem plików. Odczyt jest domyślnie szeroki: agent widzi repozytorium i większość systemu. Zapis jest za to wąski i tu pada najczęstsze pytanie: którego katalogu to właściwie dotyczy? Domyślnie agent może zapisywać tylko w katalogu, w którym uruchomiłeś Claude Code (to bieżący katalog roboczy, ten, który pokazuje pwd w chwili startu, zwykle korzeń Twojego projektu) wraz ze wszystkimi jego podkatalogami, plus w katalogu tymczasowym sesji. Cała reszta dysku, czyli Twój katalog domowy, /etc czy inne projekty leżące obok, jest zamontowana tylko do odczytu, więc każda próba zapisu tam kończy się błędem „Read-only file system".
Te granice nie są sztywne: poszerzasz je wpisami w pliku konfiguracyjnym. Chcesz pozwolić agentowi na zapis w innym katalogu? Dopisujesz jego ścieżkę do listy allowWrite. Chcesz ukryć przed nim konkretny plik z sekretem, mimo że leży w projekcie? Wpisujesz go do listy denyRead. Obie listy siedzą w bloku filesystem i wyglądają tak:
"filesystem": {
"allowWrite": [".", "/tmp/build"], // zapis: katalog projektu (kropka) plus dodatkowy /tmp/build
"denyRead": ["~/.ssh", ".env"] // tych ścieżek agent nawet nie odczyta
}
I tu odpowiedź na drugie pytanie: gdzie leży ten plik? Zależy, którego narzędzia używasz. Dla komendy /sandbox to settings.json Claude Code (projektowy .claude/settings.json albo globalny ~/.claude/settings.json), a blok filesystem wkładasz do sekcji sandbox: pełny plik pokazujemy w sekcji 6. Dla narzędzia srt to jego własny plik ustawień, który podajesz flagą -s: pełny przykład znajdziesz w sekcji 4.
Sieć. Tu podejście jest jeszcze ostrzejsze. Proces zamknięty w piaskownicy nie ma jak samodzielnie wyjść do internetu: cały jego ruch musi przejść przez pośrednika (proxy) uruchomionego poza piaskownicą. Ten pośrednik sprawdza każde połączenie wobec listy dozwolonych stron. Co jest na liście, przechodzi; cała reszta dostaje odmowę. W praktyce połączenie z niedozwolonym adresem kończy się odpowiedzią 403, zanim jakikolwiek pakiet opuści komputer.
Silnik piaskownicy został wydzielony z Claude Code i udostępniony jako otwartoźródłowy pakiet @anthropic-ai/sandbox-runtime. Instalujesz go globalnie z npm, a dostajesz polecenie srt (od Sandbox Runtime), które opakowuje w tę samą izolację dowolny proces: nie tylko komendy Claude Code, ale też lokalne serwery MCP czy własne skrypty. To ta sama technologia, tylko dostępna samodzielnie.
# instalacja narzędzia srt
npm install -g @anthropic-ai/sandbox-runtime
# na Linuksie potrzebne są jeszcze bubblewrap i socat
sudo apt-get install bubblewrap socat
# uruchamiasz dowolną komendę wewnątrz piaskownicy
srt -c 'curl -sS https://example.com'
Narzędzie jest bezpieczne domyślnie: proces startuje z minimalnym dostępem, a Ty świadomie otwierasz tylko te furtki, których faktycznie potrzebujesz. Zobaczmy to na żywej maszynie. Bez żadnej konfiguracji zapis i sieć są od razu zamknięte:
srt odcina zapis (system plików tylko do odczytu) i całą sieć (proxy zwraca 403). Nic nie przecieka bez Twojej zgodyReguły dopisujesz w pliku ustawień. Podajesz go flagą -s; struktura jest prosta: osobno sieć, osobno system plików. Poniżej realny plik, którego użyliśmy do testu: pozwala na zapis w katalogu roboczym (kropka . oznacza katalog, w którym uruchamiasz srt) i na ruch tylko do example.com, a przy okazji chroni sekret regułą denyRead:
// settings.json dla srt - otwieramy tylko to, co konieczne
{
"network": {
"allowedDomains": ["example.com"],
"deniedDomains": []
},
"filesystem": {
"allowRead": ["."],
"denyRead": ["~/.ssh", ".env"],
"allowWrite": ["."],
"denyWrite": [".env", ".git"]
}
}
Z tak wskazanymi furtkami widać dokładnie, na czym polega model „domyślnie zamknięte, świadomie otwarte". Zapis w katalogu projektu przechodzi, domena z listy odpowiada 200, ale domena spoza listy nadal dostaje 403, a odczyt .env jest zablokowany, mimo że cały katalog był dozwolony do odczytu, bo reguła denyRead jest nadrzędna:
example.com działają, ale inna domena dalej dostaje 403, a sekret .env pozostaje niedostępnyTen sam mechanizm świetnie nadaje się do izolowania serwerów MCP. Serwer MCP to zwykły proces, który agent uruchamia z szerokimi uprawnieniami. Opakowanie go w srt pozwala z góry odebrać mu dostęp do plików i stron, których nie powinien tknąć, niezależnie od tego, co robi jego kod.
Uwaga: @anthropic-ai/sandbox-runtime to wersja rozwojowa (research preview). Format konfiguracji może się jeszcze zmieniać, a proxy domyślnie decyduje na podstawie samej nazwy domeny, bez zaglądania w ruch szyfrowany; o konsekwencjach piszemy w sekcji o ograniczeniach. Traktuj narzędzie jako mocną warstwę ograniczającą skutki wpadki, a nie jako nieprzekraczalną barierę do pracy z kodem, któremu zupełnie nie ufasz.
Najłatwiej zrozumieć wartość piaskownicy, zestawiając trzy sposoby na to, jak daleko puścić agenta samodzielnie:
Flaga --dangerously-skip-permissions zdejmuje pytania, ale nie dokłada żadnej granicy: agent dostaje pełną swobodę na całym systemie, więc sensownie odpalać ją tylko w izolowanym środowisku (kontenerze albo maszynie wirtualnej). Piaskownica robi rzecz odwrotną: dokłada granicę, dzięki czemu możesz zrezygnować z pytań i jednocześnie zachować twardy limit tego, co agent w ogóle jest w stanie zrobić. Dlatego jako codzienny sposób na „mniej pytań" tryb auto-allow z /sandbox jest po prostu bezpieczniejszym wyborem.
To nie znaczy, że flaga bypass i tryby uprawnień przestają być potrzebne. Mają swoje miejsce, głównie w pełni izolowanych przebiegach i w pipeline'ach CI. Kiedy sięgnąć po co i jak bezpiecznie użyć samej flagi bypass, rozłożyliśmy na czynniki pierwsze w artykule claude --dangerously-skip-permissions - jak wyłączyć pytania i nie narobić szkód, a pełną mapę trybów i przełączanie ich w locie klawiszem Shift+Tab w artykule Tryby uprawnień w Claude Code - Shift+Tab i auto-accept.
Ustawienia z panelu /sandbox dotyczą bieżącej sesji. Żeby piaskownica działała zawsze i według Twoich reguł, opisujesz ją w settings.json: projektowo (.claude/settings.json w repozytorium) albo globalnie (~/.claude/settings.json). Konfiguracja siedzi w bloku sandbox:
// .claude/settings.json - piaskownica z regułami dla projektu
{
"sandbox": {
"enabled": true,
"autoAllowBashIfSandboxed": true,
"network": {
"allowedDomains": ["github.com", "registry.npmjs.org"]
},
"filesystem": {
"allowWrite": ["/tmp/build"],
"denyRead": ["~/.ssh", ".env"]
},
"allowUnsandboxedCommands": true,
"excludedCommands": ["docker"]
}
}
Znaczenie kluczy jest wprost praktyczne. enabled włącza piaskownicę, autoAllowBashIfSandboxed odpowiada trybowi auto-allow z panelu (komendy w piaskownicy bez pytań). W network.allowedDomains wpisujesz domeny, które mają przechodzić bez pytania, a w filesystem poszerzasz zapis (allowWrite) i wycinasz wrażliwe ścieżki z odczytu (denyRead). allowUnsandboxedCommands decyduje, czy komenda, która nie zmieściła się w piaskownicy, może spróbować uruchomić się poza nią (przez zwykłą ścieżkę uprawnień); ustawienie go na false daje piaskownicę bez furtki awaryjnej. excludedCommands to lista poleceń, które celowo omijają piaskownicę, bo się z nią nie zgrywają (piszemy o tym niżej). Pełny, aktualny wykaz kluczy znajdziesz w dokumentacji Claude Code.
Piaskownica jest mocna, ale nie jest magiczną tarczą. Zanim na niej polegniesz, warto znać jej granice.
| System | Mechanizm | Co trzeba zrobić |
|---|---|---|
| macOS | Seatbelt (wbudowany) | Nic, działa od razu |
| Linux | bubblewrap + socat | apt-get install bubblewrap socat |
| WSL2 | bubblewrap + socat | Jak na Linuksie (WSL1 nie wystarczy) |
| Windows (natywnie) | brak wsparcia | Uruchom Claude Code w WSL2 |
Domyślnie proxy podejmuje decyzję na podstawie samej nazwy domeny, bez rozszywania ruchu szyfrowanego. To wystarcza, by odciąć oczywiste wycieki, ale zbyt szeroka lista dozwolonych (na przykład cała domena współdzielona przez wielu użytkowników) może teoretycznie posłużyć do wyprowadzenia danych. Wniosek praktyczny: trzymaj listę dozwolonych domen możliwie wąską i dopisuj tylko to, czego zadanie faktycznie potrzebuje.
Część narzędzi nie lubi izolacji sieci albo systemu plików. Klasyczny przykład to docker (który sam zarządza własną izolacją) czy uruchamianie testów z obserwatorem plików. Takie polecenia dopisujesz do excludedCommands albo uruchamiasz w wariancie zgodnym z piaskownicą (na przykład testy bez trybu ciągłego obserwowania plików). To normalny element strojenia, nie usterka.
Uwaga na dostęp do gniazd i katalogów systemowych. Niektóre furtki tylko wyglądają na drobne, a otwierają całą granicę. Dostęp do gniazda Dockera (/var/run/docker.sock) oddaje kontrolę nad całym hostem, i to z konkretnego powodu: kto może pisać do tego gniazda, ten steruje demonem Dockera, a więc może kazać mu uruchomić kontener, który montuje cały dysk hosta i działa jako root. W efekcie proces z piaskownicy robi na maszynie dosłownie wszystko, mimo że sam siedzi w izolacji. Podobnie zapis do katalogu z $PATH albo do plików startowych powłoki (.bashrc, .zshrc) pozwala podłożyć polecenie, które wykona się później, już poza piaskownicą (przy następnym starcie powłoki albo wywołaniu komendy o tej nazwie). Reguła jest ta sama co przy sieci: otwieraj wąsko i tylko to, co konieczne.
Wbudowana komenda /sandbox ogranicza komendy Bash i ich procesy potomne. Nie obejmuje natomiast automatycznie hooków ani serwerów MCP. Jeśli chcesz izolować także je, sięgasz po @anthropic-ai/sandbox-runtime, który opakowuje cały proces. To dlatego oba narzędzia mają sens obok siebie: /sandbox do codziennej pracy w sesji, srt tam, gdzie granica ma objąć wszystko.
Piaskownica zmienia domyślną odpowiedź na pytanie „jak mniej klikać zgód". Do tej pory brzmiała ona „wyłącz pytania i miej nadzieję". Teraz brzmi „postaw granicę, a w jej środku pozwól agentowi działać swobodnie". Prosty plan wdrożenia wygląda tak:
bubblewrap i socat, na macOS nic. Komenda /sandbox potwierdzi, czy wszystko jest na miejscu.denyRead.srt. Tam, gdzie /sandbox nie sięga, cały proces opakujesz sandbox-runtime.Efekt jest dokładnie taki, jak na animacji na początku artykułu: agent pracuje pełną parą i bez pytań, a zapis do cudzych plików czy połączenie z obcą stroną blokuje sam system, zanim się wykonają. Tak właśnie buduje się autonomię agenta profesjonalnie: nie zaufaniem do modelu, lecz granicą wokół niego.
Piaskownica, permissions, auto mode, hooki, izolacja, MCP i systemy multi-agent na żywym kodzie podczas trzydniowego szkolenia. Prowadzi Łukasz Matuszewski, a szkolenie ma termin gwarantowany, więc odbędzie się niezależnie od liczby zgłoszeń.
Claude Code - od zera do zespołu agentów AI
Komentarze (0)
Brak komentarzy...