Beveiligingen — één beleid voor elke actie die iets wijzigt
Agents in Control Center kunnen bestanden verwijderen, branches pushen, pull requests publiceren en externe API’s aanroepen. Elk daarvan is een ander soort risico, en lange tijd had slechts één ervan — shellopdrachten — een beleid. De beveiligingen bestaan om één vraag uniform te beantwoorden, voor elke actie die een agent kan uitvoeren en die iets wijzigt, ongeacht welke runtime of welk hulpmiddel die voorstelt: is dit toegestaan, is er goedkeuring nodig, of wordt het geweigerd?
Eén engine, elk controlepunt
Sectie getiteld “Eén engine, elk controlepunt”Er is precies één beleidsengine. Die wordt geraadpleegd op elk punt waarop een actie het systeem kan verlaten: het toolregister van de ingebouwde harness, de poort van de server-side MCP-dispatcher en repo-opmutaties. Een regel die je één keer schrijft, geldt dus zowel voor de ingebouwde runtime als voor externe agent-CLI’s — er is geen tweede, stillere route eromheen. Het oudere opdrachtbeleid dat alleen op bash werkt, functioneert nog steeds: een regel kan op een opdrachtprefix matchen in plaats van op een actieklasse, en beide vormen bestaan naast elkaar in dezelfde opslag.
De engine is echter geen vervanging van de OS-sandbox, en de sandbox is geen
vervanging van de engine. Ze beantwoorden verschillende vragen: de beveiligingen
bepalen of een aanroep die Control Center kan zien wel mag plaatsvinden, terwijl
de sandbox begrenst waar het resulterende proces mag komen. cc_server past de
sandbox toe waar de host een backend biedt — maar Windows biedt er geen en Linux
heeft bwrap en socat nodig. Op zulke hosts
vormen de beveiligingen de buitenste handhavingslaag in plaats van een beleid
boven op een ondergrens, wat je moet weten wanneer je bepaalt hoe ruimhartig je
ze instelt.
ActionClass: een bewust gesloten taxonomie
Sectie getiteld “ActionClass: een bewust gesloten taxonomie”Elk hulpmiddel dat iets wijzigt, geeft aan tot welke ActionClasses het behoort, uit een gesloten set van dertien effectklassen. Vijf ervan vragen standaard om goedkeuring; de overige staan toe, en alleen een regel brengt daar verandering in.
| Klasse | Ingebouwde standaardwaarde | Wat eronder valt |
|---|---|---|
fileDelete |
Eerst vragen | Een bestand verwijderen (een verwijderingsachtige schrijfactie, rm) |
gitPush |
Eerst vragen | Naar een git-remote pushen |
prCreate |
Eerst vragen | Een pull request aanmaken |
prPublish |
Eerst vragen | Een review publiceren, een PR mergen |
vendorSyncWrite |
Eerst vragen | Schrijven naar een externe ticketservice (Linear, Jira, GitHub-synchronisatie) |
fileWriteOutsideWorktree |
Toestaan | Een bestand schrijven buiten de geïsoleerde worktree |
gitCommit |
Toestaan | Een git-commit aanmaken |
networkEgress |
Toestaan | Netwerkuitgaand verkeer (web fetch, willekeurige HTTP) |
secretAccess |
Toestaan | Een secret of referentie lezen |
packageInstall |
Toestaan | Een pakket installeren (npm, pip, pub, brew) |
processSpawn |
Toestaan | Een proces starten (shell en alles wat een shell aanroept) |
workspaceMutation |
Toestaan | De werkruimtestructuur wijzigen (repos, ruimtes, agents) |
enclosureControl |
Toestaan | Een omhulling (rig) aansturen: een VM opstarten, er invoer naartoe sturen |
De acht klassen die standaard toestaan, zijn gekozen in de veronderstelling dat
de sandboxondergrens eronder geldt. Dat is het geval waar de host een backend
biedt, en niet op Windows of op een Linux-machine zonder bwrap en socat —
dus als je wilt dat fileWriteOutsideWorktree of packageInstall daar wordt
afgevangen, moet je die regel zelf schrijven.
De set is bewust gesloten. Een nieuw hulpmiddel dat iets wijzigt en geen klasse opgeeft, zakt voor de ratchet-test, dus de taxonomie kan alleen groeien door een expliciet, beargumenteerd besluit — “taxonomievervuiling is de dood van deze functie.” Dertien klassen zijn genoeg om de beleidsregels uit te drukken die mensen daadwerkelijk schrijven (nooit pushen zonder te vragen, nooit buiten een worktree verwijderen, leesacties altijd toestaan) en weinig genoeg om de instellingen-UI begrijpelijk te houden.
Regels en bereikresolutie
Sectie getiteld “Regels en bereikresolutie”Een regel koppelt (bereik, ActionClass | opdrachtprefix) → toestaan | eerst vragen | weigeren.
Bereiken nestelen van meest naar minst specifiek:
ruimte > agent > werkruimte > modusvoorinstelling > ingebouwde standaardwaarde
Resolutie gaat eerst op specificiteit: het eerste bereik met een passende regel beslist en daar stopt de resolutie. Meest beperkend is alleen een tiebreak — tussen twee even specifieke regels binnen één bereik en bij het combineren van de klassen die één actie opgeeft. Binnen een bereik matcht een opdrachtregel op het langste opdrachtprefix. Toestaan wint nergens van weigeren.
Twee beslissingen komen met harde garanties:
- Fail-closed vragen. Een
promptzonder verbonden goedkeurder wordt geweigerd. Een onbeantwoorde vraag is nooit een ja. - Meest beperkende combinatie. Een actie die meerdere klassen omvat, combineert ze op de meest beperkende manier; wanneer meerdere klassen om goedkeuring vragen, somt één bevestiging ze allemaal op.
Er is bewust geen vergrendeling per beurt. Elke toolaanroep lost het beleid opnieuw vanaf nul op, dus herhaald vragen om goedkeuring voor dezelfde actie wordt begrensd door de “deze beslissing onthouden” van de operator zelf, niet door iets dat aan een beurt gebonden is.
Regels op argumentniveau
Sectie getiteld “Regels op argumentniveau”Een regel kan de ARGUMENTEN van een actie beperken, niet alleen het werkwoord.
“Mag pushen” en “mag naar feature/* pushen” zijn verschillende beweringen, en
alleen de tweede is een beheersmaatregel — een capaciteitspoort die alleen het
werkwoord autoriseert, ligt ten grondslag aan de meeste gepubliceerde
agentincidenten.
Een beperking kan het volgende benoemen:
- paden — globpatronen (
repos/**,!**/.env) - refs — git-refs, met
!-negatie (['**', '!main']leest als “elke branch behalve main”) - hosts — netwerkbestemmingen, met subdomeinwildcards (
*.internal) - opdrachten — opdrachtprefixen, gematcht op een woordgrens
- plafonds —
maxCount/maxCents, zodat “maximaal 50 bestanden verwijderen” uitdrukbaar is
Drie eigenschappen volgen uit het gesloten en lusvrij houden van de grammatica, en die drie zijn precies de bedoeling: elke regel is weer te geven als een zin die je kunt teruglezen, elke weigering kan de beperking benoemen die matchte, en het hele beleid is op te sommen — je kunt zien wat een agent mag doen voordat die draait.
Drie regels die ertoe doen:
- Een beperkte regel is specifieker dan een onbeperkte regel in hetzelfde
bereik, dus “push naar
mainweigeren” wint van “push toestaan” zonder dat iemand over de volgorde hoeft na te denken. - Een beperkende regel (weigeren / eerst vragen) geldt wanneer de aanvraag een willekeurige waarde aanraakt die de regel benoemt; een permissieve regel (toestaan) geldt alleen wanneer de aanvraag er volledig binnen valt. Als je beide op dezelfde manier zou lezen, kon een agent een verboden pad witwassen door er een onschuldig pad naast te zetten.
- Een regel die een aspect benoemt waarover de aanvraag niets zegt, wordt niet toegepast en ook niet overgeslagen: die escaleert naar een goedkeuring. Stil overslaan zou elke regel voor beschermde branches inactief maken tegenover een hulpmiddel dat zijn ref niet rapporteert; stil weigeren zou elke push afwijzen die de extractor niet kan beschrijven. Zonder verbonden goedkeurder verandert de bestaande fail-closed regel die escalatie in een weigering.
Wat een opdrachtregel wel en niet kan afvangen
Sectie getiteld “Wat een opdrachtregel wel en niet kan afvangen”Een commandPrefix-regel matcht op een woordgrens: git push dekt
git push origin main en niet git pushx. De regel normaliseert de shell
niet. git push (twee spaties), cd sub && git push en
GIT_DIR=… git push zijn allemaal verschillende strings, en geen ervan matcht
een regel over git push.
Dat is een echte beperking, en die wordt benoemd in plaats van verdoezeld:
opdrachtregels zijn een gemak voor de operator om gewoon agentgedrag te sturen,
geen grens tegen een kwaadwillende. De grenzen zijn de effectklassen (die een
hulpmiddel opgeeft en niet anders kan formuleren), het opdrachtnet van de modus
onder de beleidsopslag, en de OS-sandbox onder beide. Een opdrachtregel die op
allow uitkomt, verruimt geen van beide — het modusnet draait daarna en zijn
deny is definitief.
Blijvende goedkeuringen
Sectie getiteld “Blijvende goedkeuringen”Als je een goedkeuringsvraag beantwoordt met “dit onthouden”, wordt er een echte
beleidsregel geschreven: met een bereik (ruimte / agent / werkruimte),
beperkt op argumenten (het goedkeuren van een push naar feature/login
verleent feature/**, niet main) en zelfintrekkend na een expliciete TTL.
Ja zeggen voor de komende uren is iets anders dan stilletjes je permanente
beleid herschrijven, en de regels die het schrijft, belanden in dezelfde opslag
met herkomst remembered en een vervaldatum, zodat ze vroegtijdig kunnen worden
ingetrokken.
Handhavingsniveaus
Sectie getiteld “Handhavingsniveaus”Elke regel heeft er één:
- adviserend — toestaan, maar vastleggen dat de regel matchte. Dit is het invoerpad: zet een strikte regel uit in adviserende modus, lees een week lang het auditspoor om precies te zien wat die zou hebben geblokkeerd, en promoveer hem daarna. Zonder dit niveau worden strikte beleidsregels nooit ingeschakeld.
- soft — weigeren, te overschrijven door iemand met de overschrijvingsmachtiging, met een vastgelegde rechtvaardiging. De overschrijving komt zelf ook in de audit terecht.
- hard (de standaard) — weigeren. Niets overschrijft dit.
De beheerde laag
Sectie getiteld “De beheerde laag”Een installatie-operator kan beleid vastzetten dat geen enkele
werkruimtebeheerder kan versoepelen. Beheerde regels staan aan de serverkant en
worden meest beperkend samengevoegd met de eigen keten van elke werkruimte —
ze zijn geen bereik aan het hoofd ervan, want een beheerde allow aan het hoofd
van de keten zou de installatie een deny van een werkruimte laten overschrijven,
het tegenovergestelde van waar een klem voor dient. Een beheerde regel kan dus
alleen maar strenger maken.
Als je CC_SERVER_MANAGED_POLICY op een JSON-bestand zet, gaat dat volledig
boven de opgeslagen regels, en daardoor kan een operator een houding vastzetten
die geen enkele beheerders-UI kan omzetten — het antwoord op “kan ik voorkomen
dat mijn ontwikkelaars de veiligheidscontroles uitschakelen?”.
De autonomieschakelaar is een profiel, geen parallel systeem
Sectie getiteld “De autonomieschakelaar is een profiel, geen parallel systeem”De autonomieschakelaar per ruimte is een benoemd profiel boven op dezelfde
beleidsopslag, geen tweede mechanisme. De drie standen worden opgeslagen en
verzonden als proposeOnly, actWithApproval en actFreely (de vormen met
koppelstreepjes zijn alleen UI-tekst, en autonomy.setForSpace weigert al het
andere). Laat je hem oningesteld, dan gedraagt hij zich als actWithApproval.
Wat elk van de standen doet met een opgeloste beslissing:
proposeOnlyweigert elk afgeschermd hulpmiddel onmiddellijk. De agent kan nog steeds redeneren en antwoorden; hij kan alleen niet handelen, en zijn bericht zegt waarom.actWithApproval(en oningesteld) is de fail-closed goedkeuringspoort die hierboven is beschreven.actFreelykeurt alles vooraf goed wat niet op een hardedenyis uitgekomen.
Die laatste verdient een onomwonden formulering in plaats van een verzachting:
onder actFreely wordt een prompt-beslissing niet naar een goedkeurder
geëscaleerd — ze wordt toegestaan en er wordt niemand gevraagd. Alleen een
expliciete deny-regel overleeft de schakelaar. actFreely is dus een bewuste
toekenning van autonomie, geen gemaksinstelling, en de fail-closed regel
beschermt precies het geval waarin dat ertoe doet (actWithApproval, de
standaard).
Delegatie tussen agents wordt op het controlepunt delegate_task bewaakt door
alle vier de bewakers: een dieptelimiet (standaard 3), cyclusdetectie, een
autonomieplafond (een gedelegeerde kan nooit met meer autonomie handelen dan
zijn delegator — privileges kunnen niet worden witgewassen door werk aan een
vrijere agent te geven) en een budgetenvelop (delegatie schrijft af op het
resterende budget van de delegator en kan geen nieuw budget aanmaken). Elk wordt
luidruchtig geweigerd, met de reden van de bewaker woordelijk aan de agent
teruggegeven.
De eerlijkheidsmatrix van de adapters
Sectie getiteld “De eerlijkheidsmatrix van de adapters”Niet elke runtime laat Control Center elke actie onderscheppen. Externe agent-CLI’s voeren sommige hulpmiddelen native uit, in-process, waar geen poort kan zitten. In plaats van iets anders voor te wenden, draagt elke adapter een eerlijkheidsmatrix: per adapter of Control Center het toolaanbod filtert, toolaanroepen onderschept, het voltooiingscontract waarneemt, de native hulpmiddelen van de runner kan zien, en of hulpmiddelen in-process door een sandboxprofiel worden gedekt.
Twee vermeldingen zijn het lezen waard voordat je een configuratie vertrouwt. De
ingebouwde harness verklaart dat zijn bestandshulpmiddelen in-process niet in
een sandbox draaien — het toolaanbod en deze beleidsengine zijn de enige
bestandssysteemgrens die hij heeft. Claude Code verklaart dat zijn eigen
toolaanroepen niet te onderscheppen zijn, omdat het wordt gestart met
--dangerously-skip-permissions; Control Center ziet zijn mcp__*-aanroepen en, via een hook, zijn Bash-opdrachtregels, terwijl zijn eigen lees-, schrijf- en bewerkingshulpmiddelen ongezien draaien.
Het instellingenscherm toont deze matrix, want de enige onvergeeflijke fout voor een beveiligingssysteem is dekking claimen die niet bestaat.
Beleid uitproberen voordat het toeslaat
Sectie getiteld “Beleid uitproberen voordat het toeslaat”De beveiligingen vind je onder Instellingen → Werkruimte → Agentmachtigingen
(/workspaces/<id>/settings/workspace/permissions). Het scherm bevat de
beleidsmatrix waarin regels worden geschreven, beleidssjablonen, een
Wat als?-test, het auditspoor van autorisaties en de eerlijkheidsmatrix van de
adapters.
De test neemt een actieklasse (of een opdracht) en een bereik, en toont welke regel heeft beslist en waarom. Omdat resolutie puur en deterministisch is — dezelfde actie, hetzelfde bereik, dezelfde beslissing — is het antwoord van de test het antwoord dat de agent krijgt.
Gerelateerde concepten
Sectie getiteld “Gerelateerde concepten”- Sandbox en beveiliging: wat een agentuitvoering werkelijk begrenst en hoever de OS-ondergrens onder deze engine reikt
- Multiplayer — identiteit, lidmaatschap en aanwezigheid: ruimtes, principalen en waar de autonomieschakelaar zich bevindt
- Beveiligingen configureren: regels schrijven en testen in de praktijk