Tovább a tartalomhoz

Korlátok – egy szabályzat minden állapotmódosító művelethez

A Control Center ügynökei fájlokat törölhetnek, ágakat küldhetnek fel, pull requesteket tehetnek közzé és külső API-kat hívhatnak. Ezek mind más-más kockázatfajtát jelentenek, és sokáig csak az egyikükre – a shellparancsokra – volt szabályzat. A korlátok azért vannak, hogy minden állapotmódosító műveletre, amelyet egy ügynök végrehajthat, egységesen válaszoljanak egyetlen kérdésre, függetlenül attól, melyik futtatókörnyezet vagy eszköz javasolja: engedélyezve van, jóváhagyást igényel, vagy tilos?

Egy motor, minden szűk keresztmetszetnél

Szekció neve “Egy motor, minden szűk keresztmetszetnél”

Pontosan egy szabályzatmotor van. Minden olyan ponton megkérdezik, ahol egy művelet elhagyhatja a rendszert: a beépített harness eszközregiszterénél, a szerveroldali MCP-diszpécser kapujánál és a repóműveletek módosításainál. Az egyszer megírt szabály így ugyanúgy érvényes a beépített futtatókörnyezetre és a külső ügynök-CLI-kre – nincs mögötte egy második, halkabb útvonal. A régebbi, csak bashre vonatkozó parancsszabályzat továbbra is működik: egy szabály illeszkedhet parancs-előtagra műveletosztály helyett, és a két forma ugyanabban a tárban él egymás mellett.

A motor azonban nem helyettesíti az operációs rendszer homokozóját, és a homokozó sem helyettesíti a motort. Különböző kérdésekre válaszolnak: a korlátok döntik el, hogy egy, a Control Center által látható hívás egyáltalán megtörténhet-e, a homokozó pedig azt szabja meg, hová érhet el a létrejövő folyamat. A cc_server ott alkalmazza a homokozót, ahol a gazdagép kínál háttérrendszert – de a Windows nem kínál ilyet, a Linuxon pedig bwrap és socat kell hozzá. Az ilyen gazdagépeken a korlátok a legkülső érvényesítési réteg, nem pedig egy padló tetején ülő szabályzat, amit érdemes tudni, amikor eldönti, mennyire legyen megengedő.

ActionClass: szándékosan zárt taxonómia

Szekció neve “ActionClass: szándékosan zárt taxonómia”

Minden állapotmódosító eszköz megadja, hogy mely ActionClass-okba tartozik, egy tizenhárom hatásosztályból álló zárt halmazból. Öt közülük alapértelmezés szerint kérdez; a többi engedélyez, és ezen csak egy szabály változtat.

Osztály Beépített alapértelmezett Mit fed le
fileDelete Előbb kérdezzen Fájl törlése (törlés jellegű írás, rm)
gitPush Előbb kérdezzen Küldés távoli git-tárolóra
prCreate Előbb kérdezzen Pull request megnyitása
prPublish Előbb kérdezzen Átnézés közzététele, PR összefésülése
vendorSyncWrite Előbb kérdezzen Írás külső jegyrendszerbe (Linear, Jira, GitHub-szinkron)
fileWriteOutsideWorktree Engedélyezés Fájl írása az elszigetelt worktree-n kívülre
gitCommit Engedélyezés Git-commit létrehozása
networkEgress Engedélyezés Hálózati kimenő forgalom (weblekérés, tetszőleges HTTP)
secretAccess Engedélyezés Titok vagy hitelesítő adat olvasása
packageInstall Engedélyezés Csomag telepítése (npm, pip, pub, brew)
processSpawn Engedélyezés Folyamat indítása (shell, és minden, ami shellt hív)
workspaceMutation Engedélyezés A munkaterület szerkezetének módosítása (repók, terek, ügynökök)
enclosureControl Engedélyezés Elszigetelt környezet (állomás) irányítása: VM indítása, bemenet küldése neki

A nyolc alapból engedélyező osztályt abból a feltevésből választották, hogy alattuk érvényesül a homokozó padlója. Ez ott igaz, ahol a gazdagép kínál háttérrendszert, Windows alatt viszont nem, és olyan Linux-gépen sem, amelyről hiányzik a bwrap és a socat – így ha ott a fileWriteOutsideWorktree vagy a packageInstall kapuzását szeretné, azt Önnek kell szabályként megírnia.

