Περιορισμοί — μία πολιτική για κάθε ενέργεια που αλλάζει κατάσταση
Οι πράκτορες στο Control Center μπορούν να διαγράφουν αρχεία, να κάνουν push σε κλάδους, να δημοσιεύουν pull requests και να καλούν εξωτερικά API. Κάθε μία από αυτές τις ενέργειες αποτελεί διαφορετικό είδος κινδύνου και για μεγάλο διάστημα μόνο μία από αυτές — οι εντολές shell — είχε πολιτική. Οι περιορισμοί υπάρχουν για να απαντούν ομοιόμορφα σε ένα ερώτημα, για κάθε ενέργεια που αλλάζει κατάσταση και μπορεί να κάνει ένας πράκτορας, ανεξάρτητα από το ποιο runtime ή εργαλείο την προτείνει: επιτρέπεται, χρειάζεται έγκριση ή απορρίπτεται;
Μία μηχανή, κάθε σημείο ελέγχου
Ενότητα με τίτλο «Μία μηχανή, κάθε σημείο ελέγχου»Υπάρχει ακριβώς μία μηχανή πολιτικής. Αυτή συμβουλεύεται σε κάθε σημείο όπου μια ενέργεια μπορεί να εξέλθει από το σύστημα: το μητρώο εργαλείων του ενσωματωμένου harness, την πύλη του MCP dispatcher στην πλευρά του διακομιστή και τις μεταβολές repo-op. Ένας κανόνας που γράφεται μία φορά εφαρμόζεται επομένως στο ενσωματωμένο runtime και στα εξωτερικά CLI πρακτόρων το ίδιο — δεν υπάρχει δεύτερη, πιο ήσυχη διαδρομή γύρω του. Η παλαιότερη πολιτική εντολών μόνο για bash λειτουργεί ακόμη: ένας κανόνας μπορεί να ταιριάζει με πρόθεμα εντολής αντί για κλάση ενέργειας και οι δύο μορφές συνυπάρχουν στον ίδιο χώρο αποθήκευσης.
Η μηχανή όμως δεν υποκαθιστά το sandbox του λειτουργικού συστήματος και το
sandbox δεν την υποκαθιστά. Απαντούν σε διαφορετικά ερωτήματα: οι περιορισμοί
αποφασίζουν αν μια κλήση που μπορεί να δει το Control Center επιτρέπεται να
συμβεί καθόλου, ενώ το sandbox περιορίζει το πού μπορεί να φτάσει η διεργασία
που προκύπτει. Το cc_server εφαρμόζει το sandbox όπου το μηχάνημα προσφέρει
υποσύστημα — αλλά τα Windows δεν προσφέρουν κανένα και το Linux χρειάζεται
bwrap και socat. Σε αυτά τα μηχανήματα
οι περιορισμοί είναι το εξώτατο επίπεδο επιβολής και όχι μια πολιτική που
κάθεται πάνω από ένα δάπεδο, κάτι που αξίζει να γνωρίζετε όταν αποφασίζετε πόσο
επιτρεπτικοί να είστε.
ActionClass: μια σκόπιμα κλειστή ταξινομία
Ενότητα με τίτλο «ActionClass: μια σκόπιμα κλειστή ταξινομία»Κάθε εργαλείο που αλλάζει κατάσταση δηλώνει σε ποιες ActionClasses ανήκει, από ένα κλειστό σύνολο δεκατριών κλάσεων επιδράσεων. Πέντε από αυτές ζητούν έγκριση από προεπιλογή· οι υπόλοιπες επιτρέπουν, και ένας κανόνας είναι αυτό που το αλλάζει.
| Κλάση | Ενσωματωμένη προεπιλογή | Τι καλύπτει |
|---|---|---|
fileDelete |
prompt | Διαγραφή αρχείου (εγγραφή με μορφή διαγραφής, rm) |
gitPush |
prompt | Push σε απομακρυσμένο αποθετήριο git |
prCreate |
prompt | Δημιουργία pull request |
prPublish |
prompt | Δημοσίευση αξιολόγησης, συγχώνευση PR |
vendorSyncWrite |
prompt | Εγγραφή σε εξωτερικό σύστημα εισιτηρίων (συγχρονισμός Linear, Jira, GitHub) |
fileWriteOutsideWorktree |
allow | Εγγραφή αρχείου έξω από το απομονωμένο worktree |
gitCommit |
allow | Δημιουργία git commit |
networkEgress |
allow | Έξοδος δικτύου (web fetch, αυθαίρετο HTTP) |
secretAccess |
allow | Ανάγνωση μυστικού ή διαπιστευτηρίου |
packageInstall |
allow | Εγκατάσταση πακέτου (npm, pip, pub, brew) |
processSpawn |
allow | Εκκίνηση διεργασίας (shell και καθετί που καλεί το shell) |
workspaceMutation |
allow | Μεταβολή της δομής χώρου εργασίας (αποθετήρια, χώροι, πράκτορες) |
enclosureControl |
allow | Οδήγηση περιβλήματος (σταθμού): εκκίνηση VM, αποστολή εισόδου |
Οι οκτώ κλάσεις που επιτρέπουν από προεπιλογή επιλέχθηκαν με την παραδοχή ότι
κάτω από αυτές ισχύει το δάπεδο του sandbox. Ισχύει όπου το μηχάνημα προσφέρει
υποσύστημα, αλλά δεν ισχύει στα Windows ή σε ένα μηχάνημα Linux που του λείπει
το bwrap και το socat — οπότε αν θέλετε να τεθούν υπό πύλη εκεί οι
fileWriteOutsideWorktree ή packageInstall, αυτός είναι ένας κανόνας που
πρέπει να γράψετε.
Το σύνολο είναι κλειστό σκόπιμα. Ένα νέο εργαλείο που αλλάζει κατάσταση και δεν δηλώνει κλάση αποτυγχάνει στο ratchet test, οπότε η ταξινομία μπορεί να επεκταθεί μόνο με ρητή, τεκμηριωμένη απόφαση — «η επέκταση της ταξινομίας είναι ο θάνατος αυτής της λειτουργίας». Οι δεκατρείς κλάσεις αρκούν για να εκφράσουν τις πολιτικές που γράφουν πραγματικά οι άνθρωποι (ποτέ push χωρίς ερώτηση, ποτέ διαγραφή έξω από ένα worktree, πάντα να επιτρέπονται οι αναγνώσεις) και είναι αρκετά λίγες ώστε το UI ρυθμίσεων να παραμένει κατανοητό.
Κανόνες και επίλυση εμβέλειας
Ενότητα με τίτλο «Κανόνες και επίλυση εμβέλειας»Ένας κανόνας αντιστοιχίζει (scope, ActionClass | command prefix) → allow | prompt | deny.
Οι εμβέλειες φωλιάζουν από την πιο συγκεκριμένη στην πιο γενική:
χώρος > πράκτορας > χώρος εργασίας > προκαθορισμένο λειτουργίας > ενσωματισμένη προεπιλογή
Η επίλυση είναι πρώτα η ειδικότητα: η πρώτη εμβέλεια με κανόνα που ταιριάζει αποφασίζει και η επίλυση σταματά εκεί. Το πιο περιοριστικό είναι μόνο κριτήριο ισοπαλίας — μεταξύ δύο εξίσου συγκεκριμένων κανόνων μέσα στην ίδια εμβέλεια και κατά τον συνδυασμό των πολλαπλών κλάσεων που δηλώνει μία ενέργεια. Μέσα σε μια εμβέλεια, ένας κανόνας εντολής ταιριάζει με το μεγαλύτερο σε μήκος πρόθεμα εντολής. Το allow δεν υπερισχύει του deny πουθενά.
Δύο αποφάσεις φέρουν σκληρές εγγυήσεις:
- Ερωτήματα έγκρισης με ασφαλή αποτυχία. Ένα
promptχωρίς συνδεδεμένο εγκρίνοντα καταλήγει σε denied. Μια αναπάντητη ερώτηση δεν είναι ποτέ καταφατική. - Συνδυασμός με το πιο περιοριστικό. Μια ενέργεια που απλώνεται σε πολλές κλάσεις τις συνδυάζει με τον πιο περιοριστικό τρόπο· όταν πολλές κλάσεις ζητούν έγκριση, μία επιβεβαίωση τις απαριθμεί όλες.
Σκόπιμα δεν υπάρχει κλείδωμα ανά γύρο. Κάθε κλήση εργαλείου επιλύει ξανά την πολιτική από την αρχή, οπότε η επανάληψη ερωτήσεων για την ίδια ενέργεια περιορίζεται από το δικό «θυμήσου αυτή την απόφαση» του χειριστή και όχι από κάτι που αφορά έναν μόνο γύρο.
Κανόνες σε επίπεδο ορισμάτων
Ενότητα με τίτλο «Κανόνες σε επίπεδο ορισμάτων»Ένας κανόνας μπορεί να περιορίσει τα ΟΡΙΣΜΑΤΑ μιας ενέργειας, όχι μόνο το ρήμα
της. Το «μπορεί να κάνει push» και το «μπορεί να κάνει push στο feature/*»
είναι διαφορετικοί ισχυρισμοί, και μόνο ο δεύτερος αποτελεί έλεγχο — μια πύλη
δυνατοτήτων που εξουσιοδοτεί μόνο το ρήμα είναι το σχήμα πίσω από τα
περισσότερα δημοσιευμένα περιστατικά πρακτόρων.
Ένας περιορισμός μπορεί να ονομάζει:
- διαδρομές — μοτίβα glob (
repos/**,!**/.env) - refs — αναφορές git, με άρνηση
!(['**', '!main']διαβάζεται ως «οποιοσδήποτε κλάδος εκτός από τον main») - κεντρικούς υπολογιστές — προορισμούς δικτύου, με μπαλαντέρ υποτομέων
(
*.internal) - εντολές — προθέματα εντολών, με αντιστοίχιση σε όριο λέξης
- ανώτατα όρια —
maxCount/maxCents, ώστε να εκφράζεται το «διαγραφή έως 50 αρχείων»
Τρεις ιδιότητες προκύπτουν από το ότι η γραμματική μένει κλειστή και χωρίς βρόχους, και οι τρεις είναι το ζητούμενο: κάθε κανόνας αποδίδεται ως πρόταση που μπορείτε να διαβάσετε πίσω, κάθε άρνηση μπορεί να ονομάσει τον περιορισμό που ταίριαξε και ολόκληρη η πολιτική μπορεί να απαριθμηθεί — μπορείτε να δείτε τι επιτρέπεται να κάνει ένας πράκτορας πριν εκτελεστεί.
Τρεις κανόνες που έχουν σημασία:
- Ένας περιορισμένος κανόνας είναι πιο συγκεκριμένος από έναν μη
περιορισμένο στην ίδια εμβέλεια, οπότε το «να απορρίπτεται το push στο
main» υπερισχύει του «να επιτρέπεται το push» χωρίς να χρειάζεται να σκεφτεί κανείς τη σειρά. - Ένας περιοριστικός κανόνας (deny / prompt) εφαρμόζεται όταν το αίτημα αγγίζει οποιαδήποτε τιμή ονομάζει· ένας επιτρεπτικός (allow) εφαρμόζεται μόνο όταν το αίτημα βρίσκεται εξ ολοκλήρου μέσα σε αυτόν. Η ανάγνωση και των δύο με τον ίδιο τρόπο θα επέτρεπε σε έναν πράκτορα να ξεπλύνει μια απαγορευμένη διαδρομή βάζοντας δίπλα της μια αθώα.
- Ένας κανόνας που ονομάζει μια πτυχή για την οποία το αίτημα δεν λέει τίποτα ούτε εφαρμόζεται ούτε παραλείπεται: κλιμακώνεται σε έγκριση. Η σιωπηλή παράλειψη θα καθιστούσε κάθε κανόνα προστατευόμενου κλάδου ανενεργό απέναντι σε ένα εργαλείο που δεν αναφέρει το ref του· η σιωπηλή άρνηση θα απέρριπτε κάθε push που ο εξαγωγέας δεν μπορεί να περιγράψει. Χωρίς συνδεδεμένο εγκρίνοντα, ο υπάρχων κανόνας ασφαλούς αποτυχίας μετατρέπει αυτή την κλιμάκωση σε άρνηση.
Τι μπορεί και τι δεν μπορεί να πιάσει ένας κανόνας εντολής
Ενότητα με τίτλο «Τι μπορεί και τι δεν μπορεί να πιάσει ένας κανόνας εντολής»Ένας κανόνας commandPrefix ταιριάζει σε όριο λέξης: το git push καλύπτει το
git push origin main και όχι το git pushx. Δεν κανονικοποιεί το shell.
Τα git push (δύο κενά), cd sub && git push και GIT_DIR=… git push είναι
όλα διαφορετικές συμβολοσειρές και κανένα τους δεν ταιριάζει με κανόνα για το
git push.
Αυτό είναι ένα πραγματικό όριο και δηλώνεται αντί να συγκαλύπτεται: οι κανόνες
εντολών είναι μια ευκολία του χειριστή για να διαμορφώνει τη συνήθη συμπεριφορά
ενός πράκτορα, όχι ένα όριο απέναντι σε έναν αντιπαλικό. Τα όρια είναι οι
κλάσεις επιδράσεων (τις οποίες ένα εργαλείο δηλώνει και δεν μπορεί να τις
ξαναγράψει με άλλα λόγια), το δίχτυ εντολών της λειτουργίας κάτω από τον χώρο
αποθήκευσης πολιτικών και το sandbox του λειτουργικού συστήματος κάτω από τα
δύο. Ένας κανόνας εντολής που καταλήγει σε allow δεν χαλαρώνει κανένα από τα
δύο — το δίχτυ της λειτουργίας εκτελείται μετά και το deny του είναι τελικό.
Μόνιμες εγκρίσεις
Ενότητα με τίτλο «Μόνιμες εγκρίσεις»Το να απαντήσετε σε ένα αίτημα έγκρισης με «θυμήσου το» γράφει έναν πραγματικό
κανόνα πολιτικής: με εμβέλεια (χώρος / πράκτορας / χώρος εργασίας),
περιορισμένο ως προς τα ορίσματα (η έγκριση ενός push στο feature/login
παρέχει feature/**, όχι main) και αυτοανακαλούμενο με ρητό TTL. Το
«ναι» για τις επόμενες λίγες ώρες δεν είναι το ίδιο με το να ξαναγράψετε
σιωπηλά τη μόνιμη πολιτική σας, και οι κανόνες που γράφει καταλήγουν στον ίδιο
χώρο αποθήκευσης με προέλευση remembered και ημερομηνία λήξης, ώστε να
μπορούν να ανακληθούν νωρίτερα.
Επίπεδα επιβολής
Ενότητα με τίτλο «Επίπεδα επιβολής»Κάθε κανόνας φέρει ένα:
- advisory — επιτρέπει, αλλά καταγράφει ότι ο κανόνας ταίριαξε. Αυτή είναι η διαδρομή υιοθέτησης: κυκλοφορήστε έναν αυστηρό κανόνα σε λειτουργία advisory, διαβάστε το ίχνος ελέγχου για μια εβδομάδα για να δείτε ακριβώς τι θα είχε αποκλείσει και μετά αναβαθμίστε τον. Χωρίς αυτό το επίπεδο, οι αυστηρές πολιτικές δεν ενεργοποιούνται ποτέ.
- soft — αρνείται, με δυνατότητα παράκαμψης από κάποιον που κατέχει την άδεια παράκαμψης, με καταγεγραμμένη αιτιολόγηση. Η παράκαμψη αποτελεί και η ίδια ελεγχόμενο γεγονός.
- hard (η προεπιλογή) — αρνείται. Τίποτα δεν την παρακάμπτει.
Το διαχειριζόμενο επίπεδο
Ενότητα με τίτλο «Το διαχειριζόμενο επίπεδο»Ένας χειριστής της εγκατάστασης μπορεί να καρφιτσώσει πολιτική που κανένας
διαχειριστής χώρου εργασίας δεν μπορεί να χαλαρώσει. Οι διαχειριζόμενοι κανόνες
ζουν στην πλευρά του διακομιστή και συγχωνεύονται με τον πιο περιοριστικό
τρόπο με την αλυσίδα κάθε χώρου εργασίας — δεν είναι εμβέλεια στην κεφαλή
της, επειδή ένα διαχειριζόμενο allow στην κεφαλή της αλυσίδας θα επέτρεπε
στην εγκατάσταση να υπερισχύσει της άρνησης ενός χώρου εργασίας, το αντίθετο
από τον σκοπό ενός φραγμού. Ένας διαχειριζόμενος κανόνας μπορεί επομένως μόνο
να σφίξει.
Ο ορισμός του CC_SERVER_MANAGED_POLICY σε ένα αρχείο JSON υπερισχύει πλήρως
των αποθηκευμένων κανόνων, και αυτό επιτρέπει σε έναν χειριστή να καρφιτσώσει
μια στάση που κανένα UI διαχείρισης δεν μπορεί να ανατρέψει — η απάντηση στο
«μπορώ να εμποδίσω τους προγραμματιστές μου να απενεργοποιούν τους ελέγχους
ασφαλείας;».
Ο δείκτης αυτονομίας είναι προφίλ, όχι παράλληλο σύστημα
Ενότητα με τίτλο «Ο δείκτης αυτονομίας είναι προφίλ, όχι παράλληλο σύστημα»Ο δείκτης αυτονομίας ανά χώρο είναι ένα επώνυμο προφίλ πάνω στον ίδιο χώρο
αποθήκευσης πολιτικών, όχι δεύτερος μηχανισμός. Οι τρεις ρυθμίσεις του
αποθηκεύονται και αποστέλλονται ως proposeOnly, actWithApproval και
actFreely (οι μορφές με παύλες είναι μόνο κείμενο του UI και το
autonomy.setForSpace απορρίπτει οτιδήποτε άλλο). Αν μείνει ανορισμένος,
συμπεριφέρεται ως actWithApproval.
Τι κάνει κάθε ρύθμιση σε μια απόφαση που έχει προκύψει από την επίλυση:
proposeOnlyαρνείται ευθέως κάθε εργαλείο που υπόκειται σε πύλη ελέγχου. Ο πράκτορας μπορεί ακόμη να συλλογιστεί και να απαντήσει· απλώς δεν μπορεί να δράσει και το μήνυμά του εξηγεί γιατί.actWithApproval(και η ανορισμένη τιμή) είναι η πύλη έγκρισης με ασφαλή αποτυχία που περιγράφηκε παραπάνω.actFreelyπροεγκρίνει καθετί που δεν κατέληξε σε σκληρόdeny.
Η τελευταία αξίζει να ειπωθεί ευθέως και όχι μαλακά: υπό το actFreely μια
απόφαση prompt δεν κλιμακώνεται σε εγκρίνοντα — επιτρέπεται και δεν
ρωτιέται κανείς. Μόνο ένας ρητός κανόνας deny επιβιώνει του δείκτη. Άρα το
actFreely είναι μια σκόπιμη παραχώρηση αυτονομίας, όχι μια ρύθμιση ευκολίας,
και ο κανόνας ασφαλούς αποτυχίας προστατεύει ακριβώς την περίπτωση όπου έχει
σημασία (actWithApproval, η προεπιλογή).
Η ανάθεση μεταξύ πρακτόρων φυλάσσεται στο σημείο ελέγχου delegate_task από
και τους τέσσερις φρουρούς: ένα ανώτατο όριο βάθους (προεπιλογή 3), ανίχνευση
κύκλων, ένα ανώτατο όριο αυτονομίας (ένας ανατιθέμενος δεν μπορεί ποτέ να
δράσει με μεγαλύτερη αυτονομία από τον αναθέτοντά του — το προνόμιο δεν μπορεί
να ξεπλυθεί δίνοντας δουλειά σε έναν πιο ελεύθερο πράκτορα) και ένα πλαίσιο
προϋπολογισμού (η ανάθεση χρεώνει τον εναπομείναντα προϋπολογισμό του
αναθέτοντος και δεν μπορεί να κόψει περισσότερο). Κάθε άρνηση είναι ηχηρή, με
την αιτία του φρουρού να επιστρέφεται στον πράκτορα αυτολεξεί.
Ο πίνακας ειλικρίνειας των προσαρμογέων
Ενότητα με τίτλο «Ο πίνακας ειλικρίνειας των προσαρμογέων»Δεν επιτρέπει κάθε runtime στο Control Center να υποκλέψει κάθε ενέργεια. Τα εξωτερικά CLI πρακτόρων εκτελούν ορισμένα εργαλεία εγγενώς, εντός διεργασίας, όπου δεν μπορεί να σταθεί καμία πύλη. Αντί να προσποιείται το αντίθετο, κάθε προσαρμογέας φέρει έναν πίνακα ειλικρίνειας: ανά προσαρμογέα, αν το Control Center φιλτράρει την επιφάνεια εργαλείων, υποκλέπτει κλήσεις εργαλείων, τηρεί το συμβόλαιο ολοκλήρωσης, μπορεί να δει τα εγγενή εργαλεία του εκτελεστή και αν τα εργαλεία εντός διεργασίας καλύπτονται από προφίλ sandbox.
Δύο καταχωρίσεις αξίζει να διαβάσετε προτού εμπιστευτείτε μια διαμόρφωση. Το
ενσωματωμένο harness δηλώνει ότι τα εργαλεία αρχείων του εντός διεργασίας
δεν είναι sandboxed — η επιφάνεια εργαλείων και αυτή η μηχανή πολιτικής
είναι το μόνο όριο συστήματος αρχείων που έχει. Το Claude Code δηλώνει ότι οι
δικές του κλήσεις εργαλείων δεν είναι υποκλέψιμες, επειδή εκκινείται με
--dangerously-skip-permissions; το Control Center βλέπει τις κλήσεις του mcp__* και, μέσω ενός hook, τις γραμμές εντολών Bash του, ενώ τα δικά του εργαλεία read, write και edit εκτελούνται αθέατα.
Η οθόνη ρυθμίσεων εμφανίζει αυτόν τον πίνακα, επειδή η μόνη ασυγχώρητη αποτυχία για ένα σύστημα περιορισμών είναι να διεκδικεί κάλυψη που δεν υπάρχει.
Δοκιμή της πολιτικής πριν δαγκώσει
Ενότητα με τίτλο «Δοκιμή της πολιτικής πριν δαγκώσει»Οι περιορισμοί βρίσκονται στις Ρυθμίσεις → Χώρος εργασίας → Δικαιώματα
πρακτόρων (/workspaces/<id>/settings/workspace/permissions). Η οθόνη
περιλαμβάνει τον πίνακα πολιτικής όπου γράφονται οι κανόνες, πρότυπα πολιτικής,
δοκιμή υποθετικών σεναρίων, το ίχνος ελέγχου εξουσιοδότησης και τον πίνακα
ειλικρίνειας των προσαρμογέων.
Η δοκιμή δέχεται μια κλάση ενέργειας (ή μια εντολή) και μια εμβέλεια και δείχνει ποιος κανόνας αποφάσισε και γιατί. Επειδή η επίλυση είναι καθαρή και ντετερμινιστική — ίδια ενέργεια, ίδια εμβέλεια, ίδια απόφαση — η απάντηση της δοκιμής είναι η απάντηση που θα πάρει ο πράκτορας.
Σχετικές έννοιες
Ενότητα με τίτλο «Σχετικές έννοιες»- Sandbox και ασφάλεια: τι περιορίζει πραγματικά μια εκτέλεση πράκτορα και πόσο μακριά φτάνει το δάπεδο του λειτουργικού συστήματος κάτω από αυτή τη μηχανή
- Συνεργασία — ταυτότητα, συμμετοχή και παρουσία: χώροι, ταυτότητες και πού βρίσκεται ο δείκτης αυτονομίας
- Ρύθμιση περιορισμών: γράφοντας και δοκιμάζοντας κανόνες στην πράξη