CLAUDE.md, hooks y permisos: cómo decide Claude Code qué puede hacer
Claude Code lee la configuración en capas: CLAUDE.md de usuario (todos los proyectos), de proyecto (compartido, versionado) y CLAUDE.local.md (personal, para el .gitignore). Los permisos siguen la misma lógica de alcances, pero con una regla fija: un deny siempre vence a un allow, sin importar la especificidad ni de qué alcance venga cada regla. CLAUDE.md moldea lo que Claude intenta hacer; hooks como PreToolUse imponen lo que tiene permitido ejecutar, de forma determinista, incluso si el modelo decide lo contrario.
Claude Code decide qué hacer en dos capas distintas: CLAUDE.md moldea el comportamiento, y los permisos — allow, deny, hooks — deciden qué tiene autorización de ejecutar. Confundir las dos es el error más común de quien configura Claude Code por primera vez.
CLAUDE.md no es permiso — es contexto
CLAUDE.md existe en capas: un archivo de usuario (vale para todos los proyectos), uno de proyecto (compartido, versionado en git) y un CLAUDE.local.md personal, que queda fuera del control de versiones. Lo que escribe ahí moldea lo que Claude intenta hacer — pero es una instrucción en lenguaje natural, y una instrucción en lenguaje natural puede olvidarse a mitad de una conversación larga o perder frente a un pedido más reciente.
Por eso escribir "nunca ejecutes DROP TABLE en producción" en el CLAUDE.md es un buen hábito, pero no una garantía. Guía el comportamiento la mayoría de las veces; no impone nada a nivel de ejecución.
Deny siempre vence a allow — sin excepción por especificidad
Los permisos siguen alcances parecidos a los del CLAUDE.md, pero con una regla fija que no tiene excepción: cuando una regla de deny y una de allow aplican a la misma llamada, gana deny — sin importar de qué alcance venga cada una, ni cuál de las dos es más específica.
Esto derriba una intuición común: un allow muy específico, como permitir solo `git push origin main`, no escapa de un deny más genérico, como bloquear `git push *`. La jerarquía es fija a propósito, para que una restricción de seguridad no pueda ser sorteada por un allow más fino escrito en otro lugar.
Los hooks son la única capa realmente determinista
Un hook PreToolUse se ejecuta antes de que la tool corra y puede bloquear la llamada de verdad, sin importar lo que el modelo haya decidido hacer. Es la diferencia entre pedirle a Claude que evite algo e impedir que suceda.
PostToolUse se ejecuta después: útil para reaccionar a un resultado, como correr el linter tras una edición, pero inútil como barrera — en el momento en que se dispara, el comando destructivo ya se ejecutó. Elegir el hook equivocado para el objetivo es el error más común: quien quiere bloquear necesita PreToolUse; quien quiere reaccionar usa PostToolUse.
Dónde configurar cada cosa
Una preferencia personal, que no tiene sentido imponer al equipo, va en el CLAUDE.local.md, fuera del control de versiones. Una regla que todo el equipo necesita seguir, y que no puede ser ignorada en silencio por un desarrollador, va en el CLAUDE.md de proyecto o en un hook versionado — porque solo lo que está en el repositorio se comparte por construcción.
La pregunta que decide dónde vive algo no es "¿esto es importante?" — es "¿esto necesita valer para todos, aunque nadie recuerde configurarlo de nuevo?". Si la respuesta es sí, es un hook o un CLAUDE.md de proyecto. Si es solo su preferencia, es local.
Más allá de preguntar cada vez: los modos de permiso
Preguntar antes de cada edición no es la única forma de operar. El modo `acceptEdits` deja que Claude escriba y edite archivos sin confirmar uno por uno; el modo `plan` bloquea toda escritura durante la sesión, útil cuando solo quiere que explore y proponga, sin ejecutar nada. Cada modo cambia seguridad por velocidad de un modo distinto — la elección correcta depende de cuánto ya confía en la tarea que se está automatizando, no de una preferencia fija.
Esto es configuración de sesión, así que solo vale mientras la sesión dura — no sustituye a un deny permanente ni a un hook. Un modo más permisivo es una elección consciente para una tarea específica, no una forma de sortear una regla que debería seguir siendo fija.
Pruébalo tú mismo
Un equipo interno de herramientas quiere garantizar que Claude Code nunca pueda ejecutar una sentencia `DROP TABLE` o `TRUNCATE` cruda contra su base de datos Postgres de producción a través de la herramienta Bash, sin importar lo que el modelo decida hacer a mitad de la conversación.
¿Qué mecanismo aplica esto de forma determinística, en lugar de simplemente alentar al modelo a evitarlo?
Lee a continuación
- Cómo funciona el bucle agéntico de Claude CodeClaude Code opera en ciclos de reunir contexto, actuar y verificar — no una lista fija de pasos. Vea cuándo delegar a subagentes vale la pena.
- Técnicas de prompting para Claude: tags XML, ejemplos y prefillUn prompt bien escrito elimina la ambigüedad estructural. Vea cómo tags XML, ejemplos y prefill resuelven los errores más comunes al prompting.
- Qué es MCP y cómo escribir tools que Claude elige bienMCP estandariza cómo Claude se conecta a datos y acciones externas. Vea cómo nombrar y describir tools para que elija la correcta, incluso entre decenas.
- Cómo funciona el prompt caching de Claude — y cómo no pagar de másEl cache de prompt reduce el costo real, pero solo si el prefijo es idéntico byte a byte. Vea dónde poner el breakpoint y cómo tratar 429, 529 y 400.
Estudia esto de verdad
Este es un concepto entre todos los del camino de certificación. AgentPrep los convierte a todos en una misión diaria, dentro de Claude Code.
Empieza gratis