İçeriğe geç

Korumalar — her değiştirici eylem için tek ilke

Control Center’daki ajanlar dosya silebilir, dal push edebilir, pull request yayımlayabilir ve harici API’ler çağırabilir. Bunların her biri farklı bir risk türüdür ve uzun süre boyunca yalnızca biri — shell komutları — için bir ilke vardı. Korumalar, bir ajanın gerçekleştirebileceği her değiştirici eylem için, o eylemi hangi çalışma zamanının veya aracın önerdiğinden bağımsız olarak tek bir soruyu aynı biçimde yanıtlamak için vardır: buna izin mi veriliyor, onay mı gerekiyor, yoksa reddediliyor mu?

Tam olarak tek bir ilke motoru vardır. Bir eylemin sistemden çıkabileceği her noktada ona danışılır: yerleşik harness’ın araç kaydı, sunucu tarafındaki MCP dağıtıcı kapısı ve repo-op mutasyonları. Bu yüzden bir kez yazılan kural, hem yerleşik çalışma zamanında hem de harici ajan CLI’larında geçerli olur — etrafından dolaşan ikinci, daha sessiz bir yol yoktur. Eski yalnızca-bash komut ilkesi hâlâ çalışır: bir kural, eylem sınıfı yerine bir komut önekiyle eşleşebilir ve iki biçim aynı depoda bir arada bulunur.

Ne var ki motor, işletim sistemi sandbox’ının yerini tutmaz; sandbox da onun yerini tutmaz. Farklı soruları yanıtlarlar: korumalar, Control Center’ın görebildiği bir çağrının gerçekleşmesine hiç izin verilip verilmediğine karar verir; sandbox ise ortaya çıkan sürecin nerelere erişebileceğini sınırlar. cc_server, ana makine bir arka uç sunduğunda sandbox’ı uygular — ancak Windows hiçbir şey sunmaz ve Linux bwrap ile socat gerektirir. Bu ana makinelerde korumalar, bir tabanın üzerinde oturan bir ilke değil, en dıştaki uygulama katmanıdır; ne kadar izin verici olacağınıza karar verirken bunu bilmek faydalıdır.

ActionClass: bilinçli olarak kapalı bir sınıflandırma

Bölüm başlığı “ActionClass: bilinçli olarak kapalı bir sınıflandırma”

Her değiştirici araç, kapalı bir on üç etki sınıfı kümesinden hangi ActionClass’lara ait olduğunu bildirir. Bunlardan beşi kutudan çıktığı hâliyle sorar; geri kalanı izin verir ve bunu değiştiren şey bir kuraldır.

Sınıf Yerleşik varsayılan Neyi kapsar
fileDelete önce sor Bir dosyayı silme (silme biçimli bir yazma, rm)
gitPush önce sor Uzak bir git deposuna push etme
prCreate önce sor Pull request oluşturma
prPublish önce sor İnceleme yayımlama, PR birleştirme
vendorSyncWrite önce sor Harici bir bilet sağlayıcısına yazma (Linear, Jira, GitHub senkronizasyonu)
fileWriteOutsideWorktree izin ver Yalıtılmış çalışma ağacının dışındaki bir dosyaya yazma
gitCommit izin ver Bir git commit’i oluşturma
networkEgress izin ver Ağa çıkış (web getirme, rastgele HTTP)
secretAccess izin ver Bir secret veya kimlik bilgisi okuma
packageInstall izin ver Paket kurma (npm, pip, pub, brew)
processSpawn izin ver Süreç başlatma (shell ve shell’e çıkan her şey)
workspaceMutation izin ver Çalışma alanı yapısını değiştirme (depolar, alanlar, ajanlar)
enclosureControl izin ver Bir enclosure’ı (rig) yönetme: bir VM başlatma, ona girdi gönderme

Varsayılan olarak izin veren sekiz sınıf, altlarında sandbox tabanının geçerli olduğu varsayımıyla seçildi. Ana makine bir arka uç sunduğunda bu böyledir; Windows’ta ya da bwrap ve socat eksik bir Linux makinesinde ise böyle değildir — dolayısıyla orada fileWriteOutsideWorktree veya packageInstall için bir kapı istiyorsanız, yazmanız gereken bir kural vardır.

