Přeskočit na obsah

Guardraily — jedna politika pro každou měnící akci

Agenti v Control Center mohou mazat soubory, odesílat větve, publikovat pull requesty a volat externí API. Každá z těch akcí nese jiný druh rizika a dlouho měla politiku jen jedna z nich, příkazy shellu. Guardraily odpovídají na jednu otázku stejně u každé měnící akce, kterou agent může provést, ať ji navrhne kterýkoli runtime nebo nástroj: je povolená, potřebuje schválení, nebo je zakázaná?

Jeden engine, každý kontrolní bod

Sekce “Jeden engine, každý kontrolní bod”

Engine politiky je právě jeden. Konzultuje se na každém místě, kde může akce systém opustit: v registru nástrojů vestavěného harnessu, na bráně serverového dispatcheru MCP a u mutací repo operací. Pravidlo zapsané jednou proto platí pro vestavěný runtime i pro externí CLI agentů. Žádná druhá, tišší cesta okolo nevede. Starší politika jen pro bash pořád platí: pravidlo může místo třídy akce odpovídat prefixu příkazu a obě podoby žijí ve stejném úložišti.

Engine ale nenahrazuje sandbox operačního systému a sandbox nenahrazuje jeho. Každý odpovídá na jinou otázku. Guardraily rozhodují, jestli se volání, které Control Center vidí, smí vůbec stát. Sandbox omezuje, kam smí výsledný proces dosáhnout. cc_server použije sandbox tam, kde hostitel nabízí backend, ale Windows žádný nenabízí a Linux potřebuje bwrap a socat. Na těch hostitelích jsou guardraily nejvnější vrstvou vynucení, ne politikou položenou na podlahu. To se hodí vědět, když se rozhoduješ, jak volné nastavení zvolit.

ActionClass: schválně uzavřená taxonomie

Sekce “ActionClass: schválně uzavřená taxonomie”

Každý měnící nástroj deklaruje, do kterých ActionClasses patří, z uzavřené sady třinácti tříd efektů. Pět z nich má z výroby prompt, zbytek allow a mění to až pravidlo.

Třída Vestavěný výchozí Co pokrývá
fileDelete prompt Smazání souboru (zápis ve tvaru smazání, rm)
gitPush prompt Odeslání na git remote
prCreate prompt Vytvoření pull requestu
prPublish prompt Publikování kontroly, sloučení PR
vendorSyncWrite prompt Zápis do externího systému ticketů (synchronizace Linear, Jira, GitHub)
fileWriteOutsideWorktree allow Zápis souboru mimo izolovaný worktree
gitCommit allow Vytvoření git commitu
networkEgress allow Odchozí síťový provoz (web fetch, libovolné HTTP)
secretAccess allow Čtení tajemství nebo přihlašovacích údajů
packageInstall allow Instalace balíčku (npm, pip, pub, brew)
processSpawn allow Spuštění procesu (shell a všechno, co si přes shell zavolá)
workspaceMutation allow Změna struktury pracovního prostoru (repozitáře, prostory, agenti)
enclosureControl allow Ovládání izolovaného prostředí (stanice): start VM, poslání vstupu

Osm tříd s výchozím allow počítá s tím, že pod nimi leží podlaha sandboxu. Leží tam, kde hostitel nabízí backend. Na Windows a na Linuxu bez bwrap a socat ne. Chceš-li tam hlídat fileWriteOutsideWorktree nebo packageInstall, musíš to pravidlo napsat.

Sada je uzavřená schválně. Nový měnící nástroj, který nedeklaruje žádnou třídu, neprojde testem západky, takže taxonomie roste jen výslovným a zdůvodněným rozhodnutím. „Rozbujení taxonomie je pro tuhle funkci konec.“ Třináct tříd stačí na politiky, které lidé opravdu píšou (nikdy neodesílat bez dotazu, nikdy nemazat mimo worktree, čtení vždy povolit), a je jich dost málo na to, aby nastavení zůstalo srozumitelné.

Pravidla a vyhodnocení rozsahu

Sekce “Pravidla a vyhodnocení rozsahu”

Pravidlo mapuje (scope, ActionClass | command prefix) → allow | prompt | deny. Rozsahy se vnořují od nejužšího k nejširšímu:

Prostor > Agent > Pracovní prostor > Předvolba režimu > Vestavěný výchozí

Vyhodnocení jde nejdřív podle konkrétnosti: první rozsah s odpovídajícím pravidlem rozhodne a vyhodnocení tam končí. Nejpřísnější varianta je jen rozhodčí při shodě, mezi dvěma stejně konkrétními pravidly v jednom rozsahu a při skládání několika tříd, které jedna akce deklaruje. Uvnitř rozsahu se pravidlo příkazu páruje podle nejdelšího prefixu příkazu. Allow nikde nepřebije deny.

