Jednorazowa maszyna wirtualna dla agenta kodującego
Sprawdź, jak odizolować agenta kodującego: root, czysty stan dla każdego zadania, snapshoty i tani VPS ograniczają skutki błędów do maszyny odtwarzanej w 10 minut.
Dlaczego jednorazowa maszyna wirtualna jest lepsza niż laptop
Udostępnienie agentowi programistycznemu jednorazowej maszyny wirtualnej oznacza, że najgorszym skutkiem jego działania może być zniszczenie maszyny, którą można odtworzyć w ciągu dziesięciu minut. Agent nadal otrzymuje uprawnienia root, nadal instaluje pakiety i nadal uruchamia zestaw testów bez żądania zgody na każdy krok. Różnica polega na tym, gdzie wystąpią szkody. Na laptopie agent ma dostęp do katalogu domowego zawierającego klucze SSH, profil przeglądarki, pliki .env oraz każde inne repozytorium, które kiedykolwiek sklonowano. Na tymczasowym serwerze ma powłokę, kopię repozytorium i nic więcej, co warto przejąć.
To jest cała argumentacja. Dotyczy ona asymetrii, a nie prawdopodobieństwa. Ostrożny agent na ostrożnie używanym laptopie niemal zawsze działa poprawnie. Jeśli jednak raz tak nie będzie, kosztem nie jest nieudany commit. Jest nim odtworzenie systemu z kopii zapasowej, o ile taka kopia istnieje.
Określ zakres szkód, zanim zaczniesz się o nim spierać
Zakres szkód oznacza zbiór zasobów, do których proces może uzyskać dostęp. W przypadku agenta uruchomionego jako zwykły użytkownik na zwykłym komputerze zbiór ten jest większy, niż większość osób zakłada.
Obejmuje on ~/.ssh/id_ed25519, które zwykle jest niezaszyfrowane, ponieważ wpisywanie hasła stało się uciążliwe. Obejmuje ~/.aws/credentials i ~/.config/gh/hosts.yml, które z założenia zawierają zwykły tekst. Obejmuje każde repozytorium równorzędne w ~/code, w tym repozytoria zawierające ciągi połączeń produkcyjnych w lokalnym pliku env. Obejmuje także historię powłoki, w której znajdują się tokeny wklejone wcześniej. Obejmuje również sieć, do której podłączony jest laptop. Często jest to sieć domowa lub biurowa z nieuwierzytelnionymi usługami.
Nie wymaga to złośliwego agenta. Wystarczy jedna polecenie wykonane z błędnym przekonaniem o jej poprawności. rm -rf z nieustawioną zmienną rozwijającą się do /, git clean -xfd wykonane w niewłaściwym katalogu, docker system prune -af --volumes, które usuwa lokalną bazę danych, lub pomocne chmod -R 777 wykonane w katalogu domowym. Agenty są trenowane na tym samym Internecie, który nauczył tych poleceń wszystkich pozostałych.
Mechanizmem zapewniającym bezpieczeństwo nie jest ocena agenta. Jest nim fakt, że komputer, na którym mogą powstać szkody, to komputer, którego utratę można było zaakceptować.
Koszt jest łatwy do obliczenia, co ma znaczenie
Mały VPS kosztuje kilka dolarów miesięcznie. Odtworzenie środowiska na laptopie deweloperskim zajmuje dzień. To korzystny wariant, w którym problem zostaje szybko wykryty i istnieje kopia zapasowa.
Wykonaj obliczenia dla własnych danych. Pomnóż stawkę godzinową przez liczbę godzin potrzebnych na ponowną instalację systemu operacyjnego, odtworzenie katalogu domowego, rotację klucza SSH, rotację osobistego tokenu dostępu i ponowne sklonowanie dwudziestu repozytoriów. Następnie porównaj wynik z kosztem dwunastu miesięcy korzystania z najmniejszego serwera oferowanego przez dostawcę. Próg rentowności przypada na mniej niż jeden incydent na kilka lat. Incydent nie musi być katastrofalny, aby przekroczyć ten próg. Jedno popołudnie stracone z powodu uszkodzonego środowiska lokalnego już pokrywa koszt całego roku.
Druga część obliczeń dotyczy migawek. Migawka wykonana przed ryzykownym uruchomieniem zmienia niekorzystny wynik z „odtworzyć całe środowisko” na „wycofać zmiany i użyć innego promptu”. Ta możliwość nie istnieje na używanym laptopie, ponieważ nie można wykonywać migawek komputera w trakcie używania go jako stanowiska pracy.
Środowisko w lipcu 2026
Istnieją trzy uzasadnione odpowiedzi na pytanie „gdzie powinien działać agent”. Każda z nich inaczej równoważy te same dwie kwestie: siłę izolacji oraz akceptowany nakład konfiguracji.
Lokalna mikromaszyna wirtualna. Narzędzia z tej kategorii uruchamiają prawdziwą maszynę wirtualną na własnym sprzęcie, montują w niej repozytorium i umożliwiają agentowi pracę z uprawnieniami root. clawk jest obecnym przykładem. Jego główne założenie jest dokładnie takie, jak teza tego wpisu: należy udostępnić agentom programistycznym jednorazową maszynę wirtualną z systemem Linux, a nie laptop. W lipcu 2026 obsługiwane są systemy macOS 14 i nowsze na komputerach z układami Apple silicon. Eksperymentalna obsługa systemu Linux jest realizowana za pomocą Firecracker. Instalacja odbywa się za pomocą brew install clawkwork/tap/clawk. Polecenie clawk uruchamia piaskownicę i dołącza agenta w repozytorium, clawk down ją zatrzymuje, a clawk destroy usuwa. Izolację zapewnia hipernadzorca, więc jest ona silna. Ograniczenie polega na tym, że maszyna wirtualna działa na używanym komputerze. Zużywa jego pamięć i zatrzymuje się po zamknięciu pokrywy.
Kontener. Docker jest rozwiązaniem, które większość osób ma już zainstalowane, i rzeczywiście jest użyteczny.
docker run --rm -it -v "$PWD:/work" -w /work --network none ubuntu:24.04 bash--rm usuwa kontener po zakończeniu działania, a --network none całkowicie odcina mu dostęp do sieci. Jest to dobry domyślny wybór podczas kompilacji lub uruchamiania testów. Należy jasno określić, czego to rozwiązanie nie zapewnia: kontener współdzieli jądro hosta, więc błąd jądra może umożliwić ucieczkę z izolacji. Izolacja znika również po dodaniu --privileged lub zamontowaniu /var/run/docker.sock, aby agent mógł „używać Docker”. Zamontowanie gniazda Docker w kontenerze jest równoznaczne z przyznaniem temu kontenerowi uprawnień root na hoście.
Zwykły VPS, który można odtworzyć. Nie jest potrzebne nowe narzędzie. Dostępna jest rzeczywista izolacja zapewniana przez jądro, migawki u dostawcy, a system działa nadal po wyłączeniu laptopa. Jest to wzorzec opisany w dalszej części tego poradnika. Sprawdza się on podczas długotrwałego działania agentów, ponieważ zadanie trwające cztery godziny nie zależy od tego, czy użytkownik wrócił do domu.
Wzorzec VPS: przydziel agentowi własne konto użytkownika
Rozpocznij od zabezpieczonego serwera. Pierwsze dziesięć minut na nowym VPS obejmuje elementy, które nie zależą od agenta: aktualizacje, logowanie bez konta root, SSH wyłącznie z użyciem klucza oraz zaporę sieciową.
Następnie utwórz konto używane wyłącznie przez agenta. Dzięki temu błąd popełniony w ramach tego konta nie wpłynie na pozostałe elementy serwera.
sudo adduser --disabled-password --gecos "" agent
sudo install -d -m 700 -o agent -g agent /home/agent/work
sudo -u agent -H bash -lc 'id; ls -la ~'--disabled-password oznacza, że nie ma hasła, które można odgadnąć, a dostęp do konta uzyskuje się za pomocą sudo -u agent lub klucza SSH. Należy pamiętać, że agent celowo nie należy do grupy sudo. Agent z uprawnieniem sudo ma uprawnienia root, a root może odczytać pliki wszystkich pozostałych użytkowników, więc utworzona izolacja jest tylko pozorna. Jeśli agent rzeczywiście musi instalować pakiety, jest to argument za przydzieleniem mu całego serwera, a nie za nadaniem mu sudo na współdzielonym serwerze. Ogólne zasady opisano w zasadzie najmniejszych uprawnień dla użytkowników Linux na VPS.
Przed zaufaniem agentowi sprawdź granicę izolacji. Jako użytkownik agent spróbuj odczytać plik należący do własnego konta:
sudo -u agent cat /home/you/.ssh/id_ed25519Powinien zostać wyświetlony komunikat cat: /home/you/.ssh/id_ed25519: Permission denied. Jeśli zamiast tego widoczne są materiały kluczowe, katalog domowy ma uprawnienia 755, a izolacja nie działa jeszcze prawidłowo. Napraw to za pomocą sudo chmod 700 /home/you.
Nie przechowuj poświadczeń na maszynie
Cel używania jednorazowej maszyny zostaje przekreślony, jeśli zostaną na nią skopiowane sekrety produkcyjne. Zasada jest prosta: na tej maszynie nie powinno znajdować się żadne poświadczenie, którego rotacja jeszcze tego popołudnia byłaby problemem.
W przypadku git należy przekazywać SSH agent zamiast kopiować klucz. Klucz prywatny pozostaje na laptopie, a przez połączenie są przesyłane tylko żądania podpisu.
ssh -A agent@203.0.113.10
ssh -T git@github.comDrugie polecenie powinno zwrócić odpowiedź Hi yourname! You've successfully authenticated, but GitHub does not provide shell access.. Potwierdza to, że git push będzie działać bez obecności pliku klucza na serwerze. Następnie należy uruchomić na tej maszynie ls -la ~/.ssh i potwierdzić, że nie ma na niej klucza prywatnego.
Przekazywanie agenta ma jedno istotne ograniczenie, które należy jasno określić: podczas aktywnego połączenia każda osoba mająca uprawnienia root na tym serwerze może użyć przekazanego gniazda do uwierzytelnienia się jako użytkownik. Na serwerze, którego jedynym innym użytkownikiem jest użytkownik wykonujący połączenie, jest to akceptowalny kompromis. Na współdzielonej maszynie nie jest to bezpieczne rozwiązanie. Lepszym wyborem jest klucz wdrożeniowy ograniczony do jednego repozytorium. Dostępne opcje opisano w Podstawy zarządzania kluczami SSH.
W przypadku kluczy API należy przydzielić agentowi osobny klucz z osobnym limitem wydatków i przechowywać go w pliku należącym do użytkownika agent, z trybem 600. Po zniszczeniu maszyny należy unieważnić ten klucz, zamiast zastanawiać się, czy wyciekł. Widoczność wydatków na modele dla poszczególnych kluczy pozwala również utrzymać przewidywalność wartości opisanych w Kontrola kosztów agenta AI na VPS.
Ograniczenie dostępu agenta do sieci
Izolacja systemu plików wyznacza tylko połowę granicy. Drugą połowę stanowi ruch wychodzący: określa on, z czym proces może się komunikować. Linux umożliwia filtrowanie ruchu wychodzącego według użytkownika, który go utworzył. Dokładnie odpowiada to temu modelowi.
sudo iptables -A OUTPUT -m owner --uid-owner agent -o lo -j ACCEPT
sudo iptables -A OUTPUT -m owner --uid-owner agent -p udp --dport 53 -j ACCEPT
sudo iptables -A OUTPUT -m owner --uid-owner agent -p tcp --dport 443 -j ACCEPT
sudo iptables -A OUTPUT -m owner --uid-owner agent -j REJECTReguły są odczytywane w kolejności, dlatego końcowa reguła REJECT przechwytuje wszystko, na co nie zezwolono we wcześniejszych wierszach. Należy przetestować ją jako agent:
sudo -u agent curl -sS -m 5 http://example.comPołączenie powinno zakończyć się błędem curl: (7) Failed to connect to example.com port 80: Connection refused, ponieważ reguła odrzucająca odpowiada natychmiast, zamiast pozostawiać połączenie zawieszone. Żądanie HTTPS do tego samego hosta powinno nadal działać.
Należy uwzględnić dwa ograniczenia. Po pierwsze, reguły zostaną utracone po ponownym uruchomieniu systemu, chyba że zostaną zapisane za pomocą sudo apt install -y iptables-persistent, a następnie sudo netfilter-persistent save. Po drugie, filtrowane są porty i adresy, a nie nazwy. Reguła zezwalająca na port 443 umożliwia połączenie z każdym hostem HTTPS w internecie. Wystarcza to do uzyskania dostępu do API modelu, ale również do uzyskania dostępu do serwera pastebin. Rzeczywista lista dozwolonych domen wymaga przepuszczania ruchu przez serwer proxy, który odczytuje żądaną nazwę hosta. Jest to bardziej złożone rozwiązanie, niż zwykle potrzebują konfiguracje pojedynczego dewelopera. Należy deklarować tylko to, co faktycznie zapewniono: kontrolę ruchu wychodzącego na poziomie portów na komputerze, którego utrata była akceptowalna.
Przywracanie czystego stanu między zadaniami
Czysty stan dla każdego zadania to często niedoceniana korzyść. Agent, który spędził trzy godziny nad poprzednim zgłoszeniem, pozostawił zainstalowane pakiety, częściowo zastosowane migracje, nieaktualny node_modules oraz katalog roboczy git ze zmianami, których nikt nie sprawdził. Następne zadanie dziedziczy cały ten stan, a czas przeznaczony na przegląd trzeba poświęcić na ustalenie, który bałagan należy do którego uruchomienia.
Najprostsza wersja polega na utworzeniu świeżego checkoutu dla każdego zadania.
sudo -u agent -H bash -lc 'rm -rf ~/work/repo && git clone git@github.com:you/repo.git ~/work/repo'Solidniejsza wersja to utworzenie migawki u dostawcy jednorazowo, zaraz po skonfigurowaniu maszyny i przed wykonaniem jakichkolwiek działań przez agenta. Przywrócenie tej migawki przywraca cały system, włącznie z pakietami, do znanego stanu. Większość dostawców udostępnia tę funkcję w panelu sterowania lub za pośrednictwem API, a nie jako polecenie wykonywane na maszynie, dlatego dokładne kroki zależą od dostawcy. Należy utworzyć migawkę, gdy maszyna jest jeszcze w stanie początkowym.
Wszystko, na czym zależy, należy przechowywać poza maszyną tymczasową. Zwykle oznacza to wypychanie gałęzi zamiast przechowywania ich wyłącznie lokalnie. Jeśli na maszynie znajdzie się coś, czego utrata byłaby problemem, należy wykonać prawidłową kopię zapasową za pomocą kopii zapasowych restic na VPS. Maszyna, którą można zniszczyć, jest użyteczna tylko wtedy, gdy jej zniszczenie rzeczywiście nie powoduje problemów.
Aby uzyskać kilka izolowanych środowisk bez opłacania kilku serwerów, można hostować bezpośrednio zagnieżdżone maszyny wirtualne na jednym większym VPS. Sekcja Wirtualizacja zagnieżdżona na VPS wyjaśnia sposób działania tego rozwiązania, w tym sposób sprawdzenia, czy dostawca na to zezwala.
Kiedy laptop jest rzeczywiście wystarczający
Należy zachować obiektywizm, ponieważ przesadne przedstawianie izolacji powoduje utratę zaufania.
Jeśli każda komenda jest sprawdzana przed wykonaniem, laptop jest wystarczający. Monit o uprawnienia stanowi rzeczywisty mechanizm kontroli, a bezpieczne uruchamianie Claude Code na serwerze wyjaśnia, co dokładnie blokuje każdy z jego poziomów. Jeśli praca obejmuje jedno repozytorium i na komputerze nie ma żadnych poświadczeń produkcyjnych, potencjalny zakres skutków jest już niewielki. Jeśli sesje agenta są krótkie i nadzorowane, krótki jest również czas ekspozycji.
Sytuacja zmienia się natychmiast po pominięciu monitów. Uruchomienia bez nadzoru, zadania wykonywane w nocy oraz każdy przepływ pracy, w którym zatwierdza się plan i odchodzi od komputera, eliminują kontrolę człowieka zapewniającą ograniczenie skutków. Wtedy to komputer musi zapewnić tę kontrolę. To samo dotyczy wszystkiego, co poszerza zasięg działania agenta, w tym uruchamiania agenta programistycznego na VPS jednocześnie w kilku repozytoriach.
Decyzja nie dotyczy w rzeczywistości stopnia zaufania do modelu. Chodzi o to, co znajduje się obok niego, gdy model się pomyli.
FAQ
Czy kontener zapewnia wystarczającą izolację dla agenta programistycznego?
W przypadku większości zadań tak, pod dwoma warunkami. Kontener nie może działać z użyciem --privileged ani mieć zamontowanego w nim /var/run/docker.sock, ponieważ każdy z tych elementów zapewnia procesowi ścieżkę do konta root na hoście. Kontener współdzieli jądro hosta, dlatego granica izolacji jest słabsza niż w przypadku maszyny wirtualnej. Jeśli agent uruchamia niezaufany kod pobrany z Internetu, należy użyć rzeczywistej maszyny wirtualnej lub oddzielnego serwera.
Czy agent potrzebuje sudo na serwerze?
Nie. Nadanie mu sudo unieważnia utworzoną izolację, ponieważ root może odczytać dane każdego innego konta na serwerze. Należy utworzyć użytkownika agenta bez sudo i przyznać mu prawo zapisu wyłącznie do jego własnego katalogu roboczego. Jeśli zadanie rzeczywiście wymaga instalowania pakietów, należy przydzielić agentowi całą maszynę, której jest właścicielem, zamiast przyznawać mu root na współdzielonej maszynie.
Jak umożliwić agentowi wysyłanie zmian do git bez umieszczania mojego klucza SSH na serwerze?
Podczas nawiązywania połączenia należy przekazywać agenta SSH za pomocą ssh -A. Żądania podpisu są przesyłane przez połączenie, a klucz prywatny pozostaje na laptopie, dlatego ssh -T git@github.com uwierzytelnia, a git push działa bez klucza prywatnego na serwerze. Należy jednak pamiętać, że root na tym serwerze może korzystać z przekazanego gniazda podczas aktywnego połączenia. Na każdej maszynie współdzielonej z innymi osobami należy więc używać klucza wdrożeniowego ograniczonego do repozytorium.
Jakiego rozmiaru VPS potrzebuje agent?
Praca agenta polega głównie na edytowaniu plików, wykonywaniu kompilacji i uruchamianiu testów. Rozmiar maszyny należy więc dobrać do procesu kompilacji, a nie do modelu. Hostowany model działa na sprzęcie dostawcy, co generuje ruch sieciowy i prawie nie obciąża lokalnej maszyny. Na potrzeby skryptów należy rozpocząć od 2 GB RAM. Jeśli repozytorium buduje kontenery lub kompiluje większe komponenty, należy zwiększyć zasoby do 8 GB.
Jak często należy niszczyć i ponownie tworzyć maszynę?
Maszynę należy ponownie utworzyć, gdy stan systemu przestaje być możliwy do wyjaśnienia, a co najmniej zawsze wtedy, gdy mogło dojść do ujawnienia danych uwierzytelniających na tej maszynie. Świeże pobranie repozytorium przed każdym zadaniem ogranicza codzienne rozbieżności stanu. Migawka wykonana przed pierwszym uruchomieniem agenta zapewnia czysty obraz systemu, do którego można powrócić. Jeśli ponowne tworzenie maszyny wydaje się kosztowne, oznacza to, że na maszynie określonej jako tymczasowa znajduje się coś istotnego.