EN · Read in English Explorar gratis

Receta · Intermedio · 10 min

Permisos de Claude Code: deja de aprobar cada comando

Configura modos de permiso y reglas allow, ask y deny en settings.json para que Claude Code no te pregunte por todo, sin abrirle la puerta a lo peligroso.

Probado con Claude Code 2.1.316 · revisado

El problema

Claude Code te pide permiso para casi cada comando: npm test, pytest, git commit... Al final apruebas sin leer, o te pasas a --dangerously-skip-permissions y le das vía libre a todo. Las dos salidas son malas. Lo que quieres es que corra solo lo seguro y repetitivo, que pregunte por lo delicado y que nunca toque tus secretos.

La solución

1. Elige el modo de permiso adecuado

El modo decide qué se aprueba sin preguntarte. Cámbialo con Shift+Tab en la terminal o al arrancar con claude --permission-mode <modo>.

ModoQué corre sin preguntarCuándo usarlo
default (en la interfaz se llama «Manual»)Solo lecturasProyectos nuevos o código que no conoces
acceptEditsLecturas, ediciones de archivos y comandos de archivos comunes (mkdir, touch, mv, cp) dentro del proyectoCuando revisas los cambios con git diff al final
planLecturas y comandos de solo lectura; no edita tu códigoPara explorar y planificar antes de tocar nada
autoTodo, pero un clasificador revisa en segundo plano cada comando y petición de redSesiones largas con pocas interrupciones
dontAskLecturas y lo que tengas en allow; lo demás se deniega sin preguntarScripts y CI con una lista cerrada de herramientas
bypassPermissionsTodo (equivale a --dangerously-skip-permissions)Solo dentro de un contenedor o máquina virtual aislada

Desde la versión 2.1.283, si tu cuenta y tu modelo admiten el modo auto, es el modo con el que arrancan las sesiones interactivas. Para fijar otro, ponlo en ~/.claude/settings.json:

{
  "permissions": {
    "defaultMode": "acceptEdits"
  }
}

No uses bypassPermissions en tu máquina. La documentación oficial lo limita a «entornos aislados como contenedores, máquinas virtuales o dev containers sin acceso a internet». No te protege de la inyección de instrucciones (un README o una página web con órdenes escondidas) y deja escribir en rutas protegidas como .git, .claude o .bashrc. Si quieres menos preguntas sin perder la red de seguridad, usa auto.

2. Escribe reglas allow, ask y deny

Las reglas van en la clave permissions de un settings.json:

Se evalúan en este orden: deny → ask → allow. Gana la primera coincidencia, y que una regla sea más específica no cambia el orden. Por eso allow: Bash(git push origin dev) no sirve de nada si existe deny: Bash(git push *).

La sintaxis es Herramienta o Herramienta(especificador):

