Barandillas — una sola política para cada acción que muta el estado
Los agentes de Control Center pueden eliminar archivos, hacer push de ramas, publicar pull requests y llamar a API externas. Cada una de esas acciones es un tipo de riesgo distinto y, durante mucho tiempo, solo una de ellas —los comandos de shell— tenía una política. Las barandillas existen para responder de forma uniforme una sola pregunta, para toda acción que muta el estado que un agente pueda realizar, sin importar qué runtime o herramienta la proponga: ¿se permite, requiere una aprobación o se deniega?
Un solo motor, todos los puntos de control
Sección titulada «Un solo motor, todos los puntos de control»Existe exactamente un motor de políticas. Se consulta en cada punto donde una acción puede salir del sistema: el registro de herramientas del arnés integrado, la compuerta del despachador de MCP en el servidor y las mutaciones de operaciones de repositorio. Por eso, una regla escrita una sola vez aplica tanto al runtime integrado como a las CLI de agentes externos: no hay un segundo camino, más silencioso, que la rodee. La antigua política de comandos, limitada a bash, sigue funcionando: una regla puede hacer coincidir un prefijo de comando en lugar de una clase de acción, y ambas formas conviven en el mismo almacén.
El motor no sustituye, sin embargo, al sandbox del sistema operativo, ni el sandbox lo sustituye a él. Responden a preguntas distintas: las barandillas deciden si una llamada que Control Center alcanza a ver puede ocurrir siquiera, mientras que el sandbox delimita hasta dónde puede llegar el proceso resultante. cc_server aplica el sandbox donde el host ofrece un backend, pero Windows no ofrece ninguno y Linux necesita bwrap y socat. En esos hosts, las barandillas son la capa de aplicación más externa en lugar de una política que se apoya sobre un piso, algo que conviene saber cuando decides qué tan permisivo ser.
ActionClass: una taxonomía cerrada a propósito
Sección titulada «ActionClass: una taxonomía cerrada a propósito»Toda herramienta que muta el estado declara cuáles ActionClasses le corresponden, de un conjunto cerrado de trece clases de efecto. Cinco de ellas preguntan de forma predeterminada; el resto permite, y lo que cambia eso es una regla.
| Clase | Valor predeterminado | Qué abarca |
|---|---|---|
fileDelete |
Preguntar primero | Eliminar un archivo (una escritura con forma de borrado, rm) |
gitPush |
Preguntar primero | Hacer push a un remoto de git |
prCreate |
Preguntar primero | Crear una pull request |
prPublish |
Preguntar primero | Publicar una revisión, fusionar una PR |
vendorSyncWrite |
Preguntar primero | Escribir en un proveedor externo de tickets (Linear, Jira, sincronización con GitHub) |
fileWriteOutsideWorktree |
Permitir | Escribir un archivo fuera del worktree aislado |
gitCommit |
Permitir | Crear un commit de git |
networkEgress |
Permitir | Salida a la red (web fetch, HTTP arbitrario) |
secretAccess |
Permitir | Leer un secreto o una credencial |
packageInstall |
Permitir | Instalar un paquete (npm, pip, pub, brew) |
processSpawn |
Permitir | Lanzar un proceso (la shell y todo lo que invoque a la shell) |
workspaceMutation |
Permitir | Mutar la estructura del espacio de trabajo (repos, espacios, agentes) |
enclosureControl |
Permitir | Controlar un recinto (rig): arrancar una VM, enviarle entrada |
Las ocho clases que permiten de forma predeterminada se eligieron bajo el supuesto de que el piso del sandbox se aplica por debajo de ellas. Así ocurre donde el host ofrece un backend, y no ocurre en Windows ni en una máquina Linux a la que le falten bwrap y socat; por eso, si quieres que fileWriteOutsideWorktree o packageInstall tengan compuerta ahí, esa es una regla que tienes que escribir.
El conjunto es cerrado a propósito. Una nueva herramienta que muta el estado y no declara ninguna clase falla la prueba de trinquete, así que la taxonomía solo puede crecer mediante una decisión explícita y argumentada: «la proliferación de taxonomías es la muerte de esta funcionalidad». Trece clases bastan para expresar las políticas que la gente escribe de verdad (nunca hacer push sin preguntar, nunca eliminar fuera de un worktree, permitir siempre las lecturas) y son lo bastante pocas para que la interfaz de ajustes siga siendo comprensible.
Reglas y resolución de ámbitos
Sección titulada «Reglas y resolución de ámbitos»Una regla asigna (scope, ActionClass | command prefix) → allow | prompt | deny. Los ámbitos se anidan de mayor a menor especificidad:
espacio > agente > espacio de trabajo > preajuste del modo > valor predeterminado
La resolución es primero la especificidad: el primer ámbito con una regla coincidente decide, y la resolución se detiene ahí. La opción más restrictiva solo sirve de desempate: entre dos reglas igual de específicas dentro de un mismo ámbito y al combinar las distintas clases que declara una sola acción. Dentro de un ámbito, una regla de comando coincide con el prefijo de comando más largo. Permitir no le gana a denegar en ningún sitio.
Dos decisiones conllevan garantías firmes:
- Solicitudes con denegación por defecto. Una decisión
promptsin ningún aprobador conectado se resuelve como denegada. Una pregunta sin responder nunca es un sí. - Combinación más restrictiva. Una acción que abarca varias clases las combina del modo más restrictivo; cuando varias clases preguntan, una sola confirmación las enumera todas.
No hay, de forma deliberada, ninguna aprobación que persista por turno. Cada llamada de herramienta vuelve a resolver la política desde cero, así que las preguntas repetidas para la misma acción quedan acotadas por el propio «recordar esta decisión» del operador, y no por algo ceñido al turno.
Reglas a nivel de argumentos
Sección titulada «Reglas a nivel de argumentos»Una regla puede restringir los ARGUMENTOS de una acción, no solo su verbo. «Puede hacer push» y «puede hacer push a feature/*» son afirmaciones distintas, y solo la segunda es un control: una compuerta de capacidades que autoriza únicamente el verbo es la forma que hay detrás de la mayoría de los incidentes publicados con agentes.
Una restricción puede nombrar:
- rutas — patrones glob (
repos/**,!**/.env) - refs — referencias de git, con negación
!(['**', '!main']se lee como «cualquier rama excepto main») - hosts — destinos de red, con comodines de subdominio (
*.internal) - comandos — prefijos de comando, que coinciden en un límite de palabra
- techos —
maxCount/maxCents, de modo que «eliminar hasta 50 archivos» sea expresable
Tres propiedades se derivan de mantener la gramática cerrada y sin bucles, y las tres son justamente lo importante: toda regla se expresa como una frase que puedes releer, toda denegación puede nombrar la restricción que coincidió y la política completa se puede enumerar: puedes ver lo que un agente puede hacer antes de que se ejecute.
Tres reglas que importan:
- Una regla con restricciones es más específica que una sin restricciones en el mismo ámbito, así que «denegar el push a
main» gana a «permitir el push» sin que nadie tenga que pensar en el orden. - Una regla restrictiva (denegar / preguntar) se aplica cuando la solicitud toca cualquiera de los valores que nombra; una permisiva (permitir) se aplica solo cuando la solicitud está enteramente dentro de esos valores. Leer ambas de la misma manera dejaría que un agente blanqueara una ruta prohibida colocando una inocente a su lado.
- Una regla que nombra una faceta sobre la que la solicitud no dice nada no se aplica ni se omite: se escala a una aprobación. Omitirla en silencio volvería inerte toda regla de rama protegida frente a una herramienta que no informa su ref; denegar en silencio rechazaría todos los push que el extractor no puede describir. Si no hay ningún aprobador conectado, la regla existente de denegación por defecto convierte esa escalada en una denegación.
Qué puede y qué no puede atrapar una regla de comando
Sección titulada «Qué puede y qué no puede atrapar una regla de comando»Una regla de commandPrefix coincide en un límite de palabra: git push cubre git push origin main y no git pushx. No normaliza la shell. git push (dos espacios), cd sub && git push y GIT_DIR=… git push son cadenas distintas, y ninguna coincide con una regla sobre git push.
Ese es un límite real y se declara en lugar de disimularse: las reglas de comando son una comodidad para el operador que sirve para moldear el comportamiento habitual de un agente, no una frontera contra uno adversarial. Las fronteras son las clases de efecto (que una herramienta declara y no puede reescribir), la red de comandos del modo que hay bajo el almacén de políticas y el sandbox del sistema operativo que hay bajo ambas. Una regla de comando que se resuelve en allow nunca afloja ninguna de las dos: la red del modo se ejecuta después y su deny es definitivo.
Aprobaciones permanentes
Sección titulada «Aprobaciones permanentes»Responder a una solicitud con «recordar esto» escribe una regla de política real: con ámbito (espacio / agente / espacio de trabajo), restringida por argumentos (aprobar un push a feature/login concede feature/**, no main) y autorevocable mediante un TTL explícito. Decir sí durante las próximas horas no es lo mismo que reescribir en silencio tu política permanente, y las reglas que escribe caen en el mismo almacén con procedencia remembered y una fecha de expiración, así que se pueden revocar antes de tiempo.
Niveles de aplicación
Sección titulada «Niveles de aplicación»Cada regla lleva uno:
- orientativa — permite, pero registra que la regla coincidió. Es la vía de adopción: despliega una regla estricta en modo orientativo, lee el registro de auditoría durante una semana para ver exactamente qué habría bloqueado y luego promuévela. Sin este nivel, las políticas estrictas nunca llegan a activarse.
- flexible — deniega, y alguien que tenga el permiso de anulación puede anularlo con una justificación registrada. La anulación es en sí misma un evento auditado.
- estricta (la predeterminada) — deniega. Nada la anula.
El nivel administrado
Sección titulada «El nivel administrado»Un operador de la instalación puede fijar políticas que ningún administrador de espacio de trabajo puede aflojar. Las reglas administradas viven en el servidor y se combinan del modo más restrictivo con la cadena propia de cada espacio de trabajo; no son un ámbito a la cabeza de esa cadena, porque un allow administrado a la cabeza de la cadena dejaría que la instalación anulara la denegación de un espacio de trabajo, que es lo contrario de lo que busca un tope. Por eso una regla administrada solo puede apretar.
Definir CC_SERVER_MANAGED_POLICY con un archivo JSON prevalece por completo sobre las reglas almacenadas, y eso es lo que permite a un operador fijar una postura que ninguna interfaz de administración puede cambiar: la respuesta a «¿puedo impedir que mis desarrolladores desactiven los controles de seguridad?».
El dial de autonomía es un perfil, no un sistema paralelo
Sección titulada «El dial de autonomía es un perfil, no un sistema paralelo»El dial de autonomía por espacio es un perfil con nombre sobre este mismo almacén de políticas, no un segundo mecanismo. Sus tres ajustes se almacenan y se envían como proposeOnly, actWithApproval y actFreely (las formas con guiones son solo texto de la interfaz, y autonomy.setForSpace rechaza cualquier otra cosa). Dejarlo sin definir se comporta como actWithApproval.
Qué hace cada uno con una decisión ya resuelta:
proposeOnlydeniega sin más toda herramienta con compuerta. El agente aún puede razonar y responder; simplemente no puede actuar, y su mensaje dice por qué.actWithApproval(y sin definir) es la compuerta de aprobación con denegación por defecto descrita arriba.actFreelypreaprueba todo lo que no se haya resuelto en undenyestricto.
Ese último merece decirse sin suavizarlo: con actFreely, una decisión prompt no se escala a un aprobador; se permite y no se pregunta a nadie. Solo sobrevive al dial una regla deny explícita. Así que actFreely es una concesión deliberada de autonomía, no un ajuste de comodidad, y la regla de denegación por defecto protege justo el caso en el que importa (actWithApproval, el valor predeterminado).
La delegación entre agentes está protegida en el punto de control de delegate_task por las cuatro salvaguardas: un límite de profundidad (3 de forma predeterminada), detección de ciclos, un techo de autonomía (un delegado nunca puede actuar con más autonomía que su delegador: el privilegio no se puede blanquear pasándole trabajo a un agente más libre) y una envoltura de presupuesto (la delegación carga al presupuesto restante del delegador y no puede acuñar más). Cada una rechaza de forma ruidosa, con el motivo de la salvaguarda devuelto al agente palabra por palabra.
La matriz de honestidad de los adaptadores
Sección titulada «La matriz de honestidad de los adaptadores»No todos los runtimes permiten que Control Center intercepte todas las acciones. Las CLI de agentes externos ejecutan algunas herramientas de forma nativa, dentro de su propio proceso, donde no puede haber ninguna compuerta. En lugar de fingir lo contrario, cada adaptador lleva una matriz de honestidad: por adaptador, si Control Center filtra la superficie de herramientas, intercepta las llamadas de herramientas, observa el contrato de finalización, alcanza a ver las herramientas nativas del ejecutor y si las herramientas en proceso están cubiertas por un perfil de sandbox.
Dos entradas merecen leerse antes de confiar en una configuración. El arnés integrado declara que sus herramientas de archivos en proceso no están en el sandbox: la superficie de herramientas y este motor de políticas son la única frontera de sistema de archivos que tiene. Claude Code declara que sus propias llamadas de herramientas no son interceptables, porque se lanza con --dangerously-skip-permissions; Control Center ve sus llamadas mcp__* y, mediante un hook, sus líneas de comandos de Bash, mientras que sus propias herramientas de lectura, escritura y edición se ejecutan sin que nadie las vea.
La pantalla de ajustes muestra esta matriz, porque el único fallo imperdonable en un sistema de barandillas es declarar una cobertura que no existe.
Sondear la política antes de que te muerda
Sección titulada «Sondear la política antes de que te muerda»Las barandillas viven en Ajustes → Espacio de trabajo → Permisos de agentes (/workspaces/<id>/settings/workspace/permissions). La pantalla tiene la matriz de políticas donde se escriben las reglas, plantillas de políticas, una sonda de «¿qué pasaría si?», el registro de auditoría de autorización y la matriz de honestidad de los adaptadores.
La sonda recibe una clase de acción (o un comando) y un ámbito, y muestra qué regla decidió y por qué. Como la resolución es pura y determinista —misma acción, mismo ámbito, misma decisión—, la respuesta de la sonda es la respuesta que recibirá el agente.
Conceptos relacionados
Sección titulada «Conceptos relacionados»- Sandbox y seguridad: qué limita realmente la ejecución de un agente y hasta dónde llega el piso del sistema operativo que hay bajo este motor
- Multijugador — identidad, pertenencia y presencia: los espacios, los Principal y dónde vive el dial de autonomía
- Configurar barandillas: escribir y probar reglas en la práctica