Guía completa de permisos de Claude Code | settings.json, Hooks y Allowlist explicados
Guía completa de permisos de Claude Code. Aprende a usar allow/deny/ask, automatización con Hooks, settings.json por entorno y patrones prácticos, todo 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 escriben en .claude/settings.json. Colocarlo en la raíz del proyecto permite compartirlo con el equipo mediante git; colocarlo en ~/.claude.json lo convierte en una configuración global.
Prioridad (de mayor a menor):
Proyecto .claude/settings.json
> Global ~/.claude.json
> Por defecto (todo es ask)
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 producción, esto se especifica con CLAUDE_SETTINGS=.claude/settings.production.json claude.
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.
Prioridad y sobreescritura de archivos de configuración
Cuando existen múltiples archivos de configuración:
~/.claude.json ← Global (compartido entre todos los proyectos)
+
.claude/settings.json ← Proyecto (gestionado con git)
+
.claude/settings.local.json ← Sobreescrituras personales (gitignore recomendado)
=
Se aplica la configuración combinada
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
# ✅ Cambiar explícitamente la configuración antes de trabajar en producción
CLAUDE_SETTINGS=.claude/settings.production.json claude
Registrar un alias hace que sea más difícil olvidarlo:
# ~/.bashrc or ~/.zshrc
alias claude-prod='CLAUDE_SETTINGS=.claude/settings.production.json claude'
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
Lleva tu flujo con Claude Code al siguiente nivel
50 plantillas de prompts probadas en producción, listas para copiar y pegar en Claude Code.
PDF gratuito: Hoja de trucos de Claude Code en 5 minutos
Solo deja tu correo y te enviaremos al instante la hoja de trucos en una página A4.
Cuidamos tus datos personales y nunca enviamos spam.
Sobre el autor
Masa
Ingeniero apasionado por Claude Code. Dirige claudecode-lab.com, un medio tecnológico en 10 idiomas con más de 2.000 páginas.
Artículos relacionados
Guía Completa de Seguridad para Claude Code: Claves API, Permisos y Protección en Producción
Guía práctica de seguridad para usar Claude Code de forma segura. Desde la gestión de claves API hasta la configuración de permisos, automatización con Hooks y protección del entorno de producción — con ejemplos de código funcionales.
7 Casos de Fallo de Seguridad con Claude Code | Incidentes Reales y Prevención
Siete incidentes de seguridad reales con Claude Code: filtraciones de .env, eliminación de BD en producción, explosiones de facturación y más — con análisis de causa raíz y código de prevención.
Guía completa de harness engineering: cómo construir agentes de IA al estilo Claude Code
Un buen prompt no basta para dominar un LLM. Aprende a entrelazar herramientas, contexto y bucles de control en un harness, con código funcional y la arquitectura de Claude Code como guía.