Reglas deny en Claude Code: el archivo que evita un borrado
· 6 min de lectura
Las reglas deny de Claude Code son prohibiciones que escribes en la sección permissions de settings.json, como Bash(rm *) o Read(./.env). Las hace cumplir Claude Code, no el modelo: se evalúan antes que ask y allow, bloquean en todos los modos, incluido bypassPermissions, y ninguna regla allow más específica les abre una excepción.
Según la telemetría de Anthropic, los usuarios de Claude Code aprobaban alrededor del 93 % de las solicitudes de permiso. Le pusieron nombre: fatiga de aprobación. Mientras más te pregunta, menos lees lo que estás aprobando. Lo publicó en su blog de ingeniería, al explicar por qué construyó un aislamiento a nivel de sistema operativo: con él, las solicitudes de permiso bajaron un 84 %. Menos preguntas, más atención en las que quedan. Con ese dato empieza el video. Esta es la versión para leer, con los pasos en orden y los límites.
¿Por qué escribir «no borres nada» en CLAUDE.md no te protege?
En el video cuento tres casos de agentes que borraron datos. Míralos por el patrón, no por el chisme:
- Un usuario en Reddit probaba Claude Code por primera vez y a los 10 minutos el agente había borrado la base de datos de su proyecto. Él mismo aclaró que el comando destructivo lo había sugerido el modelo y que lo dejó correr.
- El fundador de una plataforma educativa contó en su blog cómo un comando de destrucción de infraestructura se llevó la base de datos, la red, los balanceadores y los snapshots: dos años y medio de datos de estudiantes. El modelo había advertido en contra de esa configuración y él avanzó igual.
- Una startup vio cómo el agente encontraba un token que servía para todos los ambientes y lo usaba para arreglar algo por su cuenta. Borró el volumen de producción, y los respaldos vivían dentro del mismo volumen.
En ninguno el modelo se volvió loco. En los tres el agente tenía permiso técnico para ejecutar algo destructivo y nadie se lo había quitado. La documentación oficial de Claude Code lo resume en dos frases: las reglas de permiso las hace cumplir Claude Code, no el modelo, y las instrucciones de tu prompt o de CLAUDE.md moldean lo que Claude intenta hacer, pero no cambian lo que Claude Code permite. Escribir «nunca borres archivos» en mayúsculas es pedirle a alguien que no entre a una habitación. Una regla deny es ponerle llave a la puerta.
Este sistema es el que enseño dentro de la comunidad MÁQUINA IA: las estaciones, los gates y el código que lo sostiene.
¿En qué orden decide Claude Code entre allow, ask y deny?
El sistema de permisos tiene tres tipos de reglas:
- Allow: Claude Code usa la herramienta sin pedirte aprobación.
- Ask: te pide confirmación cada vez que intenta usarla.
- Deny: no la deja usar.
Las reglas se evalúan en un orden fijo: primero deny, después ask y al final allow. La primera coincidencia en ese orden decide, y que una regla sea más específica no cambia nada. La documentación lo ilustra así: una regla deny amplia como Bash(aws *) bloquea también las llamadas que coinciden con una allow más estrecha como Bash(aws s3 ls). Una regla deny no admite excepciones. Hay un segundo detalle para quien arranca con --dangerously-skip-permissions, que equivale al modo bypassPermissions. Las reglas deny de Claude Code bloquean en todos los modos, incluido bypassPermissions, mientras que las allow ahí no tienen efecto. La misma documentación advierte que ese modo solo se use en entornos aislados, como contenedores o máquinas virtuales, donde Claude Code no pueda dañar tu equipo. Queda un freno de emergencia: un rm o rmdir dirigido a una ruta crítica, como la raíz del disco o tu carpeta personal, te pide aprobación incluso en bypassPermissions. Sirve de red, no de plan.
¿Qué líneas pongo en settings.json y dónde va el archivo?
Las reglas viven en la sección permissions de un archivo JSON. Tienes tres sitios donde ponerlas:
- ~/.claude/settings.json: tus ajustes de usuario, valen en todos tus proyectos.
- .claude/settings.json: el del proyecto, el que se sube al repositorio y comparte todo el equipo.
- .claude/settings.local.json: el tuyo dentro del proyecto, el que se llena solo cada vez que eliges «Yes, and don't ask again».
Un ejemplo mínimo de la sección deny, con reglas que salen literales de la documentación:
- {
- "permissions": {
- "deny": [
- "Bash(rm *)",
- "Bash(git push *)",
- "Read(./.env)"
- ]
- }
- }
Bash(rm *) bloquea los borrados con rm. Read(./.env) impide que las herramientas de archivos de Claude lean tu .env, que es donde suelen vivir tus claves, y según la documentación también bloquea Edit y Write sobre esa misma ruta. Tres detalles de sintaxis:
- El espacio antes del asterisco es parte de la regla. Bash(ls *) exige un espacio después de ls, así que no toca lsof. Bash(ls*), sin espacio, sí lo toca. Con rm pasa igual: sin espacio atrapas también rmdir y cualquier comando que empiece por esas letras.
- No escribas el nombre del parámetro. Una regla como Bash(command:rm *) se podría esquivar con un comando compuesto, así que Claude Code la ignora y te avisa al arrancar.
- Prohibir la herramienta entera la borra del contexto. Una regla deny con el nombre solo, como Bash, quita la herramienta del contexto de Claude: no la ve. Una regla con patrón la deja disponible y bloquea solo lo que coincide.
¿Qué no te cubre una regla deny?
Esto no te vuelve invencible, y la propia documentación lo aclara. Una regla de Bash compara el texto del comando que escribe Claude, no el programa. Bash(rm *) detiene rm -rf build/, pero no /bin/rm -rf build/ ni bash -c 'rm -rf build/'. Cubre la forma habitual del comando; no es una frontera de seguridad alrededor del programa. Para una protección que no dependa del texto, la documentación remite al sandboxing y a los hooks PreToolUse. Tampoco te tapa el error de configuración, el token con más alcance del que debía tener ni el respaldo guardado en el mismo sitio que lo que respalda. En el caso de la plataforma educativa, lo que salvó los datos no fue una regla de permiso: fue un respaldo interno de Amazon que ni siquiera aparecía en el panel de control. La regla deny es el cinturón y el respaldo separado es el airbag. Se usan los dos y ninguno reemplaza al otro.
¿Por dónde empiezo hoy?
- Antes de dejar trabajar solo a un agente, contesta una pregunta: qué es lo peor que podría borrar si se equivoca de la peor forma posible en ese directorio.
- Escribe esa respuesta como regla deny en ~/.claude/settings.json si vale para todos tus proyectos, o en .claude/settings.json si es de uno solo.
- Añade Read(./.env) si ese proyecto guarda claves en ese archivo.
- Revisa la sintaxis: espacio antes del asterisco y nada de command: dentro del paréntesis.
- Arranca Claude Code, lee los avisos de inicio y pídele que intente el comando prohibido en una carpeta de prueba para comprobar que la regla bloquea de verdad.
Si llevas meses usando Claude Code, tu archivo también acumula reglas allow que no recuerdas haber aprobado. Conté las mías en ninodirector.com/articulos/abri-el-archivo-de-permisos-de-claude-code, y el procedimiento para auditarlas paso a paso está en maquina-ia.com/articulos/auditar-permisos-claude-code. No se trata de desconfiar del modelo, sino de poder: a nadie se le da permiso para borrar porque prometa portarse bien.
Preguntas frecuentes
- ¿Sirve escribir «no borres archivos» en CLAUDE.md?
- No como protección. La documentación oficial de Claude Code dice que las reglas de permiso las hace cumplir Claude Code, no el modelo, y que las instrucciones de tu prompt o de CLAUDE.md moldean lo que Claude intenta hacer, pero no cambian lo que Claude Code permite. Para bloquear un comando de verdad necesitas una regla deny en la sección permissions de settings.json.
- ¿Qué gana si una regla allow y una regla deny coinciden en Claude Code?
- Gana la deny. Claude Code evalúa las reglas en un orden fijo, primero deny, después ask y al final allow, y la primera coincidencia decide. Que la regla allow sea más específica no cambia el orden: una deny amplia como Bash(aws *) bloquea también una llamada que coincide con una allow estrecha como Bash(aws s3 ls).
- ¿Las reglas deny funcionan con --dangerously-skip-permissions?
- Sí. Esa bandera equivale al modo bypassPermissions, y la documentación de modos de permiso dice que las reglas deny bloquean en todos los modos, incluido ese, mientras que las reglas allow ahí no tienen efecto. Aun así, Anthropic pide usar ese modo solo en entornos aislados, como contenedores o máquinas virtuales, donde Claude Code no pueda dañar tu equipo.
- ¿Por qué mi regla Bash(command:rm *) no bloquea nada?
- Porque Claude Code la ignora. Una regla escrita con el nombre del parámetro principal se podría esquivar con un comando compuesto, así que no se aplica y aparece un aviso al arrancar la sesión. Escríbela como Bash(rm *), con un espacio antes del asterisco: sin ese espacio la regla también atrapa comandos que empiezan por las mismas letras.
- ¿Una regla deny Bash(rm *) bloquea cualquier borrado?
- No. Una regla de Bash compara el texto del comando que escribe Claude, no el programa, así que detiene rm -rf build/ pero no /bin/rm -rf build/ ni bash -c 'rm -rf build/'. La documentación la describe como una cobertura de la forma habitual, no como frontera de seguridad. Para eso remite al sandboxing, y tus respaldos deben vivir en otro sitio.
Fuentes
- Permisos de Claude Code: el archivo que evita un borrado (video de @ninodirector en YouTube)
- Anthropic Engineering: How we contain Claude across products (93 % de aprobaciones y 84 % menos solicitudes)
- Anthropic Engineering: How we built Claude Code auto mode
- Anthropic Engineering: Beyond permission prompts, making Claude Code more secure and autonomous
- Configure permissions — documentación de Claude Code
- Choose a permission mode — documentación de Claude Code