A halmaz szándékosan zárt. Egy új, osztályt nem megadó állapotmódosító eszköz megbukik a ratchet-teszten, így a taxonómia csak kifejezett, megindokolt döntéssel bővülhet – „a taxonómiák burjánzása megöli ezt a funkciót”. Tizenhárom osztály elég ahhoz, hogy kifejezze azokat a szabályzatokat, amelyeket az emberek ténylegesen megírnak (soha ne küldj fel kérdezés nélkül, soha ne törölj a worktree-n kívül, mindig engedélyezd az olvasást), és elég kevés ahhoz, hogy a beállítások felülete érthető maradjon.

Egy szabály hozzárendelést ír le: (scope, ActionClass | command prefix) → allow | prompt | deny. A hatókörök a legspecifikusabbtól a legkevésbé specifikusig egymásba ágyazódnak:

tér > ügynök > munkaterület > módkészlet > beépített alapértelmezett

A feloldásnál a specifikusság az első: az első olyan hatókör dönt, amelyben van illeszkedő szabály, és a feloldás ott megáll. A legszigorúbb szabály csak holtverseny eldöntésére szolgál – két egyformán specifikus szabály között egy hatókörön belül, illetve amikor egyetlen művelet több deklarált osztályát összevonják. Egy hatókörön belül a parancsszabály a leghosszabb illeszkedő parancs-előtagot veszi alapul. Az engedélyezés sehol nem győzi le a tiltást.

Két döntés kemény garanciát hordoz:

  • Zárt hibamódú kérések. Egy prompt, amelyhez nincs csatlakoztatott jóváhagyó, elutasítva eredménnyel zárul. Egy megválaszolatlan kérdés soha nem jelent igent.
  • Legszigorúbb kombináció. Egy több osztályt átfogó művelet ezeket a legszigorúbb módon vonja össze; ha több osztály kérdez, egyetlen megerősítés sorolja fel mindet.

Szándékosan nincs körönkénti rögzítés. Minden eszközhívás elölről oldja fel a szabályzatot, így ugyanannak a műveletnek az ismételt megkérdezése nem körhöz kötött, hanem az üzemeltető saját „jegyezd meg ezt a döntést” választása korlátozza.

Egy szabály nem csak a művelet igéjét, hanem az ARGUMENTUMAIT is korlátozhatja. „Küldhet” és „küldhet a feature/* ágra” két különböző állítás, és csak a második jelent valódi szabályozást – a legtöbb nyilvánosságra került ügynökincidens mintázata mögött egy olyan képességkapu áll, amely egyedül az igét engedélyezi.

Egy megkötés a következőket nevezheti meg:

  • útvonalak — glob minták (repos/**, !**/.env)
  • refek — git-refek, ! tagadással (['**', '!main'] jelentése: „minden ág a main kivételével”)
  • gazdagépek — hálózati célpontok, aldomen-helyettesítő karakterekkel (*.internal)
  • parancsok — parancs-előtagok, szóhatáron illesztve
  • plafonok — maxCount / maxCents, így a „legfeljebb 50 fájl törlése” is kifejezhető

A nyelvtan zártságából és hurokmentességéből három tulajdonság következik, és mindhárom lényeg: minden szabály visszaolvasható mondatként jelenik meg, minden elutasítás meg tudja nevezni az illeszkedő megkötést, és a teljes szabályzat felsorolható – már futtatás előtt láthatja, mit tehet egy ügynök.

Három szabály, amely számít:

  • Egy megkötött szabály specifikusabb, mint egy megkötetlen ugyanabban a hatókörben, így „a main ágra való küldés tiltása” legyőzi „a küldés engedélyezése” szabályt anélkül, hogy bárkinek a sorrenden kellene gondolkodnia.
  • Egy korlátozó szabály (tiltás / kérdezés) akkor érvényesül, ha a kérés az általa megnevezett értékek bármelyikét érinti; egy megengedő szabály (engedélyezés) csak akkor, ha a kérés teljes egészében beleillik. Ha mindkettőt ugyanúgy olvasnánk, az ügynök úgy moshatna tisztára egy tiltott útvonalat, hogy mellé tesz egy ártalmatlant is.
  • Egy szabály, amely olyan szempontot nevez meg, amelyről a kérés nem mond semmit, nem alkalmazódik és nem is marad ki: jóváhagyásra eszkalálódik. A csendes kihagyás minden védett ágra vonatkozó szabályt hatástalanná tenne olyan eszközökkel szemben, amely nem jelenti be a refjét; a csendes elutasítás pedig minden olyan küldést visszautasítana, amelyet a kinyerő nem tud leírni. Ha nincs csatlakoztatott jóváhagyó, a meglévő zárt hibamódú szabály ezt az eszkalációt elutasítássá alakítja.

