Homokozó és biztonság
Miért számít itt az elkülönítés
Szekció neve “Miért számít itt az elkülönítés”Az ügynök fájlokat olvas, shellparancsokat futtat és külső API-kat hív Ön helyett. A hiba, ami igazán számít, ritkán rosszindulat — az az ügynök, amely félreolvas egy útvonalat és átírja a munkakönyvtárát, vagy az, amely feltol egy ágat, amelyet még nem nézett át. A terméknek tehát nem arra a kérdésre kell válaszolnia, hogy „megbízható-e az ügynök”, hanem arra, hogy „mekkora a hatássugár, amikor téved”.
A Control Center ezt rétegekben válaszolja meg, és a rétegek szándékosan függetlenek. Ha az egyik hiányzik, a többi akkor is tart. Ez azért fontos, mert a legkülső réteg — az operációs rendszer homokozója — az egyetlen feltételes: azon múlik, hogy a hoszt nyújt-e háttérrendszert, Windowson pedig egyetlen hoszt sem tesz ilyet.
Mi korlátozza valójában az ügynököt
Szekció neve “Mi korlátozza valójában az ügynököt”Öt dolog köti meg az ügynökfutást minden hoszton, homokozóval vagy anélkül. Egyik sem kernelhatár; mindegyik valós. Ahol a hoszt háttérrendszert kínál, az operációs rendszer homokozója ezek fölött helyezkedik el, és az alábbi „Mit ad hozzá a homokozó, és hol áll meg” szakasz elmondja, ez mit változtat.
A saját copy-on-write worktree-je. Minden beszélgetés előkészíti a saját
checkoutját minden csatolt repóból, a beépített rift natívon keresztül
copy-on-write módon klónozva, nem bájtról bájtra másolva, így az elkülönítés
elég olcsó ahhoz, hogy az alapértelmezett legyen. A munkaterülethez hozzáadott
regisztrált repó nem az a könyvtár, amelyben az ügynök dolgozik — két
beszélgetés, amely ugyanazt a repót érinti, nem látja a másik módosításait, és
egyik sem az Ön checkoutját szerkeszti.
A szemcsézettséget érdemes pontosan megadni: a worktree beszélgetésenként
értendő, nem ügynökönként. Két ügynök ugyanabban a beszélgetésben külön
overlay-munkakönyvtárat kap, amelyek megosztják a beszélgetés repos/
könyvtárát — ez épp a lényeg, hiszen egy közös változtatáson dolgoznak —, a
privát ügynökkönyvtáraik viszont külön maradnak. A copy-on-write az egyetlen
háttérrendszer mindenhol, ahol a rift elérhető: az a fájlrendszer, amely nem
tud reflinket, vagy a repótól eltérő köteten lévő adatkönyvtár, megbukik az
előkészítésen ahelyett, hogy visszaesne. Windows a kivétel — ott nincs
copy-on-write háttérrendszer, így a git worktree a háttérrendszer, nem
csendes visszaesés.
Útvonal-elkülönítés a beépített harness fájleszközeiben. A harness read,
write, edit, apply_patch, search, find és search_files eszköze
minden útvonalat a futás munkakönyvtárához és a megosztott gyökerekhez képest
old fel — a beszélgetés repos/ könyvtárához, ahol a worktree-k élnek, valamint
a tér csatolmánykönyvtárához, amikor létezik —, és mindent elutasít, ami ezen
kívülre esik. Az abszolút útvonalakat csak akkor fogadja el, ha már eleve azon
belül voltak. A worktree-n belüli, kifelé mutató symlink szintén feloldásra
kerül, és elutasításra kerül. Ezért nem tud az ügynök a ~/.ssh könyvtárba
write-olni akkor sem, ha nincs képben homokozó.
A mód eszközfelülete. Egy beszélgetés
módja dönti el, mely eszközök jelennek meg
egyáltalán a futáshoz. A csak olvasható módokban (plan, review,
orchestrate) a módosító eszközök egyszerűen nincsenek benne a
nyilvántartásban, és ezen módok shellparancs-szabályzata minden módosító
parancsot eleve megtagad — git commit, git push, npm install, docker és
a többi —, ahelyett hogy rákérdezne. Egy jelen nem lévő eszköz nem hívható meg,
ami erősebb garancia, mint egy jelen lévő és kapuzott eszköz.
Az egységes műveleti korlátok. Minden módosító eszköz deklarálja, milyen
hatásosztályokat válthat ki, és a szabályzatmotor mindegyiket engedélyezésre,
kérésre vagy tiltásra oldja fel, mielőtt a hívás lefut. Egy csatlakoztatott
jóváhagyó nélküli prompt elutasításra oldódik fel — egy kérdés, amire senki
nem tud válaszolni, soha nem igen. A feloldási modellt lásd a
Korlátok oldalon.
Közvetített hitelesítő adatok és megtisztított környezet. A hitelesítő adatokat minden indításkor kiállítjuk, és a futás végén visszavonjuk; a futás GitHub-tokenje olvasni tud, pusholni nem — lásd alább „A pushok a Control Centeren mennek át” részt. Az ACP, a harness bash és a natív becsomagolás alatti
Claude Code a folyamat indulása előtt olyan környezetet kap, amelyből
eltávolították a dinamikus linker és az interpreter injektálási vektorait
(LD_PRELOAD, DYLD_INSERT_LIBRARIES, NODE_OPTIONS, GIT_SSH_COMMAND és
társaik). A Claude Code a NoSandboxAdapter-en keresztül a hoszt környezetét
örökli.
Ahol ezek a határok elvékonyodnak
Szekció neve “Ahol ezek a határok elvékonyodnak”A harness fájleszközei a szerverfolyamatban futnak, nem gyermekfolyamatban,
így egyetlen homokozóprofil sem tudná korlátozni őket, még ha csatolnánk is
ilyet — csak a bash megy át a homokozott parancsfuttatón. Az ő elkülönítésük a
fent leírt útvonal-ellenőrzés, ezért ez az ellenőrzés teherviselő, nem csupán egy
második védelmi vonal.
A bash eszköz a másik hely, ahol pontosan kell fogalmazni. Parancsai a mód
parancsszabályzata alapján értékelődnek ki, majd megtisztított környezettel és a
worktree-t munkakönyvtárként használva indulnak el. Ahol létezik háttérrendszer,
az az indítás be van csomagolva, így a homokozó az, ami megakadályozza, hogy egy
shellparancs a worktree-n kívülre írjon; ahol nincs — Windows, vagy Linux
bwrap és socat nélkül —, a parancsszabályzat az egyetlen dolog a parancs és
a lemez többi része között. chat módban a szabályzat egy rögzített listát
tilt keményen (jogosultságnövelés, rendszer- és lemezrombolás, konténer- és
névtérkitörés), és rákérdez a távoli állapotot módosító műveletekre (git push,
gh pr create, csomagközzététel és -telepítés). Ami egyik listán sem szerepel,
az lefut. A pipeline-okat, a láncokat és az alshelleket elemezzük, és minden
alparancsot külön értékelünk ki, a legszigorúbb döntés győz.
A Claude Code adapterként az a hely, ahol a homokozón van a legnagyobb súly. A
Control Center --dangerously-skip-permissions kapcsolóval indítja, mert egy nem
interaktív claude -p egyébként örökre blokkolna a saját jóváhagyási kérésénél.
Olvasási, írási és szerkesztési hívásai a saját folyamatában történnek, és a Control Center soha nem látja őket. A Bash hívásai futás előtt egy szerveroldali hookhoz kerülnek, amely besorolja a parancssort és megkérdezi a megfelelő szabályt, a Control Center által kiszolgált mcp__* eszközök pedig a szokásos módon haladnak át a kapun. Ahol létezik
háttérrendszer, azok a láthatatlan hívások is a homokozóba csomagolva mennek
végbe, így az operációs rendszer a körülöttük lévő határ. Ahol nincs, ott semmi.
Minden adapter elmondja ezt a saját érvényesítési mátrixában — lásd
az adapterek őszinteségi mátrixát.
A pushok a Control Centeren mennek át
Szekció neve “A pushok a Control Centeren mennek át”Nincsenek ügynökönkénti jogosultságjelzők. Hogy egy ügynök létrehozhat-e commitot, pusholhat-e, nyithat-e pull requestet, írhat-e követőbe vagy elérheti-e a hálózatot, azt a korlátok döntik el — engedélyezés, előbb kérdezzen vagy tiltás —, és ugyanazok a szabályok érvényesek, bármelyik adapter futtatja is az ügynököt.
A push az a művelet, amelynek akkor is tartania kell, ha az ügynök megpróbál
megkerülni egy szabályt, ezért azzal érvényesítjük, ami az ügynök birtokában
van, nem azzal, amit futtat. Beállított GitHub App esetén egy GitHub-worktree-ben
zajló futás repóra korlátozott telepítési tokent kap, amely tartalmat olvashat és
pull requestekkel dolgozhat, de pusholni nem tud. A futás git-konfigurációja
minden GitHub-push URL-t (https://github.com/, git@github.com:,
ssh://git@github.com/) átír az ügynökfuttatási átjáróra, egy loopback
végpontra a cc_server-en. Az átjáró kiolvassa, mely refeket frissíti a push,
megkérdezi a Küldés távoli tárolóra szabályt — így egy ágakra korlátozott
szabály, például „a main-re irányuló push tiltása”, is érvényesül —, és csak
ezután továbbítja a pusht a GitHubra egy írási tokennel, amelyet erre a célra
állít ki, és soha nem ad át az ügynöknek. Az elutasított push a git saját
kimenetében jelenik meg:
! [remote rejected] main -> main (Control Center policy: …)Az átjáró csak a worktree saját repójába vagy a munkaterülethez kapcsolt GitHub-repóba továbbít pusht. A fetch az olvasási tokennel közvetlenül a GitHubra megy.
A többi shellparancs lazább kapuba ütközik. A harness bash eszköze és – egy
hookon keresztül – a Claude Code Bash eszköze minden parancssort besorol, és
megkérdezi azt a szabályt, amely alá tartozik: a git commit, merge,
rebase, cherry-pick, revert és am a Commit létrehozása; a
gh pr create a Pull request megnyitása; a gh pr merge, review,
comment és close az Átnézés vagy összefésülés közzététele; a
gh issue create, edit, comment és close az Írás külső követőbe; a
csomagtelepítések a Csomag telepítése; a curl és a wget a Hálózati
hozzáférés. Ez a művelet szokásos leírását ismeri fel, és egy ügynök, amely
el akarja rejteni (eval, szkriptfájl, közvetlen API-hívás), képes rá. A
pushok nem függenek tőle.
A homokozóba nem kerül jegykezelő API-kulcs. Az ügynökök a Control Center MCP eszközein keresztül írnak jegyeket, amelyek az Írás külső követőbe szabályt kérdezik meg.
A Hálózati hozzáférés szabályt egyszer olvassuk ki, a futás indulásakor. A
homokozó hálózata vagy be van kapcsolva, vagy ki, így a tiltás kikapcsolja, az
engedélyezés és az előbb kérdezzen pedig bekapcsolva hagyja; a harness
web_fetch és web_search eszköze továbbra is minden hívásnál kérdez. A
hitelesítő adatok a futás lebontásakor visszavonásra kerülnek, az átjáró által
kiállított írási tokenekkel együtt, így egy fogantyú nem éli túl a futást.
Mit ad hozzá a homokozó, és hol áll meg
Szekció neve “Mit ad hozzá a homokozó, és hol áll meg”A SandboxBackend enum három értéket vesz fel — native (macOS-en Seatbelt,
Linuxon és WSL2-n bubblewrap), none és microvm. Az ügynökparancsok
becsomagolása csak az első kettőt használja: a microvm az interaktív
terminálokhoz és állomásokhoz tartozó elszigetelt VM háttérrendszer, nem egy
bash-becsomagolás csendes felminősítése. A natív forma megértése
elmagyarázza, mit nyer ott, ahol csatolva van, és mit nem adott volna soha.
A cc_server indításkor egyszer felméri a hosztot, és ahol egy háttérrendszer
válaszol, az indítási útvonal mindkét illesztési pontját ellátja, mert az
átvitelek nem osztoznak egyen. Az első (SandboxPort) a Claude Code CLI-t
csomagolja. A második (SandboxManager) az ACP-adaptereket és a beépített
harness bash eszközét csomagolja. Csak az egyik ellátása a többieket
csomagolatlanul hagyná indulni, ami korábban meg is történt. Egy háttérrendszer
nélküli hoszton, vagy --sandbox off esetén, mind csomagolatlanul indul, és a
szerver az indítási sorában megmondja, melyik esetben van. Az ACP és a harness
bash továbbra is megtisztítja a környezetet; a Claude Code a
NoSandboxAdapter-en keresztül a hoszt környezetét örökli.
Egy felület szándékosan kimarad: a szerveren hosztolt terminál munkamenetenként
elfogad egy háttérrendszer-argumentumot, és a cc_server a hoszt shellre
alapértelmezve építi fel, így az alkalmazásból megnyitott terminál homokozó
nélkül fut, hacsak egy kliens kifejezetten meg nem nevezi a native-ot. Az egy
valódi shell a szerver hosztján, nem ügynökfutás.
Linuxon a bubblewrap mountnévtért épít, így az ügynök valóban csak azt látja,
amit belecsatoltak. macOS-en a sandbox-exec egy Seatbelt-profilt alkalmaz,
amely alapértelmezés szerint megengedő — egy teljesen tiltásra alapuló profil
használhatatlanná tenné az interaktív shellt, mert a felsorolandó dyld-, XPC- és
Mach-hívások száma kezelhetetlen. A macOS-profil ezért (allow default)-ból
indul, és tiltásokat vés ki: titkos útvonalak olvasása, írási szabályzat
visszaállítva tiltásra, felül pedig explicit engedélyek, unlink-blokkolás minden
tiltott útvonalon és annak ősein, hogy egy átnevezés ne kerülhesse meg az írási
tiltást, exec-tiltások a mindig veszélyes binárisokra és bármire, amit egy
írható könyvtárba másoltak, valamint a hálózat a loopback proxy portjaira és a
DNS-re korlátozva.
A gyakorlati következmény: Linuxon az ügynök fájlrendszer-képe szűkül; macOS-en az ügynök még mindig olvashatja a hoszt nagy részét, és a regisztrált checkoutjait nem a láthatatlanság védi, hanem explicit írási és átnevezési tiltások. Mindkettő névtérszintű elkülönítés, nem kernelbiztonsági határ — a háttérrendszerek ezt a saját képességjegyzeteikben maguk is elmondják.
A bind mount készlete az, ahol a keresztügynök-határ meghúzódik. Az overlay
indítás (Claude Code és ACP) legfeljebb négy útvonalat csatol be, futásonként
feloldva: az ügynök overlay-munkakönyvtárát írás-olvasásra, az ügynök
konfigurációs könyvtárát csak olvasásra, a beszélgetés megosztott repos/
könyvtárát írás-olvasásra, amikor létezik, valamint a tér csatolmánykönyvtárát
csak olvasásra, amikor létezik. Egy testvér-ügynök könyvtára soha nincs
becsatolva. A harness bash becsomagolása szűkebb: csak a futás munkakönyvtárát
csatolja be. Ez ugyanaz a forma, amelyet a harness folyamaton belüli
útvonal-ellenőrzése szoftveresen érvényesít, így a kettő egyezik — de csak az
útvonal-ellenőrzés fedi a harness saját fájleszközeit, amelyek soha nem érnek el
mountnévtérbe.
A regisztrált checkoutjai ezen felül csatlakoznak az írásmegtagadási halmazhoz,
minden módban és mindhárom becsomagolt úton (Claude Code, ACP, harness bash),
és minden szabály a szó szerinti és a symlink-feloldott alakjában is kiadásra
kerül. A második alak nem szépségápolás: a kernel a tiltási szabályt a feloldott
útvonallal veti össze, és a macOS a feloldást teszi gyakorivá, nem egzotikussá —
a /tmp valójában /private/tmp, a /var/folders/… valójában
/private/var/folders/… —, így egy rajtuk keresztül elért checkout írható lett
volna, miközben a profil látszólag tiltotta.
A hálózat homokozó alatt munkamenetenkénti domain-engedélylista, amelyet
folyamaton belüli loopback proxyk érvényesítenek. A kimenő forgalom
alapértelmezés szerint tiltott: kikapcsolt hálózattal a proxyk elindulnak, de az
engedélylistájuk üres, így minden kimenő kapcsolat elutasításra kerül.
Bekapcsolt hálózattal a feloldó egy gondozott alaplistából építi fel az
engedélylistát — LLM API-szolgáltatók, git-hoszting, csomagregiszterek, a
modellkatalógus —, plusz a GitHub domainjeiből, és minden kapcsolat célhosztját
ezzel veti össze. A helyettesítő karakterek működnek (*.example.com az
aldomainekre illeszkedik, nem a csúcstartományra). Egy külön, mindig tiltott
lista felülírja az engedélylistát, és felhő-metaadatvégpontokat és telemetriai
célpontokat fed le. Ami nem konfigurálható, az maga a lista: a specifikáció
hordoz egy egressAllowlist mezőt további domainekhez, de az indítási
útvonalban semmi nem tölti ki, így a gyakorlatban minden futás az alaplistát és
a GitHubot kapja, semmi többet.
A tiltások macOS-en megfigyelhetők: egy monitor a rendszernaplóból kiszúrja a
Sandbox-tiltásokat, kiszűri az ismert zajt, deduplikálja az újrapróbálkozási
viharokat, és mindegyiket SandboxViolation eseményként hozza felszínre,
megnevezve, mit kíséreltek meg és mi lett blokkolva. Linuxon a
becsomagolási út az stderr-ből elemzi ki az EPERM, Operation not permitted
és Permission denied szövegeket, és ugyanazt az eseménytípust bocsátja ki —
nincs rendszernapló-kiszúrás. Ezek a futás saját eseményfolyamán érkeznek, így
egy megtagadott rendszerhívás az átiratban is megjelenik, nem csak egy naplóban.
A telemetria csak addig létezik, amíg egy natív homokozó ténylegesen becsomagolja
a folyamatot — egy háttérrendszer nélküli hoszton nincs mit megfigyelni. A korlátokhoz sem kapcsolódik: egy sértés megtagadott rendszerhívásból származik, soha nem szabálykeresésből.
A megerősítések a korlátokból jönnek, nem a homokozóból
Szekció neve “A megerősítések a korlátokból jönnek, nem a homokozóból”A homokozónak nincs jóváhagyási útja. Elindul, végrehajt, eseményeket bocsát ki és lebomlik; nincs benne hely, ahol egy ember válaszolhatna egy kérdésre. Amikor egy megerősítést lát egy térben — hagyja jóvá ezt a push-t, hagyja jóvá ezt a törlést —, azt a korlátmotor (vagy a harness parancsszabályzata) emelte azelőtt, hogy a művelet egyáltalán elérte volna a futtatókörnyezetet.
Ez a sorrend szándékos. Egy jóváhagyás, amely a rendszerhívás után történt volna, auditbejegyzés lenne, nem kapu. Ezért is él a fail-closed szabály a korlátokban: csatlakoztatott jóváhagyó nélkül a döntés még az előtt megszületik, hogy bármi elindulna, és ez egy elutasítás.
Diagnosztika
Szekció neve “Diagnosztika”Az ügynök diagnosztizálása az egyetlen hely, amely elmondja, mi ellenőrizhető kézzel.
Kapcsolódó fogalmak
Szekció neve “Kapcsolódó fogalmak”- Állomások és elszigetelt környezetek: a homokozó feletti lépés — amikor a munkához egy egész eldobható gép kell kernelhatárral, nem egy becsomagolt folyamat
- Korlátok: az operációs rendszer alsó korlátja feletti szabályzatréteg, és hogy honnan jönnek valójában a jóváhagyások
- Ügynökindítás életciklusa: hová illeszkedik az elkülönítés az indítási folyamatba
- Módok: hogyan szűkíti egy mód az eszközfelületet és a parancsszabályzatot
- Homokozó-háttérrendszerek: a háttérrendszerek és konfigurációjuk
Kapcsolódó útmutatók
Szekció neve “Kapcsolódó útmutatók”- Homokozószabályzatok konfigurálása: műveleti szabályok, push-érvényesítés és fájlrendszer-beállítás
- Ügynök diagnosztizálása: mit fednek le a diagnosztikai ellenőrzések