Guía completa de permisos de Claude Code | settings.json, Hooks y Allowlist explicados
Guía de permisos de Claude Code: allow/deny/ask, settings.json, hooks PreToolUse, ajustes gestionados y budget seguro con código funcional.
Claude Code tiene capacidades extremadamente potentes de operación de archivos y ejecución de comandos. Los permisos (permissions) son lo que te permite controlar ese poder de forma segura. Supera el estado de “lo uso sin entenderlo bien” y diseña un Claude Code que funcione exactamente como lo deseas.
Este artículo explica exhaustivamente, con código funcional, todos los ajustes de .claude/settings.json, los patrones de implementación de Hooks y el diseño de permisos específico por entorno.
Visión general de los permisos
Los permisos de Claude Code se controlan en 3 niveles.
| Nivel | Clave | Comportamiento |
|---|---|---|
| Permitir | allow | Se ejecuta automáticamente sin diálogo de confirmación |
| Preguntar | ask | Requiere aprobación del usuario cada vez |
| Denegar | deny | No puede ejecutarse en absoluto (se rechaza con error) |
Los ajustes se gestionan oficialmente mediante settings.json. Usa ~/.claude/settings.json para ajustes de usuario, .claude/settings.json para reglas compartidas por el equipo y .claude/settings.local.json para sobrescrituras personales. ~/.claude.json todavía puede guardar estado como MCP, pero las reglas de permisos conviene tratarlas como configuración de settings.json.
Prioridad (de mayor a menor):
Managed settings
> Argumentos de línea de comandos
> Local .claude/settings.local.json
> Project .claude/settings.json
> User ~/.claude/settings.json
Las permission rules se fusionan entre scopes y se evalúan en orden deny -> ask -> allow
Estructura básica de settings.json
{
"permissions": {
"allow": [
"Read(**)",
"Glob(**)",
"Grep(**)",
"Bash(npm run *)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force*)"
],
"ask": [
"Write(**)",
"Edit(**)",
"Bash(git commit*)"
]
},
"hooks": {
"PreToolUse": [],
"PostToolUse": []
}
}
Nombres de herramientas y sintaxis de patrones
Los permisos se escriben en el formato “NombreHerramienta(patrón de argumento)”.
Lista de herramientas principales
| Nombre de herramienta | Descripción |
|---|---|
Read | Lectura de archivos |
Write | Creación de nuevos archivos |
Edit | Modificación parcial de archivos existentes |
Bash | Ejecución de comandos de shell |
Glob | Búsqueda por patrón de archivos |
Grep | Búsqueda de contenido |
WebFetch | Obtención de URL |
Agent | Inicio de sub-agente |
Sintaxis de patrones
"Read(**)" // Permitir lectura de todos los archivos
"Read(src/**)" // Permitir solo bajo src/
"Read(*.md)" // Permitir solo archivos .md
"Bash(npm run *)" // Permitir solo comandos que comiencen con npm run
"Bash(git *)" // Permitir todos los comandos git
"Bash(rm -rf *)" // Denegar rm -rf
** coincide con todas las rutas incluyendo directorios; * coincide con un único segmento.
Patrones prácticos
Patrón 1: Desarrollo individual (relativamente permisivo)
{
"permissions": {
"allow": [
"Read(**)",
"Glob(**)",
"Grep(**)",
"Bash(npm *)",
"Bash(git log*)",
"Bash(git diff*)",
"Bash(git status*)",
"Bash(git add*)",
"Bash(node *)",
"Bash(echo *)",
"Bash(cat *)",
"Bash(ls *)"
],
"deny": [
"Bash(rm -rf /)",
"Bash(rm -rf ~*)",
"Bash(git push --force *main*)",
"Bash(git push --force *master*)"
],
"ask": [
"Write(**)",
"Edit(**)",
"Bash(git commit*)",
"Bash(git push*)",
"Bash(rm *)"
]
}
}
Patrón 2: Desarrollo en equipo (orientado a la seguridad)
{
"permissions": {
"allow": [
"Read(**)",
"Glob(**)",
"Grep(**)",
"Bash(npm run lint)",
"Bash(npm run test)",
"Bash(npm run typecheck)",
"Bash(git log*)",
"Bash(git diff*)",
"Bash(git status*)",
"Bash(git branch*)"
],
"deny": [
"Bash(rm -rf*)",
"Bash(git push --force*)",
"Bash(git push -f*)",
"Bash(git reset --hard*)",
"Bash(git rebase *main*)",
"Bash(git rebase *master*)",
"Bash(DROP *)",
"Bash(TRUNCATE *)",
"Bash(curl * | bash)",
"Bash(wget * | sh)"
],
"ask": [
"Write(**)",
"Edit(**)",
"Bash(git commit*)",
"Bash(git push*)",
"Bash(git add*)",
"Bash(npm install*)",
"Bash(*deploy*)"
]
}
}
Patrón 3: Entorno de producción (solo lectura)
{
"permissions": {
"allow": [
"Read(**)",
"Glob(**)",
"Grep(**)",
"Bash(git log*)",
"Bash(git diff*)",
"Bash(git status*)",
"Bash(git show*)",
"Bash(cat *)",
"Bash(ls *)",
"Bash(ps *)",
"Bash(df *)",
"Bash(top *)"
],
"deny": [
"Write(**)",
"Edit(**)",
"Bash(git push*)",
"Bash(git commit*)",
"Bash(git reset*)",
"Bash(rm *)",
"Bash(mv *)",
"Bash(*deploy*)",
"Bash(*restart*)",
"Bash(*kill *)"
],
"ask": []
}
}
En trabajos de producción o casi producción, coloca esta configuración como .claude/settings.json activo y empieza con claude --permission-mode plan o con un dontAsk preaprobado. Esto se ajusta mejor al modelo oficial de scopes y permission modes que intercambiar un archivo alternativo mediante una variable de entorno.
Patrón 4: Solo generación de contenido (el patrón usado en este sitio)
{
"permissions": {
"allow": [
"Read(**)",
"Glob(**)",
"Grep(**)",
"Write(site/src/content/**)",
"Write(content/**)",
"Edit(site/src/content/**)",
"Edit(content/**)",
"Bash(git log*)",
"Bash(git diff*)",
"Bash(git status*)",
"Bash(node scripts/*)",
"Bash(QIITA_TOKEN=* node scripts/qiita-publish.mjs)"
],
"deny": [
"Bash(rm -rf*)",
"Bash(git push --force*)",
"Edit(.env*)",
"Read(.env*)"
],
"ask": [
"Bash(git add*)",
"Bash(git commit*)",
"Bash(git push*)",
"Bash(bash scripts/deploy.sh*)"
]
}
}
La clave es restringir las escrituras a un directorio específico, como con Write(site/src/content/**).
Hooks: Ejecutar procesos antes y después de los permisos
Los Hooks son un mecanismo que ejecuta comandos automáticamente antes y después de la ejecución de herramientas. Se pueden usar para verificaciones de seguridad y formateo automático.
PreToolUse: Hook previo a la ejecución
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash(git add*)",
"hooks": [{
"type": "command",
"command": "git diff --cached --name-only | grep -E '^\\.env' && echo '🚨 ¡Se detectó adición de .env!' && exit 1 || exit 0"
}]
},
{
"matcher": "Bash(git commit*)",
"hooks": [{
"type": "command",
"command": "node scripts/secret-scan.mjs"
}]
},
{
"matcher": "Bash(rm*)",
"hooks": [{
"type": "command",
"command": "echo '⚠️ Comando de eliminación detectado. Se ejecutará en 5 segundos. Ctrl+C para cancelar.' && sleep 5"
}]
}
]
}
}
Si un comando de hook devuelve el código de salida 1, la ejecución de la herramienta se bloquea. Este es el punto más importante.
PostToolUse: Hook posterior a la ejecución
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [{
"type": "command",
"command": "npx tsc --noEmit 2>&1 | head -20 || true"
}]
},
{
"matcher": "Bash(git commit*)",
"hooks": [{
"type": "command",
"command": "git log --oneline -3"
}]
}
]
}
}
PostToolUse se usa para verificaciones posteriores a la ejecución y efectos secundarios, por ejemplo, ejecutar automáticamente verificaciones de tipos después de editar archivos o mostrar las últimas 3 entradas del registro después de un commit.
Colección de recetas de Hooks prácticos
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash(npm install*)",
"hooks": [{
"type": "command",
"command": "echo '📦 Agregando paquete. Por favor revisa package.json.'"
}]
},
{
"matcher": "Bash(*deploy*)",
"hooks": [{
"type": "command",
"command": "read -p '🚀 A punto de desplegar. ¿Continuar? [y/N] ' ans && [ \"$ans\" = 'y' ] || exit 1"
}]
}
],
"PostToolUse": [
{
"matcher": "Write(*.ts)|Edit(*.ts)",
"hooks": [{
"type": "command",
"command": "npx eslint --fix $CLAUDE_TOOL_INPUT_FILE_PATH 2>/dev/null || true"
}]
}
]
}
}
Modos de permisos: Nivel de permiso al iniciar
También puedes especificar el modo al lanzar el comando claude.
# Modo normal (sigue settings.json)
claude
# Aprobar automáticamente todas las operaciones (¡peligroso! solo para entornos de confianza)
claude --dangerously-skip-permissions
# Omitir solo operaciones específicas
claude --allowedTools "Read,Grep,Glob"
# Modo no interactivo (usado en CI/CD)
claude -p "Ejecutar pruebas y reportar resultados" --dangerously-skip-permissions
--dangerously-skip-permissions debe usarse solo para automatización CI/CD o scripts de automatización completamente controlados, y evitarse en el uso interactivo diario.
2026: Permission budget seguro y revisión de equipo
Aquí permission budget no es un nombre oficial de función. Es el límite operativo de lo que permites ejecutar automáticamente durante la primera semana. Según la documentación oficial al 1 de junio de 2026, las permission rules se evalúan en orden deny -> ask -> allow. Los hooks PreToolUse agregan comprobaciones en tiempo de ejecución, pero no sustituyen un deny o ask que ya coincidió. Por eso el primer budget debe priorizar la reversibilidad antes que la velocidad.
Un budget inicial seguro es pequeño. En allow, deja solo lectura y verificación: Read, Glob, Grep, git status, git diff, git log, npm run lint y npm run test. En ask, pon operaciones que cambian intención: Edit, Write, git add, git commit, git push, npm install y deploy. En deny, pon lo irreversible o sensible: .env, secrets/**, rm -rf, git reset --hard, git push --force, curl | bash, wget | sh y comandos sobre bases de datos de producción. bypassPermissions solo pertenece a contenedores, VMs o devcontainers descartables.
En equipo, revisa .claude/settings.json como código de aplicación. Cada PR debe responder tres preguntas: si todo allow puede ejecutarse muchas veces sin daño, si cada ask representa una confirmación humana real, y si deny cubre secretos, force push, borrados y producción. En organizaciones con administración central, server-managed settings permite fijar disableBypassPermissionsMode y disableAutoMode como "disable", y usar allowManagedPermissionRulesOnly para impedir reglas locales o de proyecto.
Un fallo peligroso es permitir Bash(git *) o Bash(node *) de forma amplia y asumir que Read(.env*) basta para proteger secretos. La documentación oficial aclara que los deny de Read y Edit aplican a herramientas de archivo de Claude Code y a comandos reconocidos, pero no bloquean subprocesos arbitrarios, como scripts Node o Python, que abren archivos directamente. Para proteger secrets, evita Bash amplio y combínalo con sandbox, permisos del sistema operativo y checks PreToolUse.
Define la recuperación antes del incidente. Si aparece una edición no deseada, abre /permissions para ver la regla activa y su origen, revisa git diff y revierte con git restore -p para conservar cambios buenos. Para archivos no rastreados, ejecuta git clean -n antes de borrar. Si un secreto pudo leerse o entrar en el transcript, no basta con corregir .claude/settings.json: rota el token.
Para convertir este artículo en política de repositorio, empieza con permission budget loop y permission audit checklist. Si necesitas plantillas y material listo para usar, compara los productos de Claude Code. Para rollout de equipo, revisión de permisos y onboarding seguro, la consulta es mejor que improvisar reglas.
Prioridad y sobreescritura de archivos de configuración
Cuando existen múltiples archivos de configuración:
~/.claude/settings.json ← User (compartido entre proyectos)
.claude/settings.json ← Project (gestionado con git)
.claude/settings.local.json ← Local (personal, en gitignore)
managed-settings.json ← Managed (política de organización, máxima prioridad)
Las permission rules se fusionan y deny siempre se evalúa antes que allow
Escribe configuraciones adicionales personales en .claude/settings.local.json y agrégalo a gitignore. Para evitar que las listas de deny del equipo sean sobreescritas por configuraciones personales, el diseño seguro es escribir las reglas deny solo en settings.json.
# Agregar a .gitignore
.claude/settings.local.json
Los 5 errores más comunes
1. Equivocarse con los patrones de comodines
// ❌ Esto solo coincide con el único comando "git"
"Bash(git)"
// ✅ También coincide con git seguido de argumentos
"Bash(git *)"
"Bash(git*)" // También funciona sin espacio, pero * explícito es más seguro
2. Olvidar que deny tiene prioridad sobre ask
// Con esta configuración, Bash(rm -rf /tmp/test) es capturado por deny y bloqueado
// Nunca llega a ask
{
"deny": ["Bash(rm -rf*)"],
"ask": ["Bash(rm*)"] // ← rm -rf es manejado por deny
}
3. No prestar atención a los códigos de salida de los hooks
# Si el comando del hook PreToolUse siempre devuelve exit 0,
# los fallos de escaneo no bloquearán la ejecución
# ❌ Pasa incluso en caso de error
"command": "node scan.mjs"
# ✅ Controlar explícitamente el código de salida
"command": "node scan.mjs || exit 1"
4. Agregar accidentalmente settings.json a .gitignore
Algunos equipos agregan accidentalmente settings.json—que quieren compartir—a .gitignore. El enfoque correcto es configuración del proyecto bajo git, solo settings.local.json en gitignore.
5. Olvidar cambiar manualmente la configuración de producción
# ❌ Trabajando en producción con la configuración cotidiana
# ✅ Empezar en plan mode y mantener el .claude/settings.json del worktree seguro para producción
claude --permission-mode plan
Registrar un alias hace que sea más difícil olvidarlo:
# ~/.bashrc or ~/.zshrc
alias claude-prod='claude --permission-mode plan'
Depuración de la configuración
Cuando no está claro “por qué se está bloqueando este comando”:
# Verificar la configuración actual
claude --print-settings 2>/dev/null || cat .claude/settings.json
# Verificar qué regla está coincidiendo (modo verbose)
claude --verbose -p "Ejecutar git push"
Resumen: Mejores prácticas para el diseño de permisos
1. Empezar con deny
→ Listar comandos que nunca deben ejecutarse
→ rm -rf, git push --force, DROP TABLE son esenciales
2. Luego configurar ask
→ Operaciones de escritura y despliegue que requieren confirmación
3. Allow para todo lo demás
→ Operaciones de lectura y CI: allow para todo, por eficiencia
4. Automatizar la seguridad con Hooks
→ Escaneo pre-commit, type-check automático después de ediciones
5. Preparar archivos de configuración específicos por entorno
→ settings.json (desarrollo), settings.production.json (producción)
Con una configuración de permisos adecuada, dejarás de hacer clic mecánicamente en botones de aprobación y podrás concentrarte solo en las operaciones que realmente necesitan revisión. Dedicar 30 minutos al diseño inicial hará que cientos de horas futuras de trabajo sean más seguras.
Artículos relacionados
- Guía completa de seguridad para Claude Code
- 7 casos de fallos de seguridad en Claude Code
- Mejores prácticas de CLAUDE.md
Referencias
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.
Artículos relacionados
Recibo de verificación para Claude Code: build, URL pública, CTA y capturas
Flujo de verificación para cambios de Claude Code con diff, build, URL pública, CTA, capturas y ruta de ingresos.
Permission budget para Claude Code: avanzar seguro sin aprobar cada comando
Diseña un presupuesto de permisos para Claude Code y protege secretos, deploys, billing y datos sin frenar todo.
Mantenimiento de una biblioteca de prompts para Claude Code
Nombra, prueba y reutiliza prompts de Claude Code para convertirlos en una ruta fiable desde PDF gratuito hasta plantillas pagas.