Mit tud és mit nem tud elkapni egy parancsszabály

Szekció neve “Mit tud és mit nem tud elkapni egy parancsszabály”

A commandPrefix szabály szóhatáron illeszkedik: a git push lefedi a git push origin main parancsot, de a git pushx-et nem. A shellt nem normalizálja. A git push (két szóköz), a cd sub && git push és a GIT_DIR=… git push mind különböző karaktersorozatok, és egyik sem illeszkedik a git push-ra vonatkozó szabályra.

Ez valódi korlát, és kimondjuk ahelyett, hogy elkendőznénk: a parancsszabályok az üzemeltető kényelmi eszközei a szokásos ügynökviselkedés formálására, nem jelentenek határt egy támadó szándékú ügynökkel szemben. A határok a hatásosztályok (amelyeket egy eszköz deklarál, és nem tud átfogalmazni), a szabályzattár alatti módparancsháló, és mindkettő alatt az operációs rendszer homokozója. Egy allow-ra feloldódó parancsszabály soha nem lazítja meg egyiket sem – a módháló utána fut, és a deny-ja végleges.

Ha egy kérésre „jegyezd meg ezt” válasszal felel, az valódi szabályzati szabályt ír: hatókörrel ellátottat (tér / ügynök / munkaterület), argumentumokkal megkötöttet (a feature/login ágra való küldés jóváhagyása a feature/**-ot engedélyezi, nem a main-t), és egy megadott TTL-lel önmagát visszavonót. Nem ugyanaz néhány órára igent mondani, mint csendben átírni az állandó szabályzatát, és a beírt szabályok ugyanabba a tárba kerülnek remembered eredetmegjelöléssel és lejárati idővel, így korábban is visszavonhatók.

Minden szabály egyet hordoz:

  • tanácsadó – engedélyez, de rögzíti, hogy a szabály illeszkedett. Ez a bevezetési útvonal: tegyen ki egy szigorú szabályt tanácsadó módban, olvassa egy hétig a jogosultsági naplót, hogy pontosan lássa, mit blokkolt volna, majd léptesse elő. E szint nélkül a szigorú szabályzatok soha nem kapcsolódnak be.
  • puha – tilt, de felülírható annak, aki rendelkezik a felülírási jogosultsággal, rögzített indoklással. Maga a felülírás is auditált esemény.
  • kemény (az alapértelmezett) – tilt. Semmi nem írja felül.

A telepítés üzemeltetője rögzíthet olyan szabályzatot, amelyet egyetlen munkaterület-adminisztrátor sem lazíthat meg. A felügyelt szabályok szerveroldalon élnek, és a legszigorúbb módon olvadnak össze az egyes munkaterületek saját láncával – nem annak élén álló hatókörként, mert egy lánc elején álló felügyelt allow lehetővé tenné, hogy a telepítés felülírja egy munkaterület tiltását, ami épp az ellenkezője annak, amire egy szorító szolgál. Egy felügyelt szabály ezért csak szigoríthat.

A CC_SERVER_MANAGED_POLICY beállítása egy JSON-fájlra teljesen felülírja a tárolt szabályokat, és ez teszi lehetővé, hogy az üzemeltető olyan tartást rögzítsen, amelyet egyetlen adminfelület sem billenthet át – ez a válasz arra a kérdésre, hogy „meg tudom-e akadályozni, hogy a fejlesztőim kikapcsolják a biztonsági vezérlőket?”.

Az autonómiatárcsa profil, nem párhuzamos rendszer

Szekció neve “Az autonómiatárcsa profil, nem párhuzamos rendszer”

A térenkénti autonómiatárcsa egy elnevezett profil ugyanezen szabályzattár fölött, nem külön mechanizmus. Három beállítását proposeOnly, actWithApproval és actFreely néven tárolja és küldi (a kötőjelezett formák csak a felület szövegében élnek, és az autonomy.setForSpace minden mást elutasít). Beállítatlanul úgy viselkedik, mint az actWithApproval.

Mit tesznek a feloldott döntéssel:

  • A proposeOnly minden kapuzott eszközt egyenesen megtilt. Az ügynök továbbra is gondolkodhat és válaszolhat; egyszerűen nem cselekedhet, és az üzenete megmondja, miért.
  • Az actWithApproval (és a beállítatlan állapot) a fent leírt zárt hibamódú jóváhagyási kapu.
  • Az actFreely előre jóváhagy mindent, ami nem kemény deny-ra oldódott fel.

Az utóbbit érdemes kerek-perec kimondani, nem tompítani: actFreely alatt a prompt döntés nem eszkalálódik jóváhagyóhoz – engedélyezve lesz, és senkit nem kérdeznek meg. A tárcsát csak egy kifejezett deny szabály éli túl. Az actFreely tehát szándékos autonómiaengedmény, nem kényelmi beállítás, és a zárt hibamódú szabály pontosan ott véd, ahol számít (actWithApproval, az alapértelmezés).

Az ügynökök közötti delegálást a delegate_task szűk keresztmetszeténél mind a négy őr védi: egy mélységkorlát (alapértelmezés: 3), a ciklusfelismerés, egy autonómiaplafon (a delegált soha nem cselekedhet nagyobb autonómiával, mint a delegálója – a kiváltság nem mosható tisztára azzal, hogy a munkát egy szabadabb ügynökre bízzák) és egy költségvetési keret (a delegálás a delegáló maradék keretét terheli, és nem bocsáthat ki többet). Mindegyiket hangosan utasítja el, az őr indokát szó szerint visszaadva az ügynöknek.

Nem minden futtatókörnyezet engedi, hogy a Control Center elfogjon minden műveletet. A külső ügynök-CLI-k egyes eszközöket natívan, a folyamatukon belül futtatnak, ahová nem ülhet kapu. Ahelyett, hogy az ellenkezőjét színlelné, minden adapter egy őszinteségi mátrixot hordoz: adapterenként azt, hogy a Control Center szűri-e az eszközfelszínt, elfogja-e az eszközhívásokat, figyeli-e a befejezési szerződést, látja-e a futtató natív eszközeit, és hogy a folyamaton belüli eszközöket lefedi-e egy homokozóprofil.

Két bejegyzést érdemes elolvasni, mielőtt megbízik egy konfigurációban. A beépített harness azt jelenti be, hogy a folyamatán belüli fájleszközei nincsenek homokozóban – az eszközfelszín és ez a szabályzatmotor az egyetlen fájlrendszer-határ, amellyel rendelkezik. A Claude Code azt jelenti be, hogy a saját eszközhívásai nem foghatók el, mert --dangerously-skip-permissions kapcsolóval indul; a Control Center az mcp__* hívásait és – egy hookon keresztül – a Bash parancssorait látja, a saját olvasó, író és szerkesztő eszközei pedig láthatatlanul futnak.

A beállítások képernyője megmutatja ezt a mátrixot, mert egy korlátrendszer egyetlen megbocsáthatatlan hibája, ha nem létező lefedettséget állít.

A szabályzat kipróbálása, mielőtt az fájna

Szekció neve “A szabályzat kipróbálása, mielőtt az fájna”

A korlátok a Beállítások → Munkaterület → Ügynökjogosultságok helyen élnek (/workspaces/<id>/settings/workspace/permissions). A képernyőn megtalálható a szabályzatmátrix, ahol a szabályok íródnak, a szabályzatsablonok, a „mi lenne, ha?” próba, a jogosultsági napló és az adapterek őszinteségi mátrixa.

A próba egy műveletosztályt (vagy parancsot) és egy hatókört vesz, és megmutatja, melyik szabály döntött és miért. Mivel a feloldás tiszta és determinisztikus – ugyanaz a művelet, ugyanaz a hatókör, ugyanaz a döntés –, a próba válasza az a válasz, amelyet az ügynök kapni fog.