Küme bilinçli olarak kapalıdır. Sınıf bildirmeyen yeni bir değiştirici araç ratchet testini geçemez; bu yüzden sınıflandırma ancak açık ve gerekçeli bir kararla büyüyebilir — “sınıflandırmanın şişmesi bu özelliğin sonu demektir.” On üç sınıf, insanların gerçekte yazdığı ilkeleri ifade etmeye yeter (sormadan asla push etme, bir çalışma ağacının dışında asla silme, okumalara her zaman izin ver) ve ayarlar arayüzünün anlaşılır kalmasını sağlayacak kadar da azdır.

Bir kural (scope, ActionClass | command prefix) → allow | prompt | deny eşlemesi yapar. Kapsamlar en özgülden en gene doğru iç içe geçer:

alan > ajan > çalışma alanı > mod ön ayarı > yerleşik varsayılan

Çözümleme önce özgüllük ilkesine göre yapılır: eşleşen bir kurala sahip ilk kapsam kararı verir ve çözümleme orada durur. En kısıtlayıcı olma yalnızca bir eşitlik bozucudur — tek bir kapsam içindeki iki eşit özgüllükte kural arasında ve tek bir eylemin bildirdiği birkaç sınıfı birleştirirken. Bir kapsam içinde komut kuralı en uzun komut önekiyle eşleşir. İzin, hiçbir yerde reddi yenmez.

İki karar katı garanti taşır:

  • Varsayılanı ret olan sorular. Bağlı bir onaylayıcı yokken bir prompt reddedildi olarak çözülür. Yanıtsız bir soru asla evet değildir.
  • En kısıtlayıcı birleşim. Birkaç sınıfa yayılan bir eylem, bunları en kısıtlayıcı biçimde birleştirir; birkaç sınıf sorduğunda tek bir onay hepsini listeler.

Bilinçli olarak tur başına kalıcı bir kilit yoktur. Her araç çağrısı ilkeyi sıfırdan yeniden çözümler; bu yüzden aynı eylem için tekrar tekrar sorulması, tura bağlı herhangi bir şeyle değil, operatörün kendi “bu kararı hatırla” tercihiyle sınırlanır.

Bir kural, bir eylemin yalnızca fiilini değil ARGÜMANLARINI da kısıtlayabilir. “Push edebilir” ile “feature/* dalına push edebilir” farklı iddialardır ve yalnızca ikincisi bir denetimdir — yalnızca fiile yetki veren bir yetenek kapısı, yayımlanmış ajan olaylarının çoğunun arkasındaki biçimdir.

Bir kısıt şunları adlandırabilir:

  • yollar — glob kalıpları (repos/**, !**/.env)
  • ref’ler — git ref’leri, ! olumsuzlamasıyla (['**', '!main'] “main dışındaki her dal” diye okunur)
  • host’lar — alt alan adı joker karakterleriyle ağ hedefleri (*.internal)
  • komutlar — sözcük sınırında eşleşen komut önekleri
  • üst sınırlar — maxCount / maxCents, böylece “en fazla 50 dosya sil” ifade edilebilir

Dilbilgisini kapalı ve döngüsüz tutmanın üç sonucu vardır ve üçü de asıl amaçtır: her kural geri okuyabileceğiniz bir cümle olarak görünür, her ret eşleşen kısıtı adlandırabilir ve ilkenin tamamı numaralandırılabilir — bir ajanın çalışmadan önce neler yapabileceğini görebilirsiniz.

Önem taşıyan üç kural:

  • Kısıtlı bir kural, aynı kapsamda kısıtsız olandan daha özgüldür; bu yüzden “main dalına push etmeyi reddet”, sıralamayı kimse düşünmeden “push etmeye izin ver”i yener.
  • Kısıtlayıcı bir kural (reddet / sor), istek adlandırdığı değerlerden herhangi birine dokunduğunda uygulanır; izin verici bir kural (izin ver) ise yalnızca istek onun tamamen içinde olduğunda uygulanır. İkisini aynı biçimde okumak, bir ajanın yasak bir yolun yanına zararsız bir yol ekleyerek yasağı aklamasına izin verirdi.
  • İsteğin hiçbir şey söylemediği bir yönü adlandıran bir kural ne uygulanır ne atlanır: onaya yükseltir. Sessizce atlamak, korumalı dal kurallarının tamamını ref’ini bildirmeyen bir araca karşı işlevsiz kılardı; sessizce reddetmek, çıkarıcının tanımlayamadığı her push’u geri çevirirdi. Bağlı bir onaylayıcı yokken, mevcut varsayılanı ret olan kural bu yükseltmeyi bir redde dönüştürür.