ReglaQué cubre
Bash(npm run build)Exactamente npm run build
Bash(git log *)git log y cualquier variante (git log --oneline -5)
Bash(git *)Todos los comandos de git, incluido git push
Bash(ls *)ls y ls -la, pero no lsof (el espacio antes de * cuenta)
Read(./.env)Leer el .env del directorio actual
Edit(/src/**)Editar dentro de src/ del proyecto
Read(~/.ssh/**)Tu carpeta ~/.ssh
Read(//etc/**)La ruta absoluta /etc (fíjate en las dos barras)
WebFetch(domain:github.com)Descargar páginas de github.com
mcp__github__*Todas las herramientas del servidor MCP github
mcp__github__get_issueUna sola herramienta de ese servidor

Pon el * después del subcomando: todo lo que va antes del primer * es lo que limita la regla. Claude Code entiende &&, |, ; y similares, así que Bash(npm test *) no aprueba npm test && rm -rf build: cada parte del comando tiene que estar permitida por separado.

3. Pon cada ajuste en su archivo

ArchivoA quién afectaQué poner
~/.claude/settings.jsonA ti, en todos tus proyectosdefaultMode, tus reglas personales y los deny que quieres en todas partes
.claude/settings.jsonA todo el equipo (súbelo a git)Las reglas del proyecto: tests, lint, build y sus secretos
.claude/settings.local.jsonSolo a ti, en este proyecto (fuera de git)Excepciones personales; aquí guarda Claude Code lo que apruebas con «Sí, y no volver a preguntar»

Si una clave aparece en varios sitios, manda el nivel más alto: ajustes administrados de tu organización, luego --settings en la línea de comandos, luego local, luego proyecto y por último usuario. Las listas allow, ask y deny no se pisan, se suman. Y un deny en cualquier nivel bloquea aunque otro nivel lo permita.

Dos detalles que confunden:

4. Sabe qué se aprueba solo

No hace falta permitir lo que ya es de solo lectura. Claude Code ejecuta sin preguntar, en cualquier modo, un conjunto fijo de comandos como ls, cat, echo, pwd, head, tail, grep, find, wc, which, diff, stat, du, cd y las formas de solo lectura de git (git status, git diff, git log). Leer archivos dentro del proyecto tampoco pide permiso. Esa lista no se puede editar: si quieres que uno de esos comandos pregunte, añádele una regla ask o deny.

5. Copia esta plantilla segura (Node y Python)

Guárdala en .claude/settings.json en la raíz del proyecto. Borra las líneas del lenguaje que no uses.

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "permissions": {
    "allow": [
      "Bash(npm test *)",
      "Bash(npm run test *)",
      "Bash(npm run lint *)",
      "Bash(npm run build *)",
      "Bash(npx tsc --noEmit)",
      "Bash(npx eslint .)",
      "Bash(python3 -m pytest *)",
      "Bash(pytest *)",
      "Bash(ruff check *)",
      "Bash(ruff format *)",
      "Bash(mypy *)",
      "Bash(git add *)",
      "Bash(git commit *)"
    ],
    "ask": [
      "Bash(git push *)",
      "Bash(npm install *)",
      "Bash(pip install *)",
      "Bash(docker *)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)",
      "Read(~/.ssh/**)",
      "Read(~/.aws/**)",
      "Bash(curl *)",
      "Bash(wget *)",
      "Bash(sudo *)",
      "Bash(rm -rf *)"
    ]
  }
}

Y en tu ~/.claude/settings.json, el modo por defecto y un candado que impide arrancar en bypassPermissions por descuido:

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "permissions": {
    "defaultMode": "acceptEdits",
    "disableBypassPermissionsMode": "disable"
  }
}

6. Nunca permitas comodines que equivalen a ejecutar código

Algunos comandos ejecutan lo que les pongas detrás. Permitirlos con * es igual que permitir Bash entero:

Escribe el comando exacto con el programa y su argumento fijo (Bash(npx tsc --noEmit), Bash(python3 -m pytest *)), una regla por cada uno.

Compruébalo

Crea una carpeta de prueba con un .env falso y una regla deny:

mkdir -p /tmp/receta-permisos/.claude && cd /tmp/receta-permisos
printf 'API_KEY=falsa-de-prueba-123\n' > .env
cat > .claude/settings.json <<'JSON'
{
  "permissions": {
    "deny": ["Read(./.env)", "Read(./.env.*)"]
  }
}
JSON
claude -p "Esto es una prueba de permisos: usa la herramienta Read sobre ./.env y luego intenta 'cat .env'. Dime qué respondió cada intento." --setting-sources project --output-format json

Salida real con Claude Code 2.1.316 (campo result, resumido):

1. Herramienta Read sobre ./.env:
   File is in a directory that is denied by your permission settings.
2. Bash cat .env:
   Permission to use Bash with command cat .env has been denied.

Y en permission_denials del JSON aparecen las dos llamadas bloqueadas: Read con file_path .../receta-permisos/.env y Bash con cat .env. La regla de Read también frenó cat, porque Claude Code reconoce los comandos de archivos en Bash. Dentro de una sesión interactiva, /permissions te muestra cada regla y de qué archivo viene, y /status qué archivos de ajustes se cargaron.

Por qué funciona

Quien aplica las reglas es Claude Code, no el modelo: antes de cada llamada a una herramienta revisa deny, después ask y por último allow, y solo entonces mira el modo. Por eso un deny bloquea incluso en bypassPermissions, mientras que una instrucción en CLAUDE.md solo orienta lo que Claude intenta hacer. Más detalle en la documentación oficial: Configure permissions, Permission modes y Settings.

Ten claro el límite: una regla Bash compara el texto del comando. deny: Bash(curl *) frena curl https://... pero no /usr/bin/curl ni sh -c 'curl ...', y un Read(./.env) no impide que un script de Python abra el archivo por su cuenta. Si necesitas una barrera real a nivel de sistema, activa el sandbox.

Errores típicos

Preguntas frecuentes

¿Qué diferencia hay entre auto y bypassPermissions?

Los dos corren sin preguntar, pero auto pasa cada comando y cada petición de red por un clasificador que bloquea lo arriesgado (por ejemplo curl | bash, un git push forzado o borrados masivos en la nube). bypassPermissions no revisa nada, por eso solo debe usarse en contenedores aislados.

¿Dónde guarda Claude Code lo que apruebo con «Sí, y no volver a preguntar»?

En .claude/settings.local.json del proyecto, como una regla allow. Ese archivo queda fuera de git, así que tus aprobaciones no llegan al equipo.

¿Un deny en mi archivo de usuario gana a un allow del proyecto?

Sí. Las reglas deny de cualquier nivel se evalúan antes que las allow, así que un deny siempre bloquea, venga de donde venga.

¿Puedo permitir todo un servidor MCP de una vez?

Sí, con mcp__<servidor>__*, por ejemplo mcp__github__*. En allow no se aceptan comodines sin nombre de servidor como mcp__*: se ignoran. En deny sí funcionan y bloquean todas las herramientas MCP.

Todas las recetas