Dvě rozhodnutí nesou tvrdé záruky:

  • Výzvy se při chybějícím schvalovateli zamítnou. prompt bez připojeného schvalovatele se vyhodnotí jako zamítnuto. Nezodpovězená otázka nikdy není ano.
  • Nejpřísnější složení. Akce přes několik tříd je složí nejpřísněji. Když se ptá několik tříd, jedno potvrzení je vypíše všechny.

Schválně tu není západka na tah. Každé volání nástroje vyhodnotí politiku znovu od začátku, takže opakované dotazování na stejnou akci omezuje jen to, že si rozhodnutí pamatuješ volbou „Schválit na 8 hodin“, ne nic vázaného na tah.

Pravidla na úrovni argumentů

Sekce “Pravidla na úrovni argumentů”

Pravidlo může omezit ARGUMENTY akce, ne jen její sloveso. „Smí odeslat“ a „smí odeslat na feature/*“ jsou různá tvrzení a kontrolou je jen to druhé. Brána schopností, která pustí jen sloveso, je tvar za většinou popsaných incidentů s agenty.

Omezení může jmenovat:

  • cesty – vzory glob (repos/**, !**/.env)
  • refy – git refy, s negací ! (['**', '!main'] se čte jako „libovolná větev kromě main“)
  • hostitelé – síťové cíle, se zástupnými znaky subdomén (*.internal)
  • příkazy – prefixy příkazů, párované na hranici slova
  • stropy – maxCount / maxCents, takže „smazat až 50 souborů“ jde vyjádřit

Z uzavřené gramatiky bez smyček plynou tři vlastnosti a právě o ně jde. Každé pravidlo se vykreslí jako věta, kterou si přečteš. Každé zamítnutí umí pojmenovat omezení, které sedělo. Celou politiku jde vyjmenovat, takže vidíš, co agent smí, dřív než se spustí.

Tři pravidla, na kterých záleží:

  • Omezené pravidlo je konkrétnější než neomezené ve stejném rozsahu, takže „zakázat odeslání na main“ vyhraje nad „povolit odeslání“ a na pořadí nemusíš myslet.
  • Restriktivní pravidlo (deny / prompt) platí, když požadavek sahá na libovolnou jmenovanou hodnotu. Permisivní (allow) platí jen tehdy, když požadavek leží celý uvnitř. Stejné čtení obou by agentovi dovolilo propašovat zakázanou cestu tak, že k ní přibalí nevinnou.
  • Pravidlo, které jmenuje hledisko, o němž požadavek nic neříká, se ani nepoužije, ani nepřeskočí: eskaluje na schválení. Tiché přeskočení by každé pravidlo chráněné větve zneškodnilo proti nástroji, který svůj ref neohlásí. Tiché zamítnutí by odmítlo každé odeslání, které extraktor neumí popsat. Když není připojený schvalovatel, existující pravidlo uzavření při neúspěchu z té eskalace udělá zamítnutí.

Co pravidlo příkazu zachytí a co ne

Sekce “Co pravidlo příkazu zachytí a co ne”

Pravidlo commandPrefix se páruje na hranici slova: git push pokryje git push origin main, ne git pushx. Shell nenormalizuje. git push (dvě mezery), cd sub && git push a GIT_DIR=… git push jsou jiné řetězce a žádný z nich nesedí na pravidlo o git push.

Je to skutečný limit a je řečený napřímo. Pravidla příkazů jsou pohodlí operátora pro běžné chování agenta, ne hranice proti útočníkovi. Hranice jsou třídy efektů (nástroj je deklaruje a nemůže je přepsat jiným zápisem), příkazová síť režimu pod úložištěm politiky a sandbox operačního systému pod obojím. Pravidlo příkazu, které se vyhodnotí jako allow, žádnou z těch dvou neuvolní. Příkazová síť režimu běží až potom a její deny je konečné.

Zapamatovaná schválení

Sekce “Zapamatovaná schválení”