Bir komut kuralının yakalayabildikleri ve yakalayamadıkları

Bölüm başlığı “Bir komut kuralının yakalayabildikleri ve yakalayamadıkları”

Bir commandPrefix kuralı sözcük sınırında eşleşir: git push ifadesi git push origin main ile eşleşir, git pushx ile eşleşmez. Shell’i normalleştirmez. git push (iki boşluk), cd sub && git push ve GIT_DIR=… git push farklı dizelerdir ve hiçbiri git push hakkındaki bir kuralla eşleşmez.

Bu gerçek bir sınırdır ve üstü örtülmek yerine açıkça söyleniyor: komut kuralları, sıradan ajan davranışını biçimlendirmek için bir operatör kolaylığıdır; düşmanca davranan bir ajana karşı bir sınır değildir. Sınırlar etki sınıflarıdır (bir aracın bildirdiği ve yeniden adlandıramayacağı sınıflar), ilke deposunun altındaki mod komut ağı ve her ikisinin altındaki işletim sistemi sandbox’ıdır. allow olarak çözülen bir komut kuralı bu ikisinden hiçbirini hiçbir zaman gevşetmez — mod ağı sonradan çalışır ve onun deny kararı nihaidir.

Bir soruyu “bunu hatırla” diyerek yanıtlamak gerçek bir ilke kuralı yazar: kapsamlıdır (alan / ajan / çalışma alanı), argümanla kısıtlıdır (feature/login dalına yönelik bir push’u onaylamak maini değil feature/** kalıbını verir) ve açık bir TTL ile kendini iptal eder. Önümüzdeki birkaç saat için evet demek, kalıcı ilkenizi sessizce yeniden yazmakla aynı şey değildir; yazdığı kurallar aynı depoya remembered kaynağı ve bir son kullanma tarihiyle düşer, böylece erkenden iptal edilebilirler.

Her kural birini taşır:

  • tavsiye — izin verir, ancak kuralın eşleştiğini kaydeder. Bu, benimseme yoludur: katı bir kuralı tavsiye kipinde devreye alın, bir hafta boyunca denetim kaydını okuyup tam olarak neyi engelleyeceğini görün, sonra onu yükseltin. Bu kademe olmasaydı katı ilkeler hiçbir zaman etkinleştirilmezdi.
  • yumuşak — reddeder; geçersiz kılma iznine sahip biri tarafından, kayda geçen bir gerekçeyle geçersiz kılınabilir. Geçersiz kılmanın kendisi de denetlenen bir olaydır.
  • katı (varsayılan) — reddeder. Hiçbir şey onu geçersiz kılamaz.

Bir kurulum operatörü, hiçbir çalışma alanı yöneticisinin gevşetemeyeceği bir ilke sabitleyebilir. Yönetilen kurallar sunucu tarafında yaşar ve her çalışma alanının kendi zinciriyle en kısıtlayıcı biçimde birleştirilir — zincirin başındaki bir kapsam değildirler, çünkü zincirin başında yer alan yönetilen bir allow, kurulumun bir çalışma alanının ret kararını geçersiz kılmasına izin verirdi; bu da bir kıskacın var olma amacının tam tersidir. Bu nedenle yönetilen bir kural yalnızca sıkılaştırabilir.

CC_SERVER_MANAGED_POLICY değişkenini bir JSON dosyasına ayarlamak, depolanan kuralları tamamen geçersiz kılar; bir operatörün hiçbir yönetici arayüzünün değiştiremeyeceği bir duruşu sabitlemesini sağlayan şey budur — “geliştiricilerimin güvenlik denetimlerini devre dışı bırakmasını engelleyebilir miyim?” sorusunun yanıtı.

Özerklik kadranı paralel bir sistem değil, bir profildir

Bölüm başlığı “Özerklik kadranı paralel bir sistem değil, bir profildir”

Alan başına özerklik kadranı, ikinci bir mekanizma değil, aynı ilke deposu üzerinde adlandırılmış bir profildir. Üç ayarı proposeOnly, actWithApproval ve actFreely olarak saklanır ve gönderilir (tireli biçimler yalnızca arayüz metnidir ve autonomy.setForSpace başka her şeyi reddeder). Ayar boş bırakılırsa actWithApproval gibi davranır.

Her birinin çözümlenmiş bir karara etkisi:

  • proposeOnly kapıya tabi her aracı doğrudan reddeder. Ajan yine de akıl yürütüp yanıt verebilir; yalnızca harekete geçemez ve mesajı bunun nedenini söyler.
  • actWithApproval (ve ayarın boş bırakılması), yukarıda açıklanan varsayılanı ret olan onay kapısıdır.
  • actFreely, katı bir deny olarak çözülmeyen her şeyi önceden onaylar.

Sonuncusunun yumuşatılmak yerine açıkça söylenmesi gerekir: actFreely altında bir prompt kararı bir onaylayıcıya yükseltilmez — izin verilir ve kimseye sorulmaz. Kadrandan yalnızca açık bir deny kuralı sağ çıkar. Dolayısıyla actFreely bir kolaylık ayarı değil, bilinçli bir özerklik devridir ve varsayılanı ret olan kural tam da önemli olduğu durumu (actWithApproval, varsayılan) korur.

Ajanlar arasındaki devretme, delegate_task kilit noktasında dört korumanın tamamıyla korunur: bir derinlik sınırı (varsayılan 3), döngü algılama, bir özerklik tavanı (devredilen ajan, kendisine devreden ajandan asla daha fazla özerklikle hareket edemez — ayrıcalık, iş daha serbest bir ajana verilerek aklanamaz) ve bir bütçe zarfı (devretme, devredenin kalan bütçesinden düşer ve yeni bütçe yaratamaz). Her biri, korumanın gerekçesi ajana birebir döndürülerek yüksek sesle reddedilir.

Her çalışma zamanı, Control Center’ın her eylemi yakalamasına izin vermez. Harici ajan CLI’ları bazı araçları yerel olarak, süreç içinde çalıştırır; oraya hiçbir kapı yerleşemez. Bunun aksini varsaymak yerine her adaptör bir dürüstlük matrisi taşır: adaptör başına, Control Center’ın araç yüzeyini filtreleyip filtrelemediği, araç çağrılarını yakalayıp yakalamadığı, tamamlanma sözleşmesini gözlemleyip gözlemlediği, çalıştırıcının yerel araçlarını görüp göremediği ve süreç içi araçların bir sandbox profiliyle kapsanıp kapsanmadığı.

Bir yapılandırmaya güvenmeden önce okunmaya değer iki kayıt var. Yerleşik harness, süreç içi dosya araçlarının sandbox’ta çalışmadığını bildirir — sahip olduğu tek dosya sistemi sınırı araç yüzeyi ve bu ilke motorudur. Claude Code, kendi araç çağrılarının yakalanamadığını bildirir; çünkü --dangerously-skip-permissions ile başlatılır. Control Center mcp__* çağrılarını ve bir hook aracılığıyla Bash komut satırlarını görür; kendi read, write ve edit araçları ise görünmeden çalışır.

Ayarlar ekranı bu matrisi gösterir; çünkü bir koruma sistemi için affedilmez tek hata, var olmayan bir kapsamı iddia etmektir.

Korumalar Ayarlar → Çalışma alanı → Ajan izinleri altında yer alır (/workspaces/<id>/settings/workspace/permissions). Ekranda kuralların yazıldığı ilke matrisi, ilke şablonları, bir “ne olur?” sorgusu, yetkilendirme denetim kaydı ve adaptör dürüstlük matrisi bulunur.

Sorgu bir eylem sınıfı (veya bir komut) ile bir kapsam alır ve hangi kuralın karar verdiğini ve nedenini gösterir. Çözümleme saf ve belirlenimci olduğundan — aynı eylem, aynı kapsam, aynı karar — sorgunun yanıtı, ajanın alacağı yanıttır.