Las reglas de permisos de Claude Code te permiten escribir entradas allow / ask / deny en settings.json para especificar, de forma granular, qué herramientas, comandos, archivos y dominios se ejecutan sin preguntar, piden confirmación cada vez o están prohibidos. Se pueden compartir en todo un equipo, de modo que bloqueas con certeza lo peligroso mientras dejas que el trabajo seguro y rutinario se ejecute sin interrupciones.

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.

CLAUDE CODE · REGLAS DE PERMISOS

Control granular con allow / ask / deny

Se evalúa deny → ask → allow (gana la primera coincidencia)

deny

Prohibido (gana sobre todo)

ask

Pregunta cada vez

allow

Se ejecuta sin preguntar

1. Qué son las reglas de permisos (frente a los modos)

Claude Code usa un sistema de permisos por niveles. Las lecturas (ver archivos, Grep, etc.) no necesitan aprobación; los comandos Bash y las ediciones de archivos sí, y sobre esa base, las reglas te permiten especificar excepciones granulares (fuente: la documentación oficial "Configure permissions" de Claude Code).

Es fácil confundir las reglas con los modos de permisos. Los modos son la base amplia de "con qué frecuencia pregunta" (default/acceptEdits/auto, etc.); las reglas son especificaciones por herramienta y por comando. Funcionan juntos: el modo establece la base y las reglas la anulan con "permite siempre esto" o "nunca permitas aquello".

💡 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).

ALLOW

Se ejecuta sin preguntar

La herramienta o el comando indicado se ejecuta sin aprobación manual.

ASK

Pregunta cada vez

Pide confirmación en cada uso. Una coincidencia con ask pregunta aunque también coincida un allow más amplio.

DENY

Prohibido (máxima prioridad)

Bloquea la herramienta. Gana sobre cualquier allow, y un deny en cualquier nivel siempre prevalece.

Las reglas se evalúan deny → ask → allow. La primera coincidencia decide el resultado, y la especificidad de la regla no cambia el orden. Un deny amplio Bash(aws *) gana sobre un allow más específico Bash(aws s3 ls). La idea: un deny no puede llevar excepciones de lista de permitidos.

⚠️ 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.

HerramientaEjemploSignificado
BashBash(npm run *)Comandos que empiezan por npm run (el * final = límite de palabra)
Read / EditRead(./.env)Leer el .env del directorio actual (ruta estilo gitignore)
WebFetchWebFetch(domain:example.com)Peticiones a example.com
MCPmcp__github__get_*Las herramientas get_ del servidor github
AgentAgent(Explore)El subagente Explore

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 *.

// Permitir comandos seguros, denegar git push
{
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(git commit *)"
    ],
    "deny": [
      "Bash(git push *)"
    ]
  }
}

Cuidado con los comandos compuestos. Claude Code entiende separadores como && || ; |, y cada subcomando debe coincidir de forma independiente. Bash(safe-cmd *) no permite safe-cmd && rm -rf .. Ten en cuenta que los comandos de solo lectura (ls/cat/grep/find/pwd, etc.) se ejecutan sin preguntar en todos los modos, y los envoltorios como timeout/nice/nohup se eliminan antes de la comparación.

Las rutas de Read/Edit siguen la semántica de gitignore con cuatro anclas:

FormaAnclaEjemplo
//pathAbsoluta del sistema de archivosRead(//tmp/x)
~/pathHomeRead(~/.ssh/**)
/pathRaíz del proyectoEdit(/src/**)
path / ./pathDirectorio actualRead(.env)

/Users/... NO es absoluta: es relativa a la raíz del proyecto. Usa //Users/... (doble barra) para rutas absolutas. Read(.env) equivale a Read(**/.env) y coincide con todos los .env que haya por debajo.

4. Jerarquía y precedencia de settings.json

Las reglas viven en settings.json. Hay varios archivos, y los niveles más altos son más fuertes. La regla clave: un deny en cualquier nivel siempre vence a un allow en cualquier otro nivel.

PrioridadUbicaciónUso
1 (la más fuerte)Managed settingsPolítica de la organización. Usuarios y CLI no pueden anularla
2Argumentos de línea de comandosAnulaciones temporales de la sesión
3.claude/settings.local.jsonAjustes personales del proyecto (gitignored)
4.claude/settings.jsonAjustes compartidos del proyecto (versionados)
5~/.claude/settings.jsonAjustes 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). Para leer o editar fuera del directorio de trabajo, añade rutas a additionalDirectories.

5. Recetas prácticas

Combinaciones habituales. La forma básica: denegar con certeza lo peligroso y permitir la rutina segura para automatizarla.

🔒 Proteger archivos de secretos

deny: ["Read(.env)", "Read(**/secrets/**)", "Read(~/.ssh/**)"]. Bloquea las lecturas de raíz.

🚀 Confirmar siempre las operaciones de riesgo

ask: ["Bash(git push *)", "Bash(rm *)"]. Obliga a confirmar incluso en modo auto.

⚡ Automatizar el trabajo rutinario

allow: ["Bash(npm run *)", "Bash(git commit *)"]. Tests, builds y commits se ejecutan sin interrupciones.

Restringir URLs mediante patrones de argumentos de Bash es frágil (curl http://github.com/ * se sortea fácilmente con -X GET o con la expansión de variables). En su lugar, deniega curl/wget y permite dominios concretos con WebFetch(domain:...). Para un control más estricto, valida las URLs en un hook PreToolUse.

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.
  • El deny de Read/Edit no detiene el acceso indirecto. Se aplica a las herramientas de archivo integradas y a cat/head/sed, pero no a un script de Python o Node que abra archivos por su cuenta. Para una protección a nivel de sistema operativo, usa también el sandboxing.
  • Atención a los ejecutores de entornos. devbox run *, npx y docker exec ejecutan sus argumentos como un comando, así que Bash(devbox run *) también permite devbox run rm -rf .. Escribe reglas que incluyan el comando interno.
  • Los hooks no anulan las reglas. Un hook PreToolUse puede ampliar permisos, pero deny/ask se evalúan independientemente de lo que devuelva el hook (la prioridad del deny no cambia).

※ El comportamiento se corresponde con la documentación oficial de Claude Code (Configure permissions / Settings), a fecha de junio 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.json para conceder, preguntar o prohibir por herramienta, comando, archivo y dominio. Los modos fijan la base; las reglas se ocupan de los detalles.
  • Precedencia: deny → ask → allow (gana la primera coincidencia; la especificidad es irrelevante). Un deny en cualquier nivel siempre gana. 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.

"Bloquear con certeza lo peligroso y automatizar la rutina segura" es el corazón del diseño de reglas. Combínalo con los modos de permisos, los hooks y el ajuste de esfuerzo para ejecutar Claude Code de forma segura y fluida.

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 me aseguro de que .env nunca se lea?

A. Pon deny: ["Read(.env)", "Read(**/secrets/**)"]. Ten en cuenta que esto se aplica a las herramientas de archivo integradas y a los comandos tipo cat, pero no a las lecturas indirectas mediante un script. Para una protección a nivel de sistema operativo, activa también el sandboxing.

Q. ¿Puedo restringir URLs o archivos mediante argumentos de Bash?

A. No de forma fiable. curl http://github.com/ * se sortea fácilmente con opciones o con la expansión de variables. Para limitar URLs, deniega curl/wget y usa WebFetch(domain:...), o valida en un hook PreToolUse.