Odpověď na výzvu volbou „Schválit na 8 hodin“ zapíše skutečné pravidlo politiky. Má rozsah (prostor / agent / pracovní prostor), je vázané na argumenty (schválení odeslání na feature/login udělí feature/**, ne main) a samo se zruší po explicitním TTL. Ano na pár následujících hodin není tiché přepsání trvalé politiky. Vzniklá pravidla spadnou do stejného úložiště s proveniencí remembered a s expirací, takže je můžeš odvolat dřív.

Každé pravidlo nese jednu:

  • advisory – povolit, ale zaznamenat, že pravidlo sedělo. Tudy vede zavedení. Nasadíš přísné pravidlo v režimu advisory, týden čteš auditní stopu a vidíš přesně, co by bylo zablokovalo, a pak ho povýšíš. Bez téhle úrovně se přísné politiky nikdy nezapnou.
  • soft – zakázat, s možností přebití pro toho, kdo drží oprávnění k přebití, a se zaznamenaným zdůvodněním. Samotné přebití je auditovaná událost.
  • hard (výchozí) – zakázat. Nic ho nepřepíše.

Operátor instalace může připnout politiku, kterou správce pracovního prostoru neuvolní. Spravovaná pravidla žijí na serveru a s vlastním řetězem každého pracovního prostoru se slučují nejpřísněji. Nejsou rozsahem na jeho začátku. Spravované allow v čele řetězu by instalaci dovolilo přebít deny pracovního prostoru, a to je opak toho, k čemu svorka slouží. Spravované pravidlo proto umí jen přitáhnout.

Když CC_SERVER_MANAGED_POLICY ukazuje na soubor JSON, má před uloženými pravidly úplnou přednost. Operátor tak připne postoj, který žádné správcovské rozhraní nepřepne. To je odpověď na otázku „zabráním vývojářům vypnout bezpečnostní kontroly?“.

Volič autonomie je profil, ne paralelní systém

Sekce “Volič autonomie je profil, ne paralelní systém”

Volič autonomie na prostor je pojmenovaný profil nad stejným úložištěm politiky, ne druhý mechanismus. Tři nastavení se ukládají a posílají jako proposeOnly, actWithApproval a actFreely (v rozhraní jsou to jen texty „Jen navrhovat“, „Jednat se schválením“ a „Jednat volně“ a autonomy.setForSpace cokoli jiného odmítne). Nenastavený se chová jako actWithApproval.

Co každé udělá s už vyhodnoceným rozhodnutím:

  • proposeOnly rovnou zakáže každý hlídaný nástroj. Agent pořád umí uvažovat a odpovídat, jen nemůže jednat a jeho zpráva řekne proč.
  • actWithApproval (a nenastavený stav) je výše popsaná brána schválení, která se při chybějícím schvalovateli uzavře.
  • actFreely předem schválí vše, co nedopadlo jako tvrdé deny.

To poslední je potřeba říct napřímo. Pod actFreely se rozhodnutí prompt ke schvalovateli neeskaluje: povolí se a nikdo se neptá. Volič přežije jen explicitní pravidlo deny. actFreely je záměrné udělení autonomie, ne nastavení pro pohodlí, a pravidlo uzavření při neúspěchu chrání právě případ, kde na něm záleží (actWithApproval, výchozí).

Delegování mezi agenty hlídá v kontrolním bodě delegate_task všechny čtyři pojistky: strop hloubky (výchozí 3), detekce cyklů, strop autonomie (delegát nikdy nejedná s vyšší autonomií než jeho delegátor, oprávnění nejde proprat předáním práce volnějšímu agentovi) a obálka rozpočtu (delegování účtuje zbývající rozpočet delegátora a neumí vyrobit další). Každá se odmítne nahlas a důvod pojistky se agentovi vrátí doslova.

Matice upřímnosti adaptéru

Sekce “Matice upřímnosti adaptéru”

Ne každý runtime nechá Control Center zachytit každou akci. Externí CLI agentů pouštějí některé nástroje nativně, v procesu, kam se brána nevejde. Místo předstírání proto každý adaptér nese matici upřímnosti. U každého adaptéru říká, jestli Control Center filtruje plochu nástrojů, zachytává volání nástrojů, sleduje kontrakt dokončení, vidí nativní nástroje runneru a jestli nástroje v procesu kryje profil sandboxu.

Dva záznamy si přečti, než konfiguraci uvěříš. Vestavěný harness deklaruje, že jeho souborové nástroje v procesu nejsou v sandboxu. Plocha nástrojů a tenhle engine politiky jsou jediná hranice souborového systému, kterou má. Claude Code deklaruje, že jeho vlastní volání nástrojů nejsou zachytitelná, protože se spouští s --dangerously-skip-permissions. Control Center vidí jeho volání mcp__* a přes hook i jeho příkazové řádky Bash, zatímco jeho vlastní nástroje pro čtení, zápis a úpravy běží mimo dohled.

Obrazovka nastavení tu matici ukazuje, protože jediné neodpustitelné selhání systému guardrailů je tvrdit pokrytí, které neexistuje.

Prověř politiku, než se zakousne

Sekce “Prověř politiku, než se zakousne”

Guardraily jsou v Nastavení → Pracovní prostor → Oprávnění agentů (/workspaces/<id>/settings/workspace/permissions). Na obrazovce je matice politiky, kam se pravidla zapisují, Šablony politik, sonda Co kdyby?, Auditní stopa autorizací a Kde se pravidla vynucují.

Sonda vezme třídu akce (nebo příkaz) a rozsah a ukáže, které pravidlo rozhodlo a proč. Vyhodnocení je čisté a deterministické, takže stejná akce a stejný rozsah dají stejné rozhodnutí. Odpověď sondy je odpověď, kterou dostane agent.