Permisos de Claude Code: configura settings.json con seguridad
Configura allow, ask y deny en Claude Code con un settings.json seguro y una comprobación lista para copiar.
Solo quieres que Claude Code ejecute las pruebas, pero aparece una confirmación para cada comando. En el extremo contrario, si autorizas Bash sin límites, también podrías dejar pasar un borrado, un hard reset o un push --force sin revisar.
No tienes que elegir entre aprobarlo todo o bloquearlo todo. Una configuración inicial razonable automatiza las lecturas y las pruebas, pide confirmación antes de editar o publicar cambios y rechaza el acceso a secretos y las operaciones destructivas. Esos tres niveles se definen en settings.json.
Lo esencial de esta guía
- Las reglas se evalúan en este orden: deny → ask → allow. Primero se bloquea, después se pregunta y, por último, se permite automáticamente.
- Las lecturas dentro del proyecto ya se realizan sin aviso. Autoriza solo pruebas revisadas, pregunta antes de editar, acceder fuera o hacer push, y bloquea secretos y operaciones destructivas.
Bash(git *)es demasiado amplio: también alcanza comandos comogit reset --hardygit push --force.- Bloquear
Read(.env)no basta para contener cualquier proceso hijo. Si necesitas una barrera fuerte, combina las reglas con el sandbox. - Después de guardar el archivo, usa
/permissionsy/statuspara comprobar qué reglas están activas y de qué archivo proceden.
Qué puede hacer Claude Code y qué debe decidir una persona
| Claude Code puede hacerlo solo | Requiere revisión humana | Debe bloquearse siempre |
|---|---|---|
| Buscar archivos, revisar diferencias y ejecutar pruebas | Editar archivos, hacer commit o push, instalar dependencias | Leer secretos, forzar un push, ejecutar hard reset o borrar en masa |
Read, Grep, git diff | Edit, git commit, npm install | .env, git push --force, git reset --hard, rm -rf |
Toda acción difícil de deshacer, que envíe datos fuera del equipo o que pueda tocar credenciales debe quedar en ask o deny.
Un settings.json seguro para empezar
Crea .claude/settings.json en la raíz del proyecto y pega esta configuración. Está pensada como una base conservadora que el equipo puede versionar en Git.
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"defaultMode": "default",
"allow": [
"Bash(npm test *)",
"Bash(npm run lint *)"
],
"ask": [
"Edit",
"WebFetch",
"Bash(git add *)",
"Bash(git commit *)",
"Bash(git push *)",
"Bash(git clean *)",
"Bash(git restore *)",
"Bash(npm install *)",
"Bash(npm uninstall *)"
],
"deny": [
"Read(.env)",
"Read(.env.*)",
"Read(**/secrets/**)",
"Edit(.env)",
"Edit(.env.*)",
"Edit(**/secrets/**)",
"Bash(git push --force *)",
"Bash(git reset --hard *)",
"Bash(rm -rf *)",
"Bash(rm *)",
"PowerShell(Remove-Item *)"
]
}
}
Esta base presupone que ya has revisado los scripts de package.json. En un repositorio desconocido, deja allow vacío hasta comprobar qué ejecuta realmente la prueba. Bash(npm test *) coincide con npm test y con sus variantes con argumentos.
Dónde guardar settings.json
| Ámbito | Ubicación | Uso recomendado |
|---|---|---|
| User | ~/.claude/settings.json | Preferencias comunes a todos tus proyectos |
| Project | .claude/settings.json | Reglas del equipo que se comparten mediante Git |
| Local | .claude/settings.local.json | Ajustes exclusivos de este equipo; no se suben a Git |
| Managed | Configuración distribuida por un administrador | Políticas de organización que el usuario no puede reemplazar |
La precedencia es Managed, línea de comandos, Local, Project y User. Los arrays como permissions.allow se concatenan entre ámbitos; no se reemplazan por completo. Una coincidencia en deny se evalúa antes que ask y allow. Coloca los bloqueos comunes en Project y las políticas inmutables en Managed.
Cómo leer las reglas allow, ask y deny
| Regla | Qué significa |
|---|---|
Read | Coincide con todas las lecturas integradas; normalmente no hace falta un allow global dentro del proyecto |
Bash(npm test) | Coincide exactamente con npm test |
Bash(npm test *) | Coincide con npm test y con argumentos posteriores |
Bash(ls*) | También puede coincidir con lsof; es más amplio de lo que parece |
Read(//Users/me/secrets/**) | Ruta absoluta desde la raíz del sistema de archivos |
Edit(/src/**/*.ts) | En Project, coincide con los archivos TypeScript bajo src del proyecto |
WebFetch(domain:docs.anthropic.com) | Coincide con solicitudes WebFetch al dominio indicado |
Una regla como Bash(git *) cubre git push origin main, pero también git reset --hard. Autoriza comandos concretos en lugar de conceder acceso a todo Git.
Por qué Read y Edit no protegen por sí solos los secretos
Los patrones de ruta de Read y Edit siguen la sintaxis de gitignore.
| Sintaxis | Punto de referencia | Ejemplo |
|---|---|---|
//path | Raíz del sistema de archivos | Read(//Users/me/secrets/**) |
~/path | Directorio personal | Read(~/.ssh/**) |
/path | Ubicación base del archivo de configuración | En Project: Edit(/src/**) |
path o ./path | Directorio de trabajo actual | Read(.env) |
Una sola barra inicial no representa una ruta absoluta. Read(.env) impide que la herramienta integrada Read abra ese archivo, pero no es una barrera general para cualquier comando de Bash o proceso hijo. Por ejemplo, un script de Node.js puede abrir un archivo por su cuenta si el sistema operativo se lo permite.
Si el repositorio contiene credenciales, añade también el sandbox de Claude Code y aplica restricciones en el nivel del sistema operativo. Las reglas de permisos y el sandbox son capas complementarias, no sustitutos.
Tres casos de uso
Caso de uso 1: automatizar solo las pruebas en un proyecto personal
Entrada: código fuente, pruebas y diferencias de Git. Salida: propuesta de corrección y resultado de las pruebas. Revisión humana: edición, instalación de dependencias, commit y push.
Empieza con la configuración mínima anterior y deja Edit en ask. Cuando una operación segura se repita con frecuencia, muévela a allow de forma explícita. No amplíes la regla a Bash completo solo para eliminar una confirmación molesta.
Caso de uso 2: compartir bloqueos peligrosos con todo el equipo
Entrada: lista de comandos necesarios y operaciones prohibidas. Salida: configuración versionada en Git. Revisión humana: nuevas reglas deny y cualquier excepción temporal.
Guarda en Project los bloqueos para .env, push --force y reset --hard. Si la organización necesita impedir que una persona modifique esas reglas, trasládalas a Managed settings.
Caso de uso 3: investigar un repositorio de producción sin modificarlo
Entrada: registros del incidente e historial de Git. Salida: posibles causas y un plan de corrección. Revisión humana: cualquier edición, despliegue o envío de datos externo.
Inicia Claude Code en Plan Mode:
claude --permission-mode plan
Si la investigación exige escribir archivos, cambia primero a una rama de trabajo o a un entorno aislado. Solo entonces aprueba la modificación.
Cuatro errores concretos y su corrección
| Error | Causa | Corrección |
|---|---|---|
Permitir Bash(git *) | El patrón también cubre push y hard reset | Autoriza solo órdenes cuyos efectos hayas revisado |
Añadir allow: Bash(aws s3 ls) bajo deny: Bash(aws *) | Deny gana antes que ask y allow; la especificidad no crea excepciones | Reduce el deny o separa la operación segura tras otro comando |
Tratar Read(.env) como aislamiento del sistema | Un proceso Node.js o Python arbitrario no queda bloqueado por completo | Añade denyRead o credenciales del sandbox |
| Borrar un allow Local y verlo todavía activo | Los arrays se combinan entre User, Project y Local | Revisa el origen en /permissions y los ámbitos en /status |
Consulta los fallos de seguridad de Claude Code para ver incidentes y las mejores prácticas de seguridad para revisar el despliegue completo.
Cómo elegir el permission mode
| Modo | Cuándo usarlo | Precaución |
|---|---|---|
default | Primer contacto con un repositorio | Pide confirmación cuando una acción la necesita |
acceptEdits | Desarrollo cuyo alcance ya comprendes | Aprueba ediciones y operaciones comunes de archivos |
plan | Investigación, diseño o lectura de un incidente | No modifica el código fuente |
auto | Prueba de tareas largas con evaluación de seguridad en segundo plano | Revisa la documentación porque sigue siendo una función en evolución |
dontAsk | Automatización no interactiva con operaciones preaprobadas | Rechaza lo no autorizado en vez de pedir confirmación |
bypassPermissions | Contenedor o máquina virtual desechable | No lo uses en tu PC habitual ni en producción |
Con sandbox.autoAllowBashIfSandboxed: true, una orden Bash que se ejecute dentro del sandbox puede pasar sin una pregunta aunque exista una regla ask para Bash. Los deny explícitos siguen aplicándose. Revisa esta interacción antes de asumir que aparecerá una confirmación.
Pitfall: permitir demasiado y confiar solo en un hook
Un error habitual consiste en colocar todo Bash en allow y usar un único hook PreToolUse para bloquear comandos peligrosos. Un fallo de instalación, una condición incompleta o un matcher mal escrito deja entonces abierta la única barrera.
Causa: la autorización base es demasiado amplia y toda la protección depende de una sola comprobación dinámica.
Corrección: escribe primero deny explícitos y reglas allow estrechas. Usa los hooks como una capa adicional para decisiones dinámicas. Una coincidencia en deny o ask sigue teniendo prioridad aunque un hook devuelva allow.
JSON y JavaScript listos para copiar
Guarda el JSON mostrado al principio en .claude/settings.json. Después crea este script como scripts/check-claude-permissions.mjs. Comprueba que el archivo sea JSON válido y que no falten cuatro bloqueos mínimos.
// scripts/check-claude-permissions.mjs
import { readFileSync } from "node:fs";
const path = ".claude/settings.json";
const settings = JSON.parse(readFileSync(path, "utf8"));
const deny = new Set(settings.permissions?.deny ?? []);
const required = [
"Read(.env)",
"Edit(.env)",
"Bash(git push --force *)",
"Bash(git reset --hard *)",
"Bash(rm *)",
"PowerShell(Remove-Item *)",
];
const missing = required.filter((rule) => !deny.has(rule));
if (missing.length > 0) {
console.error(`Faltan reglas deny: ${missing.join(", ")}`);
process.exit(1);
}
console.log("Comprobación mínima de permisos: OK");
Ejecútalo desde la raíz del proyecto:
node scripts/check-claude-permissions.mjs
Esta prueba no demuestra que el repositorio sea seguro. Su propósito es detectar en CI que alguien haya eliminado por error uno de los bloqueos mínimos.
Qué revisar cuando la configuración no funciona
- Abre
/permissionsy comprueba la regla efectiva y el archivo que la define. - Usa
/statuspara ver qué niveles de configuración se cargaron. - Revisa diferencias pequeñas pero importantes, como
Bash(ls *)frente aBash(ls*), o/pathfrente a//path. - Comprueba la autorización automática del sandbox y cualquier
denyoaskde un ámbito superior. - Devuelve a
.claude/settings.jsontoda regla que deba compartir el equipo, en lugar de dejarla solo en una opción temporal de la CLI.
Resumen
Empieza pegando una configuración mínima en .claude/settings.json y confirma su procedencia con /permissions.
Pon solo las pruebas revisadas en allow, deja las ediciones y acciones externas en ask, y bloquea secretos y operaciones destructivas con deny. Amplía la lista únicamente cuando conozcas el efecto exacto de cada comando.
Para instalar esta política junto con otras reglas de desarrollo, consulta los materiales de Claude Code, donde reunimos plantillas y listas de comprobación.
Fuentes oficiales
- Configure permissions — documentación oficial de Claude Code
- Claude Code settings — documentación oficial
- Choose a permission mode — documentación oficial
- Configure the sandboxed Bash tool — documentación oficial
- Debug your configuration — documentación oficial
- Security — documentación oficial
- Hooks reference — documentación oficial
Resultado de la prueba realizada
El 22 de julio de 2026 analizamos con JSON.parse el bloque JSON de los diez idiomas y ejecutamos el control de Node.js en un proyecto temporal. Con los seis deny obligatorios terminó con código 0; al quitar Bash(git reset --hard *), terminó con código 1 e indicó la regla ausente.
La prueba usó únicamente un fixture inventado: no contiene credenciales, repositorios de clientes ni datos de producción, y no representa un resultado obtenido en un sistema real. La interfaz de permisos puede variar según el sistema operativo y la versión de Claude Code; comprueba también /permissions y /status en tu entorno.
Artículos relacionados
Recuperarse de una denegación de permisos en Claude Code sin debilitar guardrails
Convierte un comando denegado en plan seguro con razón, alternativa, pruebas y criterio de reintento.
Escalera de permisos de Claude Code para ampliar acceso sin perder control
Pasa de read-only a ediciones limitadas, comandos de prueba y checks de deploy con menos riesgo.
Permission budget de Claude Code: permisos, coste y logs en 5 minutos
Un loop práctico para reglas allow/deny, límites de coste, logs de ejecución y handoff en Claude Code.
PDF gratis: cheatsheet de Claude Code
Introduce tu email y descarga una hoja con comandos, hábitos de revisión y flujos seguros.
Cuidamos tus datos y no enviamos spam.
Sobre el autor
Masa
Ingeniero enfocado en workflows prácticos con Claude Code.