Backendy sandboxu
Přehled backendů
Sekce “Přehled backendů”| Backend | Hodnota | Platforma | Dostupnost |
|---|---|---|---|
| Izolované VM | microvm |
macOS, Linux, Windows (hypervizor microVM) | Řízeno sondou runtime microVM; platí pro interaktivní terminály — shell běží uvnitř stanice, ne na hostiteli |
| Nativní | native |
macOS (Seatbelt), Linux a WSL2 (bubblewrap) | Sonda při startu; Linux odmítne běh, který vyžaduje zákazy zápisu podle globu názvu souboru, a ty bubblewrap vynutit neumí |
| Žádný | none |
Vše | Výchozí hodnota při parsování, výchozí stav terminálu a náhrada, když není backend k dispozici nebo je nastaveno --sandbox off |
SandboxBackend.fromName vrací none pro null nebo nerozpoznanou uloženou hodnotu. Uložené "docker" se mapuje na native.
microvm je jediný backend s hranicí jádra — zátěž
opravdu neběží na hostiteli. Tichá záloha to není ani jedním
směrem: výslovná žádost o něj na hostiteli, který VM nespustí, selže
nahlas („Požádal jsem o VM a dostal jsem svůj notebook“ je jediné zhoršení,
které si uzavřený stroj nemůže dovolit) a jen neuvedená výchozí hodnota sestoupí na
native, s řádkem v logu, který to řekne. Skutečný backend relace se hlásí
zpátky klientovi a dostane odznak, takže terminál se nikdy nemůže vydávat za uzavřený,
když běží na hostiteli. Životní cyklus, obrazy a odchozí provoz samotného VM
pokrývá reference stanic.
Windows nemá nativní sandbox. NativeSandboxAdapter.probe vrací available: false na každém hostiteli, který není macOS ani Linux/WSL2. Odeslání agenta na Windows proto používá none. Backend microvm je zvlášť: řídí ho sonda podle runtime microVM a platí pro interaktivní terminály a stanice, ne pro obalení bash na hostiteli.
Výsledky sondy
Sekce “Výsledky sondy”Vynucování pouští sonda. Běží jednou, při startu serveru.
| Hostitel | available |
Poznámka / nápověda |
|---|---|---|
| macOS | true |
sandbox-exec (Seatbelt) — izolace jmenného prostoru, bez hranice jádra |
Linux nebo WSL2 s bwrap a socat |
true |
bubblewrap — izolace jmenného prostoru, bez hranice jádra |
| Linux nebo WSL2, chybí jeden z nástrojů | false |
requiresInstall: true, s nápovědou k instalaci, která pojmenuje chybějící balíčky |
| Jakákoli jiná platforma | false |
Nativní sandbox se na téhle platformě nenabízí |
Server výsledek zapíše na jeden startovací řádek: agent sandbox ON a k tomu poznámka, no OS-native agent sandbox on this host a k tomu nápověda, nebo agent sandbox DISABLED by --sandbox off. GET /healthz pole sandboxu nenese.
--sandbox / CC_SERVER_SANDBOX bere on (výchozí) nebo off. Je to vypnutí, ne zapnutí: on znamená „obal, když hostitel nabízí backend“, nikdy „vyžaduj ho“.
Nativní backend
Sekce “Nativní backend”macOS: Seatbelt
Sekce “macOS: Seatbelt”Používá sandboxový mechanismus Apple Seatbelt (tentýž systém jako macOS App Sandbox).
Vygenerovaný profil je ve výchozím stavu permisivní ((allow default)) a vykrajuje zákazy, protože profil, který ve výchozím stavu všechno zakáže, udělá interaktivní shell nepoužitelný — volání dyld, XPC a Mach je na vypsání moc. Praktický důsledek: agent pořád může číst většinu hostitele; tvoje registrované checkouty chrání výslovné zákazy zápisu a přejmenování, ne neviditelnost.
- Čtení souborového systému: zakázané pro tajné cesty (
~/.ssh,~/.aws,~/.gnupg,~/.config/gh,~/Library/Keychainsa zbytek sady zákazů čtení) - Zápis do souborového systému: nejdřív se vrátí na zákaz, pak se výslovně povolí podcesty, přičemž cesty s povinným zákazem (rc soubory shellu,
.git/hooks, konfigurace Claude, chráněné checkouty) jsou blokované i uvnitř zapisovatelného kořene.file-write-unlinkje zakázaný na každé zakázané cestě a jejích předcích, takže přejmenování zákaz zápisu neobejde - Proces:
process-execzakazuje binárky, které jsou vždy nebezpečné, a k tomu blokuje spuštění čehokoli ze zapisovatelného adresáře - Síť: omezená na porty proxy v procesu a na DNS — loopback není povolený plošně a Unix sockety povolené nejsou. Proxy vynucují seznam povolených domén dané relace (viz Odchozí síť)
- Konfigurace: profily se generují pro každý start ze
SandboxSpec
Požadavky:
sandbox-exec(/usr/bin/sandbox-exec), součást každé instalace macOS — další nástroje nejsou potřeba
Linux: bubblewrap
Sekce “Linux: bubblewrap”Používá bubblewrap (bwrap) k vytvoření jmenných prostorů připojení a PID.
- Souborový systém: vytvoří jmenný prostor připojení, ve kterém jsou vidět jen navázané cesty
- Síť: běží v nesdíleném síťovém jmenném prostoru; provoz se k proxy na hostiteli dostane přes mosty
socatna Unix socketech - Proces: izolace jmenného prostoru PID
Požadavky:
- Nainstalované
bubblewrapasocat(sudo apt-get install bubblewrap socatna Debian/Ubuntu) - Podpora jmenných prostorů v jádře (na moderním Linuxu standard)
Bubblewrap umí zastínit existující cestu, ale neumí zakázat nový soubor .env,
*.key nebo *.pem uvnitř zapisovatelného bindu. Standardní politika odeslání
tyhle zákazy podle globu názvu souboru vyžaduje, takže nativní odeslání agenta teď
selže uzavřeně na Linuxu a WSL2, i když sonda najde bubblewrap. Nespustí se
s potichu slabší politikou. K obnovení nativního odeslání na Linuxu je potřeba
backend s pravidly názvů souborů v okamžiku vytvoření. Vypnutí sandboxu je
výslovné vypnutí bez omezení, ne rovnocenné náhradní řešení.
Žádný backend
Sekce “Žádný backend”Bez sandboxu. Proces běží přímo na hostiteli s jeho souborovým systémem, sítí a přístupem k procesům. ACP a nástroj bash harnessu pořád dostanou očištění prostředí a politiku příkazů; Claude Code přes NoSandboxAdapter dědí prostředí hostitele. Sem spadne odeslání agenta na hostiteli bez dostupného backendu nebo s --sandbox off a je to výchozí stav terminálu, když klient uvede none.
Terminál hostovaný na serveru
Sekce “Terminál hostovaný na serveru”Terminál má vlastní pravidla sandboxu, ne ta ze sondy odeslání. defaultBackend u TerminalSessionService je none a cc_server ho nepřepisuje, takže relace terminálu spouští shell hostitele, dokud klient výslovně nepožádá o native — panel terminálu v aplikaci na počítači o to nežádá.
Když je požadovaný native, shell se obalí přes SandboxManager pevným profilem terminálu: $HOME a pracovní adresář relace jsou zapisovatelné, síť je otevřená a ~/.ssh, ~/.aws, ~/.gnupg, ~/.config/gh a ~/Library/Keychains mají zákaz čtení. Token forge jen pro čtení a brána pro push se neuplatní — to řeší odeslání. Když obal není podporovaný, relace selže, místo aby na PTY shellu hostitele ukázala odznak nativního sandboxu.
Odchozí síť
Sekce “Odchozí síť”Když se sandbox spustí, odchozí přístup k síti vynucují proxy v procesu, ne pravidla firewallu v jádře. Na hostiteli bez dostupného backendu nic z toho neplatí a spuštěný proces se k síti dostane přesně tak, jako by se k ní dostal uživatel serveru.
- Runtime sandboxu spouští HTTP/HTTPS proxy a SOCKS5 proxy na
127.0.0.1uvnitř procesucc_server, jeden pár na každou omezenou relaci (http_proxy.dart,socks_proxy.dart). Souběžné běhy pár nesdílejí. - Sandboxované procesy dostanou proměnné prostředí proxy (
HTTP_PROXY/HTTPS_PROXY→ HTTP proxy,ALL_PROXY→ SOCKS proxy;GIT_SSH_COMMANDvede git přes SSH skrz SOCKS proxy). Na Linuxu je síťový jmenný prostor nesdílený, takže proxy jsou jediná cesta ven; na macOS sandbox sdílí loopback hostitele a mluví s nimi přímo. - Cílový hostitel každého spojení se porovná se seznamem povolených domén relace; všechno ostatní se odmítne. Dva tvary zástupných znaků, každý s právě jednou
*: úvodní*.example.comodpovídá libovolné subdoméně (včetněa.b.example.com), ale ne samotnému apexu; prostřední návěštíbedrock.*.amazonaws.comodpovídá právě jednomu návěští (bedrock.us-east-1.amazonaws.com, nebedrock.evil.attacker.amazonaws.com). - Seznam povolených se pro každou relaci sestaví z vybraného základu (
kBaselineAllowedDomains: poskytovatelé LLM, hosting gitu, registry balíčků), plus domény GitHubu (kGithubDomains), plusSandboxSpec.egressAllowlist. Cesta odeslání nikdy nepředá další položkyegressAllowlist, takže v praxi každý běh dostane základ plus GitHub. - Pevný seznam zákazů (
kBaselineDeniedDomains: endpointy metadat cloudu, cíle telemetrie) má přednost před všemi povoleními. networkEnabled: falseproxy pro danou relaci pořád spustí, ale seznam povolených je prázdný, takže se každé odchozí spojení odmítne. Odeslání hodnotu nastaví při startu běhu podle pravidla Přístup k síti: zakázat síť vypne, povolit a nejdřív se zeptat ji nechají zapnutou.
SandboxSpec
Sekce “SandboxSpec”Specifikace předaná do SandboxPort.launch:
| Pole | Typ | Popis |
|---|---|---|
sessionId |
String |
Stabilní identifikátor relace (obvykle id prostoru) |
workspaceId |
String |
Id vlastnicího pracovního prostoru |
agentId |
String? |
Agent právě navázaný na sandbox, pokud nějaký je |
bindMounts |
List<SandboxBindMount> |
Připojení hostitel→host; sandbox vidí jen cesty hostitele uvedené tady |
networkEnabled |
bool (výchozí true) |
Nastaví ho odeslání podle pravidla pro odchozí síťový provoz (vypnuté jen tehdy, když vyjde zakázat). Když je vypnuté, proxy pro danou relaci se pořád spustí, ale seznam povolených je prázdný, takže se každé odchozí spojení odmítne |
egressAllowlist |
List<String> (výchozí []) |
Další povolené domény odchozího provozu; podporuje zástupné znaky (*.example.com a tvar s jedním prostředním návěštím). Odeslání tohle pole nikdy nenaplní, takže obalený běh dostane vybraný základ plus domény GitHubu |
guestWorkdir |
String? |
Výchozí pracovní adresář uvnitř sandboxu; jednotlivá volání exec ho umí přepsat |
mode |
Mode (výchozí chat) |
Vykrajuje pravidla zápisu do souborového systému: chat nechává bind mounty zapisovatelné; review, plan a orchestrate jsou jen pro čtení |
protectedPaths |
List<String> (výchozí []) |
Cesty hostitele, které uvnitř sandboxu nesmí být v žádném režimu zapisovatelné |
runnerStateDirs |
List<String> (výchozí []) |
Adresáře hostitele, ve kterých si runner drží vlastní stav, zapisovatelné v každém režimu (zatím je to CLAUDE_CONFIG_DIR spravovaný Control Center) |
execGrantRoots |
List<String> (výchozí []) |
Stromy adresářů schválené operátorem, které na macOS znovu otevřou blok exec ze zapisovatelného adresáře. Linux je ignoruje — bwrap nemá v $HOME blok exec, který by šlo znovu otevřít |
protectedPaths drží původní registrované checkouty repozitářů, rozřešené při každém odeslání z repozitářů pracovního prostoru. Agenti pracují jen v copy-on-write worktree dané konverzace, takže originály nesmí jít zevnitř sandboxu zapisovat — na macOS by je jinak plošné povolení zápisu Seatbeltu do $HOME nechalo zapisovatelné přes bash. Přidají se do sady zákazů zápisu tajemství v každém režimu, včetně chat.
Každá cesta se zákazem čtení i se zákazem zápisu se vypíše v doslovném zápisu i v zápisu po rozřešení symlinku. Jádro porovnává pravidlo zákazu s rozřešenou cestou, takže pravidlo zapsané proti cestě se symlinkem se nikdy neuplatní — a na macOS je to běžný případ, ne výjimka, protože /tmp se rozřeší na /private/tmp a /var/folders/… na /private/var/folders/…. Položky obsahující * nebo ? se berou jako globy a nechají se být; cesta, která se nerozřeší, zůstane zapsaná tak, jak byla.
SandboxBindMount
Sekce “SandboxBindMount”| Pole | Typ | Popis |
|---|---|---|
hostPath |
String |
Absolutní cesta na hostiteli |
guestPath |
String |
Cesta uvnitř sandboxu (u nativního sandboxu se rovná hostPath; ponechaná kvůli symetrii adaptérů) |
readOnly |
bool (výchozí false) |
Když je true, připojí se jen pro čtení |
SandboxHandle
Sekce “SandboxHandle”Vrací ho SandboxPort.launch:
| Pole | Typ | Popis |
|---|---|---|
sessionId |
String |
Identifikátor relace |
backend |
SandboxBackend |
Který backend běží |
state |
SandboxState |
Stav životního cyklu |
error |
Object? |
Nastavené, když je state rovno error |
details |
Map<String, Object?> |
Soukromá evidence adaptéru (pracovní adresář, PID, cesta k profilu atd.) |
SandboxState
Sekce “SandboxState”| Stav | Popis |
|---|---|
created |
Specifikace je vytvořená, ale VM ještě nestartovalo |
warm |
Běží a je připravené spouštět příkazy |
active |
Právě provádí příkaz |
suspended |
Pozastavené / checkpoint na disku, aby se ušetřila RAM |
destroyed |
Uklizené; handle už neplatí |
error |
Start selhal — viz SandboxHandle.error |
Události sandboxu
Sekce “Události sandboxu”| Typ události | Popis |
|---|---|
stdout |
Standardní výstup ze sandboxu |
stderr |
Standardní chybový výstup ze sandboxu |
exit |
Proces sandboxu skončil (nese exitCode) |
starting |
Sandbox se spouští |
ready |
Sandbox je připravený přijímat volání exec |
killed |
Proces ukončil hostitel (OOM, timeout, ruční zastavení) |
violation |
Politika sandboxu byla porušena (nese SandboxViolation) |
SandboxViolation
Sekce “SandboxViolation”| Pole | Typ | Popis |
|---|---|---|
action |
String |
Odmítnuté sloveso (např. file-read*, network-outbound) |
target |
String |
Cesta nebo hostitel, na který odmítnutá operace mířila |
raw |
String? |
Surový řádek logu, užitečný při ladění |
Viz také
Sekce “Viz také”- Sandbox a zabezpečení
- Nastavte politiky sandboxu
- Guardraily
- CLI cc_server: příznak
--sandbox