Cómo se instala
Qué confina el Nivel 1, qué no cubre y cuándo hace falta el Nivel 2 (contenedor).
# Aislamiento del entorno de IA (referencia para Claude Code)
Confina el asistente al repositorio del proyecto: lectura/escritura acotadas a la carpeta y red
*default-deny*. Es el **Nivel 1** (baseline) de la disciplina de
[operations.md](../../methodology/operations.md) → *Aislamiento del entorno de IA*. Para el
**Nivel 2** (contenedor, autonomía total o código no confiable), usa el devcontainer oficial de
Anthropic: <https://code.claude.com/docs/en/devcontainer.md> — en vez de mantener una imagen
propia que envejece.
| Archivo | Qué es |
|---|---|
| [`settings.json`](settings.json) | Línea base de seguridad del proyecto — **se versiona** |
| [`settings.local.json`](settings.local.json) | Lo específico de tu máquina — **no se versiona** |
| [`SETTINGS.md`](SETTINGS.md) | La guía: qué hace cada clave, cómo se reparten los dos archivos y los **errores reales** de configuración con su arreglo |
| [`gitignore.template`](gitignore.template) | El `.gitignore` de partida (`F0.3`): lo que **no entra al historial** — `initial-references/`, `.env`, volcados de BD |
## Por qué dos capas
Por defecto Claude Code **escribe** solo en la carpeta del proyecto, pero **lee** casi todo el
equipo —incluidos `~/.ssh/` y `~/.aws/credentials`—. El confinamiento real necesita dos capas
complementarias:
- **Sandbox de SO** (sistema operativo) (`sandbox.*`): aísla los **comandos de shell** (en Linux, vía `bubblewrap` +
`socat`).
- **Reglas de permisos** (`permissions.deny`): cubren las herramientas internas
**Read/Edit/Write**, que **no** pasan por el sandbox.
Sin las reglas, un `Read` interno fuera del proyecto se salta el sandbox; sin el sandbox, un
`cat` por shell se salta las reglas. Por eso van las dos.
## Uso
1. Copia `settings.json` a `.claude/settings.json` **en la raíz de tu proyecto** (no en
`~/.claude/`: el `.` de `allowRead` solo se resuelve a la raíz del proyecto cuando el archivo
vive en los settings del proyecto). Este archivo **se commitea**: quien clone hereda el
aislamiento.
2. Copia `settings.local.json` a `.claude/settings.local.json`. Ahí va lo que solo vale en tu
máquina —toolchains con ruta absoluta, `additionalDirectories`, dominios propios—. Las listas
de los dos archivos **se suman**: el local agrega, no reemplaza. Ese archivo no se versiona:
ya viene en el `gitignore.template`, que se copia a `.gitignore` en el mismo paso.
3. En Linux instala las dependencias del sandbox: `bubblewrap` y `socat`.
4. Lanza Claude **siempre desde la carpeta del proyecto**, nunca desde tu home.
5. Reinicia la sesión y verifica en **dos pasos**, porque mirar la config no basta:
- **Config resuelta:** `/sandbox` (pestañas *Mode* / *Overrides* / *Config*) muestra qué
lecturas y escrituras quedaron permitidas y avisa de los patrones ignorados.
- **Prueba empírica:** pide leer una **ruta denegada** —por ejemplo `/etc/hostname`— con la
herramienta de lectura. Debe quedar **bloqueada sin preguntar**. Si se lee, o si aparece un
prompt de aprobación, la regla está mal anclada: lleva una sola barra en vez de `//`
(ver [`SETTINGS.md`](SETTINGS.md) → *Anclaje de rutas*). Repite con un `cat` a la misma
ruta: ahí el bloqueo lo pone el sandbox.
El reparto entre los dos archivos, clave por clave, está en [`SETTINGS.md`](SETTINGS.md).
## Notas
- `failIfUnavailable: true` hace que Claude **no arranque** si el sandbox no está disponible, en
vez de caer en silencio a modo sin aislamiento.
- `allowUnsandboxedCommands: false` cierra el escape de reintentar un comando fuera del sandbox.
- `permissions.defaultMode: "default"` deja la sesión en **modo manual**: lo que ninguna regla
resuelve se pregunta al humano en vez de aprobarlo un clasificador. Las reglas `deny` bloquean
igual en los dos modos; el modo solo gobierna esa zona gris.
- Los `deny` de rutas de sistema se escriben con **doble barra** (`Read(//etc/**)`): una sola
barra ancla la regla en la raíz del proyecto, no en el disco.
- `network.allowedDomains` arranca **vacío** (sin red para los comandos). Los dominios que
necesite el proyecto van en la base; los tuyos, en el local. No afecta a las llamadas del modelo
ni a `WebFetch`/`WebSearch`. (`WebFetch` sí se ve afectado por otra vía: el `deny` de
`~/.claude` tapa donde se guardan sus salidas grandes — ver [`SETTINGS.md`](SETTINGS.md) §2.)
- Para denegar específicamente archivos de credenciales (además de `denyRead`) existe
`sandbox.credentials.files`.
- Límite honesto: el filtrado de red **no inspecciona TLS** (Transport Layer Security) (dominios amplios dejan margen de
exfiltración) y el aislamiento es respecto al **host**, no al propio proyecto: un `.env` o
credenciales dentro de la carpeta montada siguen siendo visibles. No dejes secretos ahí.
> El schema `sandbox.*` es config específica de Claude Code y puede cambiar; verifica el vigente
> en la doc oficial: <https://code.claude.com/docs/en/sandboxing.md>.