Guías gratuitas Agentes

Claude CodeAgentesEmpezar

El truco de seguridad de Claude Code

¿Te da miedo dejarlo correr solo? Arma una lista de permitidos y una de prohibidos. Tienes la velocidad del piloto automático con límites que no puede cruzar, porque las reglas de prohibición le ganan a todo.

El miedo es razonable. Le das a un agente acceso a tu terminal y a tus archivos, y en algún momento vas a estar en otra pestaña mientras corre algo que no leíste. La reacción normal es una de dos: aprobar cada paso a mano —y perder toda la velocidad— o apagar los avisos y rezar.

Hay un tercer camino y es el que usa la gente que de verdad deja a Claude Code trabajando: escribir una lista de lo que puede hacer sin preguntar y otra de lo que no puede hacer nunca. La velocidad del piloto automático, con paredes.

Lo que hace que esto funcione y no sea un placebo es una regla del sistema: las prohibiciones le ganan a todo. No es una recomendación al modelo, es el programa el que bloquea.

Cómo se decide cada acción

Hay tres listas y se evalúan siempre en el mismo orden: primero deny, luego ask, luego allow. Gana la primera que coincida, y qué tan específica sea la regla no cambia el orden.

La consecuencia práctica importa mucho: una prohibición amplia como Bash(aws *) bloquea todo lo que coincida, incluso si tienes un permiso más fino como Bash(aws s3 ls). Una regla de prohibición no admite excepciones adentro. Si quieres permitir un pedazo, no lo prohíbas entero.

Y algo que conviene tener claro antes de empezar: estas reglas las impone Claude Code, no el modelo. Lo que escribas en tu CLAUDE.md orienta lo que Claude intenta hacer, pero no es un límite. El límite son estas listas.

Dónde se escriben

En un archivo de configuración, bajo la llave permissions. El del proyecto vive en .claude/settings.json y se puede subir al repositorio para que todo el equipo lo herede; el tuyo personal, en ~/.claude/settings.json.

Para verlas y editarlas sin abrir el archivo está el comando /permissions, que además te dice de qué archivo viene cada regla. Y cuando apruebas algo con "sí, no vuelvas a preguntar", la regla se guarda sola en .claude/settings.local.json.

La sintaxis, en cinco reglas

La lista de prohibidos que le pongo a cualquier proyecto

Esta es la base. No depende del lenguaje ni del tipo de trabajo.

{
  "permissions": {
    "deny": [
      "Read(.env)",
      "Read(**/.env.*)",
      "Read(~/.ssh/**)",
      "Read(**/credentials/**)",
      "Edit(**/.git/**)",
      "Bash(git push *)",
      "Bash(rm -rf *)",
      "Bash(curl *)",
      "Bash(wget *)"
    ],
    "ask": [
      "Bash(git commit *)",
      "Bash(npm publish *)"
    ],
    "allow": [
      "Bash(npm run test *)",
      "Bash(npm run build)",
      "Bash(git diff *)",
      "Edit(src/**)",
      "WebFetch(domain:claude.com)"
    ]
  }
}

Dos decisiones de ahí valen explicación.

Por qué prohibir curl y wget. Tratar de restringir una URL desde una regla de Bash no funciona: se rompe con las opciones antes de la dirección, con https en vez de http, con un redireccionamiento, con la URL guardada en una variable. La forma que sí sostiene es cerrar las herramientas de red de la terminal y dejar que las descargas pasen por WebFetch, que sí filtra por dominio: WebFetch(domain:claude.com) permite ese sitio, WebFetch(domain:*.tuempresa.com) permite subdominios.

Por qué ask y no deny en los commits. Prohibir un commit es molesto y termina en que lo desactivas. Ponerlo en ask te da un momento de revisión sin bloquear el flujo. La lista de en medio es la que la mayoría no usa y es la más útil.

El paso que todo mundo se salta: entender hasta dónde llegan estas reglas. Las prohibiciones de lectura y edición cubren las herramientas de archivo de Claude y los comandos de terminal que sabe reconocer, como cat, head o sed. No cubren un subproceso que abre archivos por su cuenta: si Claude escribe un script de Python que lee tu .env y lo corre, la regla de Read no lo detiene. Para un límite que aplique a todos los procesos, lo que necesitas es el modo de aislamiento del sistema, no la lista de permisos.

El detalle que salva

Claude Code entiende los operadores del shell. Una regla como Bash(comando-seguro *) no autoriza comando-seguro && otro-comando: cada parte de un comando compuesto tiene que coincidir por su cuenta con alguna regla, y los separadores que reconoce incluyen &&, ||, ; y las tuberías.

Donde sí hay que tener cuidado es con los ejecutores de entorno. docker exec, npx y compañía corren lo que venga después, así que un permiso de la forma Bash(loquesea run *) autoriza cualquier cosa que siga. Si quieres permitir trabajo dentro de uno de esos, escribe la regla con el comando interno incluido, uno por cada cosa que quieras permitir.

Cómo lo armo en la práctica

No te sientes a escribir cuarenta reglas hoy. El camino que funciona es al revés: pega la lista de prohibidos de arriba en tu .claude/settings.json y trabaja normal durante una semana aprobando a mano. Cada vez que apruebes el mismo comando por tercera vez, muévelo a allow. En dos semanas tienes una lista hecha con tus datos reales, no con los que imaginaste.

El error que veo seguido es el opuesto: alguien se emociona, permite Bash completo para dejar de ver avisos, y se queda sin ninguna pared. Si vas a permitir todo, al menos deja la lista de prohibidos puesta —es lo único que sigue aplicando aunque el resto esté abierto. Para el siguiente paso, dejarlo trabajando solo con esas paredes ya puestas, sigue con deja de ser niñera de Claude.

Una guía nueva cada semana

Sistemas de IA que ya están corriendo en operaciones reales, explicados paso a paso. Sin relleno y sin teoría.

Se cancela con un clic. Tu correo no se comparte con nadie.