Contenido
Claude Code usa reglas de permisos con allow / ask / deny en settings.json para especificar qué herramientas, comandos, archivos y dominios se permiten sin confirmación, requieren aprobación o están prohibidos. Los equipos pueden compartirlas para rechazar llamadas coincidentes y reducir las aprobaciones de tareas habituales ya revisadas. No bloquean de forma uniforme otras formas de invocar el mismo programa ni el acceso mediante scripts.
Esta guía explica qué son las reglas de permisos (y en qué se diferencian de los modos de permisos), la precedencia allow/ask/deny, la sintaxis de las reglas, la jerarquía de settings.json y recetas prácticas, todo basado en la especificación oficial.
Control granular con allow / ask / deny
Se evalúa deny → ask → allow (gana la primera coincidencia)
deny
Evalúa primero las reglas deny coincidentes
ask
Pregunta cada vez
allow
Se ejecuta sin preguntar
1. Qué son las reglas de permisos (frente a los modos)
Claude Code utiliza un sistema de permisos por niveles. Tomando Manual como referencia, las lecturas del área de trabajo normalmente no requieren confirmación, mientras que las ediciones y la ejecución de Bash normalmente sí, con excepciones como los comandos integrados de solo lectura y las reglas allow. Sobre esa base, las reglas especifican excepciones individuales (fuente: «Configure permissions», documentación oficial de Claude Code).
Es fácil confundir las reglas con los modos de permisos. Los modos establecen la política general de confirmación (default, acceptEdits, auto, etc.); las reglas especifican herramientas y comandos individuales. Se complementan: los modos fijan la base y las reglas la modifican con instrucciones como «permite siempre esto» o «rechaza esta llamada».
💡 Las reglas las hace cumplir Claude Code, no el modelo. Tu prompt o tu CLAUDE.md moldean lo que Claude intenta hacer, pero no lo que está permitido. Concede o revoca el acceso mediante /permissions, las reglas, los modos o un hook PreToolUse.
2. allow / ask / deny y la precedencia
Hay tres tipos de regla. El comando /permissions las lista y edita (y muestra de qué settings.json procede cada una).
Se ejecuta sin preguntar
La herramienta o el comando indicado se ejecuta sin aprobación manual.
Pregunta cada vez
Pide confirmación en cada uso. Una coincidencia con ask pregunta aunque también coincida un allow más amplio.
Prohibido (máxima prioridad)
Bloquea el uso. Tiene prioridad sobre allow: entre las reglas de ajustes, allow no puede anular un deny coincidente.
Las reglas se evalúan en el orden deny → ask → allow. Entre las reglas ordinarias de ajustes, la primera coincidencia decide y la especificidad no cambia el orden. Un deny amplio Bash(aws *) bloquea incluso un allow más específico Bash(aws s3 ls). Lo esencial es que allow no puede anular un deny coincidente. La negación en rutas relativas de Read/Edit es una función aparte.
⚠️ Las dos formas de deny se comportan de manera distinta: un nombre de herramienta a secas como Bash elimina la herramienta por completo del contexto de Claude (Claude nunca la ve). Una regla acotada como Bash(rm *) mantiene la herramienta disponible y bloquea solo las llamadas que coinciden.
3. Sintaxis de las reglas (Tool(specifier))
El formato es Tool (todo) o Tool(specifier) (algo concreto). Cada herramienta tiene su propio estilo de especificador.
| Herramienta | Ejemplo | Significado |
|---|---|---|
| Bash | Bash(npm run *) | Comandos que empiezan por npm run (el * final = límite de palabra) |
| Read / Edit | Read(./.env) | Leer el .env del directorio actual (ruta estilo gitignore) |
| WebFetch | WebFetch(domain:example.com) | Peticiones a example.com |
| MCP | mcp__github__get_* | Las herramientas get_ del servidor github |
| Agent | Agent(Explore) | El subagente Explore |
Las reglas MCP solo se aplican al servidor que nombran. Desde v2.1.299 (14 de octubre de 2026), mcp__a no permite otros servidores llamados a__b ni a_. Para un servidor cuyo nombre contiene __ o termina en _, escribe el nombre completo normalizado seguido de __*, como en mcp__reports__v2__* (documentación oficial y historial de cambios, comprobado el 18 de octubre de 2026).
Los comodines de Bash pueden aparecer en cualquier sitio. Bash(ls *) (espacio + *) coincide con ls -la pero no con lsof (límite de palabra); Bash(ls*) (sin espacio) coincide con ambos. Un :* final equivale a *.
// Permite o deniega llamadas específicas; no bloquea todas las vías al mismo programa
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git commit *)"
],
"deny": [
"Bash(git push *)"
]
}
}
Los comandos compuestos se evalúan por subcomando y se retiran los envoltorios reconocidos antes de la evaluación. Sin embargo, otras formas de invocar el mismo programa no siempre coinciden: Bash(git push *) no coincide con git -C . push. Los comandos integrados de solo lectura normalmente omiten la confirmación, pero las restricciones de lectura fuera del área de trabajo y las esperas del clasificador de auto son condiciones distintas.
Las rutas de Read/Edit siguen la semántica de gitignore con cuatro anclas:
| Forma | Ancla | Ejemplo |
|---|---|---|
//path | Absoluta del sistema de archivos | Read(//tmp/x) |
~/path | Home | Read(~/.ssh/**) |
/path | El ancla del archivo de configuración (la raíz del proyecto en la configuración del proyecto, ~/.claude en la de usuario) | Edit(/src/**) |
path / ./path | Directorio actual | Read(.env) |
* /Users/... NO es absoluta: es relativa al ancla del archivo de configuración (la raíz del proyecto en la configuración del proyecto). En la configuración de usuario, Read(/secrets/**) apunta a ~/.claude/secrets/**, así que para una regla que valga en todos los proyectos usa // o ~/. Usa //Users/... (doble barra) para rutas absolutas. Read(.env) equivale a Read(**/.env) y coincide con todos los .env que haya por debajo.
La negación en reglas deny de rutas relativas es una función aparte. En una lista de la misma fuente, colocar Read(!sample.env) después de Read(*.env) excluye sample.env del ámbito de esa regla. No puede levantar un deny de otra fuente, una regla anclada con /, ~/ o //, ni la prohibición de un directorio entero. No lo confundas con anular deny mediante allow. Documentación oficial: patrones de negación.
4. Jerarquía y precedencia de settings.json
Los valores de los ajustes se resuelven según la jerarquía. Para las reglas de permisos, un deny coincidente se evalúa antes que allow. La tabla describe la prioridad entre reglas de archivos de ajustes y de la CLI; no es una garantía absoluta que abarque también cambios de decisión de los mods.
| Prioridad | Ubicación | Uso |
|---|---|---|
| 1 (la más fuerte) | Managed settings | Política de la organización. Usuarios y CLI no pueden anularla |
| 2 | Argumentos de línea de comandos | Anulaciones temporales de la sesión |
| 3 | .claude/settings.local.json | Ajustes personales del proyecto (gitignored) |
| 4 | .claude/settings.json | Ajustes compartidos del proyecto (versionados) |
| 5 | ~/.claude/settings.json | Ajustes de usuario para todos los proyectos |
// .claude/settings.json (compartido por el equipo)
{
"permissions": {
"defaultMode": "acceptEdits",
"allow": ["Bash(npm run *)", "WebFetch(domain:docs.example.com)"],
"deny": ["Read(.env)", "Read(**/secrets/**)", "Bash(git push *)"],
"additionalDirectories": ["../shared-lib"]
}
}
El modo de permisos por defecto también se fija aquí, como defaultMode (detalles de los modos). Eso sí, auto y bypassPermissions no surten efecto desde la configuración del proyecto (.claude/settings.json, .claude/settings.local.json), así que van en la configuración de usuario o en la gestionada. Para leer o editar fuera del directorio de trabajo, añade rutas a additionalDirectories.
5. Recetas prácticas
Empieza por limitar allow a llamadas habituales revisadas y usar ask/deny para las llamadas que quieras restringir. Esto no controla automáticamente otras formas de realizar la misma operación ni todo lo que ocurre dentro de un script permitido.
🔒 Proteger archivos de secretos
deny: ["Read(.env)", "Read(**/secrets/**)", "Read(~/.ssh/**)"]. Restringe las herramientas de archivos integradas y los comandos de archivos cuyas rutas de destino pueden reconocerse. Quedan otras vías, incluidas búsquedas recursivas, scripts arbitrarios y MCP.
🚀 Añade confirmación a llamadas específicas
ask: ["Bash(git push *)", "Bash(rm *)"]. Añade confirmación a llamadas coincidentes incluso en auto. Vigila otras formas de invocación y los cambios de decisión de los mods.
⚡ Automatizar el trabajo rutinario
allow: ["Bash(npm run *)", "Bash(git commit *)"]. Tests, builds y commits se ejecutan sin interrupciones. Eso sí, en el modo automático una regla amplia de ejecución del gestor de paquetes como Bash(npm run *) se retira y esos comandos pasan por el clasificador.
La coincidencia de argumentos Bash no basta para imponer restricciones de URL. Incluso una política que deniegue curl/wget y use WebFetch deja vías mediante rutas absolutas, sh -c y otros programas. Las reglas de dominio de WebFetch controlan esa herramienta, no todo el tráfico de Bash. Para imponer destinos, combina controles como la lista de destinos permitidos del sandbox y gestiona por separado las herramientas y los reintentos fuera del sandbox.
6. Trampas y confusiones habituales
- El deny lo hace cumplir Claude Code, no el modelo. Escribir "no leas esto" en tu prompt o en CLAUDE.md no lo impedirá sin una regla.
- Deny de Read/Edit no impide el acceso indirecto. Se aplica a las herramientas de archivos integradas y a
cat/head/sed, pero no a scripts Python o Node que abren archivos por su cuenta. Otra excepción son las operaciones recursivas comogrep -r pattern ., que no nombran el archivo de destino. Las restricciones del sistema operativo se aplican a los procesos dentro del sandbox; Read integrado, MCP y otras vías requieren controles aparte. - Atención a los ejecutores de entornos.
devbox run *,npxydocker execejecutan sus argumentos como un comando, así queBash(devbox run *)también permitedevbox run rm -rf .. Escribe reglas que incluyan el comando interno. - Los hooks no anulan las reglas. Un hook PreToolUse puede ampliar los permisos, pero deny/ask se evalúan independientemente de su resultado. Sin embargo,
tool.checkde un mod puede sustituir la decisión en una fase posterior. Puede aprobar ask y, en entornos personales sin ajustes gestionados, también deny. En equipos gestionados y Team/Enterprise, deny tiene prioridad por defecto, aunque los ajustes de la organización pueden cambiarlo. Debes decidir si confías en los mods instalados. - En el modo automático, incluso un comando de tu lista allow puede pasar por el clasificador. Al entrar en el modo automático se retiran las reglas allow amplias que permiten ejecutar código arbitrario (
Bash(*)sin más, intérpretes con comodín comoBash(python*), comandos run de gestores de paquetes, reglasAgent, etc.), que vuelven al salir del modo; las reglas acotadas comoBash(npm test)se mantienen. Las reglas solo coinciden tal como están escritas, así queBash(git push *)no coincide congit -C . push, y un comando que no coincide con ninguna regla lo juzga el clasificador. Las escrituras en rutas protegidas también pasan por el clasificador aunque coincida una regla allow. Si se bloquea una acción legítima, puedes reintentarla desde Recently blocked (Recently denied antes de la v2.1.314) en/permissions(ver modos de permiso). También hay issues en GitHub que informan de comandos permitidos que se bloquearon (por ejemplo, #95996). Este punto sigue la documentación oficial (Choose a permission mode) a 9 de octubre de 2026.
* El comportamiento se corresponde con la documentación oficial de Claude Code (Configure permissions / Settings files and precedence / Choose a permission mode), a fecha de 9 de octubre de 2026. Puede cambiar: consulta la documentación oficial para lo más reciente.
Resumen
Tres ideas clave sobre las reglas de permisos de Claude Code.
- Qué son: allow/ask/deny en
settings.jsonpara conceder, preguntar o prohibir por herramienta, comando, archivo y dominio. Los modos fijan la base; las reglas se ocupan de los detalles. - Prioridad: deny → ask → allow (gana la primera coincidencia; la especificidad no importa). Entre reglas de ajustes, allow no puede anular un deny coincidente. Niveles: managed > CLI > local > project > user.
- Sintaxis:
Tool(specifier). Bash usa comodines (espacio + * es un límite de palabra), Read/Edit usan rutas estilo gitignore, WebFetch usa domain:. Los comandos compuestos necesitan que coincida cada subcomando.
Entiende con qué coincide cada regla y reduce solo las aprobaciones que necesites reducir. Combina reglas con modos de permisos y hooks. Considera un sandbox cuando necesites restricciones efectivas de archivos o red. Distingue qué capa cubre cada vía.
Si quieres investigar el estado actual y recibir asesoramiento sin modificar el código, consulta cómo usar Codex y Claude Code solo para investigar. Incluye los pasos en la aplicación, el IDE y la CLI, y una instrucción para evitar que el agente pase a implementar.
Preguntas frecuentes
Q. ¿En qué se diferencian las reglas de permisos de los modos?
A. Los modos son la base amplia de confirmación (default/acceptEdits/auto, etc.); las reglas son especificaciones por herramienta y por comando. Funcionan juntos, y las reglas anulan los modos (p. ej., las reglas ask/deny siguen aplicándose en modo auto).
Q. Lo permití, ¿por qué sigue preguntando?
A. Porque la evaluación es deny → ask → allow. Si un ask (o deny) distinto también coincide con la llamada, gana incluso sobre un allow más específico. La especificidad no cambia el orden.
Q. ¿Dónde pongo settings.json?
A. Compartido por el equipo: .claude/settings.json (versionado). Personal: .claude/settings.local.json (gitignored). Para todos los proyectos: ~/.claude/settings.json. Para una aplicación a nivel de toda la organización, usa managed settings (no se pueden anular).
Q. ¿Cómo puedo restringir la lectura de .env?
A. deny: ["Read(.env)", "Read(**/secrets/**)"] restringe las herramientas de archivos integradas y los comandos de archivos reconocibles. No garantiza bloquear todas las vías, incluidas búsquedas recursivas que no nombran la ruta de destino, Python/Node y MCP. Para el shell, comprueba los permisos de lectura del sistema operativo o denyRead dentro del sandbox; revisa aparte los permisos de otras herramientas.
Q. ¿Puedo restringir URLs o archivos mediante argumentos de Bash?
A. La coincidencia de cadenas de comandos no bloquea otras formas de invocación ni operaciones equivalentes de red y archivos mediante otros programas. Las reglas de dominio de WebFetch se aplican a WebFetch. Para imponer límites, combina el aislamiento de archivos y red del shell con controles separados del acceso fuera del sandbox.
El alcance y las excepciones de los permisos y el aislamiento se contrastaron de nuevo con la documentación oficial original el 9 de octubre de 2026. No se cambiaron ajustes del equipo ni se hicieron pruebas de inicio.