Entorno aislado y seguridad
Por qué importa aquí el aislamiento
Sección titulada «Por qué importa aquí el aislamiento»Un agente lee archivos, ejecuta comandos de shell y llama a API externas en tu nombre. El fallo que te importa rara vez es la malicia: es un agente que malinterpreta una ruta y reescribe tu copia de trabajo, o uno que hace push de una rama que aún no habías terminado de revisar. Así que la pregunta que el producto tiene que responder no es «¿es fiable el agente?», sino «cuál es el radio de impacto cuando se equivoca».
Control Center responde a eso por capas, y las capas son independientes a propósito. Si falta una, las demás siguen en pie. Eso importa, porque la capa más externa —el entorno aislado del sistema operativo— es la única condicional: depende de que el host ofrezca un backend, y en Windows ninguno lo hace.
Qué limita realmente a un agente
Sección titulada «Qué limita realmente a un agente»Cinco cosas limitan la ejecución de un agente en cualquier host, haya entorno aislado o no. Ninguna de ellas es una frontera del kernel; todas son reales. Donde el host ofrece un backend, el entorno aislado del sistema operativo se sitúa por encima de ellas, y la sección «Qué añade el entorno aislado y dónde se detiene», más abajo, explica qué cambia eso.
Su propio worktree de copia en escritura. Cada conversación aprovisiona su
propia copia de trabajo de cada repositorio vinculado, clonada mediante copia en
escritura con el binario nativo rift que se incluye en lugar de copiarse byte a
byte, así que el aislamiento es lo bastante barato como para ser la opción
predeterminada. El repositorio registrado que añadiste al espacio de trabajo no
es el directorio en el que trabaja el agente: dos conversaciones que tocan el
mismo repositorio no pueden ver los cambios de la otra y ninguna está editando
tu copia de trabajo.
Merece la pena ser preciso con el nivel de granularidad: el worktree es por
conversación, no por agente. Dos agentes de la misma conversación reciben
directorios de trabajo overlay distintos que comparten el repos/ de esa
conversación —que es justo lo que se busca, ya que colaboran en un mismo
cambio—, mientras que sus directorios privados de agente permanecen separados.
La copia en escritura es el único backend allí donde se distribuye rift: un
sistema de archivos que no puede hacer reflink, o un directorio de datos en un
volumen distinto al del repositorio, hace fallar el aprovisionamiento en lugar
de recurrir a otra cosa. Windows es la excepción: allí no hay backend de copia
en escritura, así que git worktree es el backend, no una degradación
silenciosa.
Confinación de rutas en las herramientas de archivos del arnés integrado.
Las herramientas read, write, edit, apply_patch, search, find y
search_files del arnés resuelven cada ruta contra el directorio de trabajo de
la ejecución más las raíces compartidas —el directorio repos/ de la
conversación, donde viven los worktrees, y el directorio de adjuntos del espacio
cuando existe— y rechazan todo lo que quede fuera. Las rutas absolutas solo se
aceptan si ya estaban dentro. Un enlace simbólico que esté dentro del worktree y
apunte fuera de él también se resuelve y se rechaza. Por eso un agente no puede
usar write sobre ~/.ssh aunque no haya ningún entorno aislado de por medio.
La superficie de herramientas del modo. El modo
de una conversación decide qué herramientas se materializan siquiera para la
ejecución. En los modos de solo lectura (plan, review, orchestrate), las
herramientas que mutan simplemente no están en el registro y la política de
comandos de shell de esos modos deniega sin más todo comando que mute
—git commit, git push, npm install, docker y el resto— en lugar de preguntar
por ellos. Una herramienta que no está presente no se puede invocar, lo que es
una garantía más fuerte que la de una herramienta presente que se somete a
comprobación.
Las barandillas de acciones unificadas. Cada herramienta que muta declara las
clases de efecto que puede producir, y el motor de políticas resuelve cada una
como permitir, preguntar o denegar antes de que se ejecute la llamada. Un
prompt sin ningún aprobador conectado se resuelve como denegado: una
pregunta que nadie puede responder nunca es un sí. Consulta
Barandillas para ver el modelo de
resolución.
Credenciales del bróker y un entorno saneado. Las credenciales se emiten en cada lanzamiento y se revocan cuando termina la ejecución, y el token de GitHub que tiene una ejecución puede leer pero no hacer push; consulta «Los push pasan por Control Center» más abajo. ACP, el
bash del arnés y Claude Code bajo el wrapper nativo reciben un entorno al que
se le han quitado los vectores de inyección del enlazador dinámico y del
intérprete (LD_PRELOAD, DYLD_INSERT_LIBRARIES, NODE_OPTIONS,
GIT_SSH_COMMAND y similares) antes de que arranque el proceso. Claude Code a
través de NoSandboxAdapter hereda el entorno del host.
Dónde se debilitan esos límites
Sección titulada «Dónde se debilitan esos límites»Las herramientas de archivos del arnés se ejecutan en el proceso del servidor,
no en un proceso hijo, así que ningún perfil de entorno aislado podría
limitarlas aunque se aplicara uno: solo bash pasa por el ejecutor de comandos
aislado. Su confinación es la comprobación de rutas descrita antes, de modo que
esa comprobación es estructural en lugar de ser una segunda línea de defensa.
La herramienta bash es el otro punto en el que conviene ser preciso. Sus
comandos se evalúan contra la política de comandos del modo y luego se lanzan
con un entorno saneado y el worktree como directorio de trabajo. Donde existe un
backend, ese lanzamiento va envuelto, así que es el entorno aislado lo que
impide que un comando de shell escriba fuera del worktree; donde no existe
—Windows, o Linux sin bwrap y socat—, la política de comandos es lo único que
separa al comando del resto del disco. En el modo chat, la política deniega
sin contemplaciones una lista fija (escalada de privilegios, destrucción del
sistema y del disco, escape de contenedores y de espacios de nombres) y pregunta
ante mutaciones de estado remoto (git push, gh pr create, publicación e
instalación de paquetes). Todo lo que no está en ninguna de las dos listas se
ejecuta. Los pipelines, las cadenas y los subshells se analizan y cada
subcomando se evalúa por separado, y gana la decisión más restrictiva.
Claude Code, cuando se usa como adaptador, es el caso en el que el entorno
aislado soporta más peso. Control Center lo lanza con
--dangerously-skip-permissions, porque un claude -p no interactivo se
bloquearía indefinidamente en su propia solicitud de aprobación. Sus llamadas de lectura, escritura y edición ocurren dentro de su propio proceso y Control Center nunca las ve. Sus llamadas a Bash se envían, antes de ejecutarse, a un hook del servidor que clasifica la línea de comandos y pregunta a la regla correspondiente, y las herramientas mcp__* que sirve Control Center pasan por el control como siempre. Donde existe un
backend, esas llamadas invisibles siguen ocurriendo dentro del wrapper del
entorno aislado, así que el sistema operativo es la frontera que las rodea.
Donde no existe, no hay ninguna. Cada adaptador lo declara en su matriz de
aplicación; consulta la matriz de honestidad de los adaptadores.
Los push pasan por Control Center
Sección titulada «Los push pasan por Control Center»No hay indicadores de permisos por agente. Si un agente puede crear un commit, hacer push, abrir una pull request, escribir en un rastreador o llegar a la red lo deciden las barandillas —permitir, preguntar primero o denegar—, y las mismas reglas se aplican sea cual sea el adaptador que ejecute al agente.
Un push es la acción que tiene que aguantar incluso frente a un agente que
intenta esquivar una regla, así que se aplica por lo que el agente tiene y no
por lo que ejecuta. Con una GitHub App configurada, una ejecución en un worktree
de GitHub recibe un token de instalación con alcance de repositorio que puede
leer contenido y trabajar con pull requests, pero no hacer push. La
configuración de git de la ejecución reescribe cada URL de push de GitHub
(https://github.com/, git@github.com:, ssh://git@github.com/) hacia la
pasarela de ejecuciones de agentes, un endpoint de loopback en cc_server.
La pasarela lee qué refs actualiza el push, pregunta a la regla Enviar a un
remoto —así que se aplica una regla limitada a ramas, como «denegar los push
a main»— y solo entonces reenvía el push a GitHub con un token de escritura
que acuña para ese fin y que nunca entrega al agente. Un push rechazado aparece
en la propia salida de git:
! [remote rejected] main -> main (Control Center policy: …)La pasarela solo reenvía push al repositorio propio del worktree o a un repositorio de GitHub vinculado al espacio de trabajo. Los fetch van directamente a GitHub con el token de lectura.
Los demás comandos de shell encuentran una puerta más blanda. La herramienta
bash del arnés y, mediante un hook, la herramienta Bash de Claude Code
clasifican cada línea de comandos y preguntan a la regla que le corresponde:
git commit, merge, rebase, cherry-pick, revert y am son Crear un
commit; gh pr create es Abrir una pull request; gh pr merge,
review, comment y close son Publicar una revisión o fusionar;
gh issue create, edit, comment y close son Escribir en un rastreador
externo; las instalaciones de paquetes son Instalar un paquete; curl y
wget son Acceder a la red. Esto reconoce la forma habitual de escribir una
acción, y un agente decidido a ocultarla (eval, un archivo de script, una
llamada directa a la API) puede hacerlo. Los push no dependen de ello.
En un entorno aislado no se coloca ninguna clave de API de tickets. Los agentes escriben tickets con las herramientas MCP de Control Center, que preguntan a Escribir en un rastreador externo.
La regla Acceder a la red se lee una sola vez, cuando arranca la ejecución.
La red de un entorno aislado está activada o desactivada, así que denegar la
desactiva, mientras que permitir y preguntar primero la dejan activada; las
herramientas web_fetch y web_search del arnés siguen preguntando en cada
llamada. Las credenciales se revocan cuando la ejecución se desmonta, junto con
cualquier token de escritura que haya acuñado la pasarela, así que un
identificador no sobrevive a la ejecución.
Qué añade el entorno aislado y dónde se detiene
Sección titulada «Qué añade el entorno aislado y dónde se detiene»La enumeración SandboxBackend tiene tres valores: native (Seatbelt en macOS,
bubblewrap en Linux y WSL2), none y microvm. El envoltorio de comandos de
agentes solo usa los dos primeros: microvm es el backend de VM aislada para
terminales interactivos y rigs, no una mejora silenciosa de un envoltorio de
bash. Entender la forma nativa explica qué ganas allí donde se aplica y qué
nunca te iba a dar.
cc_server sondea el host una vez al arrancar y, donde un backend responde,
alimenta los dos puntos de enganche que tiene la ruta de despacho, porque los
transportes no comparten uno solo. El primero (SandboxPort) envuelve la CLI de
Claude Code. El segundo (SandboxManager) envuelve los adaptadores ACP y la
herramienta bash del arnés integrado. Alimentar solo uno dejaría a los demás
lanzando sin envoltorio, que es lo que solía ocurrir. En un host sin backend, o
con --sandbox off, todos lanzan sin envoltorio y el servidor indica en qué caso
estás en su línea de arranque. ACP y el bash del arnés siguen saneando el
entorno; Claude Code a través de NoSandboxAdapter hereda el entorno del host.
Una superficie se queda deliberadamente al margen: el terminal alojado en el
servidor acepta un argumento de backend por sesión y cc_server lo construye con
el shell del host como valor predeterminado, así que un terminal que abras desde
la aplicación se ejecuta sin entorno aislado a menos que un cliente indique
native de forma explícita. Es un shell real en el host del servidor, no una
ejecución de agente.
En Linux, bubblewrap crea un espacio de nombres de montaje, así que el agente
ve realmente solo lo que se ha montado dentro de él. En macOS, sandbox-exec
aplica un perfil de Seatbelt que es permisivo de forma predeterminada: un
perfil totalmente denegado por defecto hace que un shell interactivo sea
inutilizable, porque el número de llamadas dyld, XPC y Mach que habría que
enumerar es impracticable. Por eso el perfil de macOS parte de (allow default)
y recorta denegaciones: lecturas de rutas secretas, una política de escritura
reajustada a denegar con permisos explícitos por encima, bloqueo de unlink en
cada ruta denegada y sus ancestros para que un rename no pueda eludir una
denegación de escritura, denegaciones de exec para binarios siempre peligrosos y
para cualquier cosa copiada a un directorio con permiso de escritura, y red
restringida a los puertos del proxy de loopback más DNS.
La consecuencia práctica: en Linux se estrecha la visión que el agente tiene del sistema de archivos; en macOS el agente todavía puede leer buena parte del host, y tus copias de trabajo registradas están protegidas por denegaciones explícitas de escritura y de renombrado en lugar de por invisibilidad. En ambos casos se trata de aislamiento a nivel de espacios de nombres, no de una frontera de seguridad del kernel; los propios backends lo dicen en sus notas de capacidades.
El conjunto de montajes bind es donde se traza la frontera entre agentes. El
despacho con overlay (Claude Code y ACP) monta hasta cuatro rutas, resueltas por
ejecución: el directorio de trabajo overlay del agente en lectura y escritura, el
directorio de configuración del agente en solo lectura, el directorio repos/
compartido de la conversación en lectura y escritura cuando existe, y el
directorio de adjuntos del espacio en solo lectura cuando existe. El directorio
de un agente hermano nunca se monta. El envoltorio de bash del arnés es más
estrecho: solo monta con bind el directorio de trabajo de la ejecución. Esta es
la misma forma que la comprobación de rutas en proceso del arnés aplica por
software, así que ambas coinciden, pero solo la comprobación de rutas cubre las
herramientas de archivos del propio arnés, que nunca llegan a un espacio de
nombres de montaje.
Tus copias de trabajo registradas se suman además al conjunto de denegación de
escritura, en todos los modos y en las tres rutas envueltas (Claude Code, ACP, el
bash del arnés), y cada regla se emite tanto en su forma literal como en su
forma resuelta por enlaces simbólicos. La segunda forma no es una sutileza: el
kernel compara una regla de denegación con la ruta resuelta, y macOS hace que la
resolución sea el caso habitual y no el exótico —/tmp en realidad es
/private/tmp, /var/folders/… en realidad es /private/var/folders/…—, así
que una copia de trabajo a la que se llegara por cualquiera de las dos vías
habría sido escribible mientras el perfil parecía prohibirlo.
La red, bajo un entorno aislado, es una lista de permitidos de dominios por
sesión que aplican los proxies de loopback en proceso. La salida es de denegación
predeterminada: con la red desactivada, los proxies siguen arrancando, pero su
lista de permitidos está vacía, así que se rechaza toda conexión saliente. Con
ella activada, el resolutor construye la lista de permitidos a partir de una
línea base curada —proveedores de API de LLM, alojamiento de git, registros de
paquetes, el catálogo de modelos— más los dominios de GitHub, y compara el host
de destino de cada conexión con esa lista. Los comodines funcionan
(*.example.com coincide con subdominios, no con el dominio raíz). Una lista
aparte de siempre denegados prevalece sobre la lista de permitidos y cubre los
endpoints de metadatos de la nube y los sumideros de telemetría. Lo que no es
configurable es la propia lista: la especificación incluye un campo
egressAllowlist para dominios adicionales, pero nada en la ruta de despacho
lo rellena, así que en la práctica cada ejecución recibe la línea base más
GitHub, y nada más.
En macOS, las denegaciones son observables: un monitor intercepta el registro del
sistema en busca de denegaciones de Sandbox, filtra el ruido conocido, deduplica
las tormentas de reintentos y expone cada una como un SandboxViolation que indica qué se intentó y qué se bloqueó. En Linux, la ruta del
envoltorio analiza stderr en busca de EPERM, Operation not permitted y
Permission denied, y emite el mismo tipo de evento: no hay interceptación del
registro del sistema. Todos ellos llegan al flujo de eventos de la propia
ejecución, así que una llamada al sistema denegada aparece en la transcripción y
no solo en un registro. La telemetría solo existe mientras un entorno aislado
nativo está envolviendo realmente el proceso; en un host sin backend no hay nada
que observar. Tampoco tiene relación con las barandillas: una violación proviene de una llamada al sistema denegada, nunca de una consulta de regla.
Las confirmaciones vienen de las barandillas, no del entorno aislado
Sección titulada «Las confirmaciones vienen de las barandillas, no del entorno aislado»El entorno aislado no tiene ninguna vía de aprobación. Lanza, ejecuta, emite eventos y se desmonta; no hay ningún sitio en él donde una persona pueda responder a una pregunta. Cuando ves una confirmación en un espacio —aprobar este push, aprobar este borrado—, la ha planteado el motor de barandillas (o la política de comandos del arnés) antes de que la acción llegara siquiera al runtime.
Este orden es deliberado. Una aprobación posterior a la llamada al sistema sería un registro de auditoría, no un control. También es la razón de que la regla de fallo cerrado resida en las barandillas: sin ningún aprobador conectado, la decisión se toma antes de que se ejecute nada y es una denegación.
Diagnóstico
Sección titulada «Diagnóstico»Diagnosticar un agente es el único sitio donde se indica qué se puede comprobar a mano.
Conceptos relacionados
Sección titulada «Conceptos relacionados»- Rigs y recintos: el escalón por encima del entorno aislado, para cuando el trabajo necesita una máquina desechable entera con una frontera de kernel, y no un proceso envuelto
- Barandillas: la capa de políticas por encima de la base del sistema operativo y el origen real de las aprobaciones
- Ciclo de vida del despacho de agentes: dónde encaja el aislamiento en el flujo de despacho
- Modos: cómo un modo estrecha la superficie de herramientas y la política de comandos
- Backends del entorno aislado: los backends y su configuración
Guías relacionadas
Sección titulada «Guías relacionadas»- Configurar políticas del entorno aislado: reglas de acciones, aplicación de los push y postura del sistema de archivos
- Diagnosticar un agente: qué cubren las comprobaciones de diagnóstico