Módulo 5: Skills y Hooks: automatizar tu workflow
Permission System: Control de acceso en Claude Code
Permission System: Control de acceso en Claude Code
Descripción
Claude Code es un agente que puede leer tu codebase, escribir archivos, ejecutar comandos en terminal, instalar paquetes, y hacer commits. Ese poder es lo que lo hace útil — y es exactamente lo que lo hace peligroso si no se controla. El permission system es el mecanismo que garantiza que Claude Code actúe solo dentro de los límites que tú defines.
Esta cápsula cubre el modelo de permisos de Claude Code: qué acciones requieren aprobación, cómo configurar niveles de confianza, qué hace el flag --dangerously-skip-permissions (y por qué su nombre es una advertencia), y cómo diseñar una política de permisos para proyectos reales donde la seguridad importa.
El permission system es el cierre natural de este módulo. Skills te dan control sobre qué hace Claude. Hooks te dan control sobre cómo se valida. Permissions te dan control sobre qué puede hacer Claude. Juntos, forman un sistema de gobernanza completo.
El modelo de permisos
Claude Code opera bajo un principio simple: pedir antes de actuar. Antes de ejecutar cualquier acción que modifique tu sistema, Claude te pide confirmación.
Acciones que requieren aprobación
| Acción | Riesgo | Aprobación por defecto |
|---|---|---|
| Leer archivos | Bajo | ✅ Automática (no pide) |
| Buscar en archivos (grep/glob) | Bajo | ✅ Automática |
| Escribir/editar archivos | Medio | ⚠️ Pide confirmación |
| Crear archivos nuevos | Medio | ⚠️ Pide confirmación |
| Ejecutar comandos en terminal | Alto | ⚠️ Pide confirmación |
| Instalar paquetes | Alto | ⚠️ Pide confirmación |
| Hacer requests HTTP | Medio | ⚠️ Pide confirmación |
| Operaciones git (commit, push) | Alto | ⚠️ Pide confirmación |
| Eliminar archivos | Alto | ⚠️ Pide confirmación |
Cómo se ve la solicitud de permiso
Cuando Claude quiere ejecutar una acción que requiere aprobación, muestra un prompt como este:
Claude wants to execute: npm test
Allow? [y/n/always]
Tus opciones:
| Opción | Qué hace |
|---|---|
y (yes) | Permite esta acción una vez |
n (no) | Bloquea esta acción |
always | Permite esta acción siempre (para esta sesión y futuras) |
El flujo de decisión
Claude quiere ejecutar una acción
│
▼
¿Está en allowedTools? ──── Sí ──▶ Ejecutar sin preguntar
│
No
│
▼
¿El usuario ya dijo "always"? ──── Sí ──▶ Ejecutar sin preguntar
│
No
│
▼
Mostrar prompt de permiso
│
├── y → Ejecutar (solo esta vez)
├── n → No ejecutar
└── always → Ejecutar + recordar para siempre
Niveles de permiso (modos)
Claude Code tiene 6 permission modes, de más restrictivo a más permisivo:
- Default (
default) — solo lecturas auto-aprobadas; pide confirmación para escrituras y comandos - Accept edits (
acceptEdits) — auto-aprueba escrituras a archivos; pide confirmación para comandos - Plan (
plan) — modo read-only para investigación y diseño antes de ejecutar - Auto mode (
auto) — classifier decide automáticamente (research preview, marzo 2026) - Don't ask (
dontAsk) — auto-aprueba un set explícito de tools que tú definiste, pregunta el resto - Bypass permissions (
bypassPermissions) — aprueba todo (--dangerously-skip-permissions)
Cambiar entre modos con Shift+Tab: el cycle por defecto rota entre default → acceptEdits → plan. Los modos auto y bypassPermissions se agregan al cycle si los habilitas explícitamente. dontAsk nunca aparece en el cycle (solo se activa por configuración). El modo actual se muestra en el footer.
Nivel 1: Ask every time (default)
Claude pide confirmación cada vez que quiere ejecutar una acción que modifica tu sistema.
Claude wants to write to: src/components/Button.tsx
Allow? [y/n/always]
Claude wants to execute: npm install axios
Allow? [y/n/always]
Claude wants to execute: git commit -m "Add Button"
Allow? [y/n/always]
Cuándo usarlo: Proyectos nuevos, codebases que no conoces bien, trabajo con agentes que no has verificado.
Nivel 2: Allow for session
Cuando respondes y a un permiso, Claude puede ejecutar esa acción específica en la sesión actual. En la siguiente sesión, volverá a preguntar.
Esto aplica cuando Claude te pide permiso y tú dices "sí" — no se recuerda entre sesiones.
Cuándo usarlo: La mayoría del desarrollo diario. Le dices "sí" a las acciones que esperas, y Claude deja de preguntar durante la sesión.
Nivel 3: Always allow (configurado en settings)
Configuras en settings qué herramientas Claude puede usar sin preguntar. Esto persiste entre sesiones.
{
"allowedTools": [
"Read",
"Grep",
"Glob",
"Write",
"Execute"
]
}
Cuándo usarlo: Después de establecer confianza. Proyectos personales donde sabes exactamente qué hace Claude. Workflows repetitivos donde las confirmaciones son fricción innecesaria.
Nivel 4: Auto Mode (research preview, marzo 2026)
El gran cambio de 2026: en vez de aprobar manualmente cada acción, Auto Mode pone un classifier delante de los permission prompts. Acciones seguras corren sin interrupción; acciones destructivas o sospechosas se bloquean y se te surfacean.
Es el punto medio entre:
- Ask every time (demasiada fricción para sesiones largas)
--dangerously-skip-permissions(demasiado riesgo — aprueba todo)
Cómo funciona el classifier:
Claude quiere ejecutar una acción
│
▼
Classifier evalúa riesgo
│
├── Acción segura (edit archivo de src/, run test) → ✅ Ejecuta sin preguntar
├── Acción dudosa (delete, force push) → ⚠️ Te surfacea para que decidas
└── Acción peligrosa (rm -rf /, sudo) → ❌ Bloquea
Activarlo:
# Durante una sesión: Shift+Tab para ciclar al modo auto
# Se ve en el footer: "auto mode on"
O configuralo como default en settings:
{
"permissions": {
"defaultMode": "auto"
}
}
Cuándo usarlo:
- Sesiones largas donde aprobar cada acción se vuelve ruido
- Developers que confían en el classifier para filtrar lo peligroso
- Como alternativa más segura a
--dangerously-skip-permissions
Cuándo NO usarlo:
- Proyectos críticos de producción donde cada acción necesita review humano
- Primera sesión con Claude en un codebase nuevo (mejor empezar con default)
- Cuando estás debuggeando comportamiento del agente
Requisitos para usar Auto Mode (mayo 2026):
- Plan: Max, Team, Enterprise o API directo. No disponible en Pro plan.
- Modelo: Sonnet 5 u Opus 5 en Team/Enterprise/API; Opus 5 en Max.
- Provider: solo Anthropic API directo. No funciona vía Bedrock, Vertex ni Foundry.
- Versión Claude Code: v2.1.83 o superior.
- Admin controls: en Team/Enterprise el admin debe habilitarlo explícitamente; puede bloquearlo con
permissions.disableAutoMode: "disable"en settings.
Comportamiento de fallback: si el classifier bloquea 3 acciones consecutivas o 20 totales en una sesión, Auto Mode se pausa y vuelve a prompts manuales. En modo headless (-p), bloqueos repetidos abortan la sesión completa.
Nota importante: Auto Mode sigue en research preview en mayo 2026. El classifier mejora con el tiempo pero no es infalible. Siempre revisa el output y los commits antes de pushear.
Configurar permisos en settings
Dónde se configuran
Los permisos se configuran en los mismos archivos de settings que los hooks:
| Archivo | Scope | Ejemplo de uso |
|---|---|---|
.claude/settings.json | Proyecto (compartido con equipo) | Permisos del proyecto para todo el equipo |
.claude/settings.local.json | Personal (no compartido) | Tus permisos personales |
Formato de allowedTools
{
"allowedTools": [
"Read",
"Write",
"Execute",
"Grep",
"Glob"
]
}
Cada entry en allowedTools es el nombre de una herramienta que Claude puede usar sin pedir permiso.
Herramientas configurables
| Herramienta | Qué permite |
|---|---|
Read | Leer archivos (ya permitido por defecto en la mayoría de configuraciones) |
Write | Escribir y editar archivos |
Execute | Ejecutar comandos en terminal |
Grep | Buscar contenido en archivos |
Glob | Buscar archivos por patrón |
WebFetch | Hacer peticiones HTTP |
Permisos granulares con patrones
Puedes ser más específico usando patrones en allowedTools:
{
"allowedTools": [
"Read",
"Grep",
"Glob",
"Write(src/**)",
"Execute(npm test)",
"Execute(npm run lint)",
"Execute(git status)",
"Execute(git diff)"
]
}
En este ejemplo:
- Claude puede leer y buscar archivos libremente
- Claude puede escribir solo en
src/(no en configs, no en scripts) - Claude puede ejecutar solo
npm test,npm run lint,git statusygit diffsin preguntar - Para cualquier otro comando, Claude pedirá permiso
Ejemplo: Configuración conservadora
{
"allowedTools": [
"Read",
"Grep",
"Glob"
]
}
Claude puede leer y buscar, pero pide permiso para todo lo demás. Ideal para proyectos sensibles.
Ejemplo: Configuración permisiva
{
"allowedTools": [
"Read",
"Write",
"Execute",
"Grep",
"Glob",
"WebFetch"
]
}
Claude tiene acceso completo sin preguntar. Solo para proyectos personales donde confías completamente en Claude.
Ejemplo: Configuración balanceada (recomendada)
{
"allowedTools": [
"Read",
"Grep",
"Glob",
"Write(src/**)",
"Write(tests/**)",
"Execute(npm test*)",
"Execute(npm run *)",
"Execute(git status)",
"Execute(git diff*)",
"Execute(git add *)",
"Execute(git log*)"
]
}
Claude puede leer, buscar, escribir código y tests, ejecutar scripts de npm, y ver el estado de git. Para commits, push, instalación de paquetes, y comandos fuera de npm/git, pide permiso.
El flag --dangerously-skip-permissions
Qué hace
claude --dangerously-skip-permissions
Este flag desactiva todo el sistema de permisos. Claude puede hacer cualquier cosa sin preguntar: escribir archivos, ejecutar comandos, instalar paquetes, eliminar directorios, hacer push a remote.
Por qué el nombre es una advertencia
El nombre --dangerously-skip-permissions no es casual. Es una advertencia explícita. Cuando usas este flag:
- ⚠️ Claude puede ejecutar
rm -rfsin preguntar - ⚠️ Claude puede hacer
git push --forcesin preguntar - ⚠️ Claude puede instalar paquetes maliciosos sin preguntar
- ⚠️ Claude puede modificar archivos de configuración del sistema sin preguntar
- ⚠️ Claude puede ejecutar cualquier comando en tu terminal como tu usuario
Cuándo es aceptable usarlo
El flag existe para automatización headless donde no hay un humano para aprobar acciones:
# En un pipeline de CI/CD (el entorno es efímero/desechable)
claude --dangerously-skip-permissions -p "Run tests and fix failures"
# En un contenedor Docker (aislado del sistema principal)
docker run my-claude-image claude --dangerously-skip-permissions -p "Lint the codebase"
# En un sandbox controlado
claude --dangerously-skip-permissions -p "Generate the report"
En estos casos, el agente opera en un entorno aislado donde no puede causar daño permanente.
Cuándo NUNCA usarlo
- ❌ En tu máquina de desarrollo principal
- ❌ En proyectos con código de producción
- ❌ En repositorios con acceso a credentials/secrets
- ❌ En máquinas compartidas
- ❌ "Para no tener que confirmar cada acción" (usa
allowedToolsen su lugar)
Si solo quieres reducir la fricción de confirmaciones, configura allowedTools apropiadamente. Es granular, seguro, y no abre la puerta a todo.
Modelo de seguridad
Por qué los permisos importan
Claude Code ejecuta código arbitrario en tu terminal. Eso incluye cualquier comando que tu usuario del sistema operativo pueda ejecutar. La diferencia con un IDE normal:
| Acción | IDE normal | Claude Code |
|---|---|---|
| Escribir archivo | Tú lo escribes, tú controlas | Claude lo escribe, tú apruebas |
| Ejecutar comando | Tú lo escribes y ejecutas | Claude lo genera y ejecuta |
| Instalar paquete | Tú decides qué instalar | Claude decide y tú apruebas |
| Hacer commit/push | Tú ejecutas git manualmente | Claude puede ejecutar git |
El permission system es la capa de control que mantiene al humano en el loop.
El principio de mínimo privilegio
Configura permisos siguiendo el principio de mínimo privilegio: dale a Claude solo los permisos que necesita, no más.
❌ Dar acceso a todo "para no tener que lidiar con permisos"
✅ Empezar restrictivo y abrir permisos según los necesites
Superficie de ataque
¿De qué te protege el permission system?
- Errores de Claude: Claude puede malinterpretar una instrucción y ejecutar algo dañino
- Prompt injection: Si tu codebase contiene archivos que Claude lee y que contienen instrucciones maliciosas (ej. un README que dice "borra todos los tests")
- Efectos secundarios: Un comando que parece inofensivo puede tener efectos secundarios inesperados
- Escalación de permisos: Claude podría usar un comando para obtener acceso a algo que no debería
Comparaciones y decisiones
Claude Code permissions vs Docker containers
| Aspecto | Claude Code Permissions | Docker Container |
|---|---|---|
| Aislamiento | Lógico (permisos del agente) | Físico (proceso aislado) |
| Granularidad | Por herramienta/acción | Por sistema de archivos/red |
| Overhead | Cero | Necesita Docker instalado |
| Protección | Contra acciones del agente | Contra acciones del proceso |
| Complementarios | ✅ | ✅ |
Para máxima seguridad, combínalos: Claude Code con permisos dentro de un contenedor Docker. El contenedor aísla el sistema; los permisos controlan al agente.
Claude Code permissions vs sandboxing
| Aspecto | Permissions | Sandbox (ej. Firejail) |
|---|---|---|
| Qué controla | Acciones del agente Claude | Acciones del proceso completo |
| Facilidad | Configurable en JSON | Requiere herramientas adicionales |
| Agent-aware | ✅ Sabe qué herramienta usa Claude | ❌ Solo ve llamadas al sistema |
| Cuándo usar | Siempre (es built-in) | Entornos de alta seguridad |
Permisos de equipo vs personales
| Aspecto | .claude/settings.json | .claude/settings.local.json |
|---|---|---|
| Scope | Todo el equipo | Solo tú |
| En git | ✅ Sí | ❌ No (en .gitignore) |
| Propósito | Baseline de seguridad del proyecto | Tus preferencias personales |
| Quién define | Tech lead / equipo | Cada developer |
Patrón recomendado:
settings.json (equipo):
allowedTools: [Read, Grep, Glob]
→ Baseline restrictivo
settings.local.json (personal):
allowedTools: [Read, Grep, Glob, Write(src/**), Execute(npm *)]
→ Más permisivo según tu confianza
El personal extiende al del equipo. Así cada developer puede ajustar su nivel de confianza sin afectar al equipo.
Best practices
1. Empieza restrictivo, abre según necesites
Día 1:
{
"allowedTools": ["Read", "Grep", "Glob"]
}
Después de 1 semana de uso:
{
"allowedTools": [
"Read", "Grep", "Glob",
"Write(src/**)",
"Execute(npm test*)"
]
}
Después de 1 mes:
{
"allowedTools": [
"Read", "Grep", "Glob",
"Write(src/**)", "Write(tests/**)",
"Execute(npm *)", "Execute(git status)", "Execute(git diff*)"
]
}
2. Usa session permissions para trabajo exploratorio
Cuando estás en una sesión de exploración o prototipado, di always a los prompts de permisos que apliquen. Eso los activa solo para la sesión — en la siguiente sesión vuelves al baseline.
3. Nunca skips permissions en codebases no confiables
Si clonas un repo que no es tuyo, no uses --dangerously-skip-permissions. Los archivos del repo podrían contener instrucciones que manipulen a Claude para ejecutar acciones dañinas (prompt injection vía archivos del codebase).
4. Separa permisos de proyecto vs personales
.claude/settings.json → Equipo: baseline restrictivo
.claude/settings.local.json → Personal: tu nivel de confianza
Siempre agrega settings.local.json a .gitignore.
5. Combina permissions con hooks
Los permisos son la primera línea de defensa. Los hooks son la segunda:
Permiso: Claude puede escribir en src/
Hook PreToolUse: Pero no si el archivo contiene secrets
Hook PostToolUse: Y después de escribir, ejecuta el linter
Es defensa en profundidad: capas de control que se complementan.
6. Documenta la política de permisos en CLAUDE.md
## Permisos
Este proyecto usa permisos restrictivos. Claude tiene permiso automático para:
- Leer y buscar archivos
- Escribir en src/ y tests/
- Ejecutar npm scripts
Para todo lo demás, Claude pedirá confirmación.
NO uses --dangerously-skip-permissions en este proyecto.
Patterns comunes
Pattern 1: Desarrollo personal
Para proyectos personales donde eres el único developer y confías en Claude:
{
"allowedTools": [
"Read", "Grep", "Glob",
"Write",
"Execute(npm *)",
"Execute(git add *)",
"Execute(git commit *)",
"Execute(git status)",
"Execute(git diff*)",
"Execute(git log*)",
"Execute(python *)",
"Execute(node *)"
]
}
Claude puede escribir en cualquier parte y ejecutar npm, git (sin push), Python, y Node. No puede hacer push, instalar paquetes globales, ni ejecutar comandos fuera de esa lista.
Pattern 2: Equipo con CI/CD
Para equipos donde CI/CD valida todo:
{
"allowedTools": [
"Read", "Grep", "Glob",
"Write(src/**)",
"Write(tests/**)",
"Execute(npm test*)",
"Execute(npm run lint*)"
]
}
Más restrictivo: Claude puede escribir código y tests, ejecutar tests y lint. Todo lo demás requiere aprobación. CI/CD se encarga de la validación completa en push.
Pattern 3: Proyecto sensible (fintech, healthcare)
Para proyectos con datos sensibles o requisitos de compliance:
{
"allowedTools": [
"Read",
"Grep",
"Glob"
]
}
Solo lectura automática. Todo lo demás requiere aprobación explícita. Cada acción de Claude queda documentada por la aprobación manual.
Pattern 4: CI/CD headless
Para pipelines automatizados donde Claude corre sin supervisión:
# En un contenedor Docker efímero
docker run --rm \
-v $(pwd):/workspace \
-e ANTHROPIC_API_KEY=$API_KEY \
claude-image \
claude --dangerously-skip-permissions \
-p "Run tests, fix any failures, and create a summary report"
El contenedor es efímero (se destruye después), así que el flag --dangerously-skip-permissions es aceptable. El daño máximo que Claude puede hacer está limitado por el contenedor.
Pitfalls y edge cases
Pitfall 1: Dar permisos amplios de Execute
El error:
{
"allowedTools": ["Execute"]
}
El problema: Execute sin patrón permite a Claude ejecutar cualquier comando: rm, curl, sudo, chmod, etc.
La solución: Siempre usa patrones con Execute:
{
"allowedTools": [
"Execute(npm *)",
"Execute(git status)",
"Execute(python -m pytest*)"
]
}
Pitfall 2: Confundir session permissions con settings
El error: Creer que decir always en un prompt de permiso configura los settings permanentemente.
La realidad: always en el prompt interactivo configura el permiso para la sesión. Para configuración permanente, edita settings.json.
Pitfall 3: Settings.local.json en git
El error: Olvidar agregar .claude/settings.local.json a .gitignore.
El problema: Tus permisos personales (posiblemente más permisivos) se comparten con el equipo.
La solución:
# .gitignore
.claude/settings.local.json
Pitfall 4: --dangerously-skip-permissions como "acceso directo"
El error: Usar el flag porque "estoy cansado de confirmar cada acción."
La solución: Configura allowedTools con las acciones que quieres pre-aprobar. Es igual de rápido pero mucho más seguro.
Pitfall 5: No revisar los permisos del equipo
El error: Cada developer configura sus permisos independientemente, sin baseline del equipo.
La solución: Define settings.json como baseline del equipo:
{
"allowedTools": ["Read", "Grep", "Glob"]
}
Cada developer puede extender en settings.local.json, pero el baseline del proyecto es restrictivo.
Ejemplo completo integrado
Escenario: configuras una política de permisos para un equipo de 5 developers trabajando en un proyecto full-stack.
settings.json (compartido con el equipo)
{
"allowedTools": [
"Read",
"Grep",
"Glob",
"Write(src/**)",
"Write(tests/**)",
"Write(docs/**)",
"Execute(npm test*)",
"Execute(npm run lint*)",
"Execute(npm run format*)",
"Execute(git status)",
"Execute(git diff*)",
"Execute(git log*)"
],
"hooks": {
"PreToolUse": [
{
"matcher": "Write",
"command": "./scripts/hooks/security-check.sh"
},
{
"matcher": "Execute",
"command": "./scripts/hooks/safety-gate.sh"
}
],
"PostToolUse": [
{
"matcher": "Write",
"command": "./scripts/hooks/format.sh"
},
{
"matcher": "Write",
"command": "./scripts/hooks/lint.sh"
}
]
}
}
settings.local.json (developer senior, personal)
{
"allowedTools": [
"Read",
"Grep",
"Glob",
"Write",
"Execute(npm *)",
"Execute(git *)",
"Execute(docker *)",
"Execute(python *)"
]
}
settings.local.json (developer junior, personal)
{
"allowedTools": [
"Read",
"Grep",
"Glob",
"Write(src/**)",
"Write(tests/**)",
"Execute(npm test*)",
"Execute(npm run *)"
]
}
CLAUDE.md (sección de permisos)
## Política de permisos
### Baseline del proyecto (settings.json)
- Claude puede leer y buscar archivos libremente
- Claude puede escribir en src/, tests/, y docs/
- Claude puede ejecutar npm test, npm run lint, npm run format
- Claude puede ver estado de git (status, diff, log)
- Todo lo demás requiere aprobación
### Para developers
- Configura tu nivel personal en .claude/settings.local.json
- NO uses --dangerously-skip-permissions
- Si necesitas un permiso que no está en el baseline, pídelo al equipo
### Hooks de seguridad
- PreToolUse: security check (bloquea secrets) + safety gate (bloquea comandos peligrosos)
- PostToolUse: format + lint automáticos
Flujo en acción
Developer junior:
> "Agrega validación al endpoint de login"
Claude quiere escribir src/routers/auth.py
→ allowedTools incluye Write(src/**) → ✅ Procede sin preguntar
→ Hook security-check.sh → ✅ No hay secrets
→ Claude escribe el archivo
→ Hook format.sh → Prettier formatea
→ Hook lint.sh → ESLint valida → 0 errores
Claude quiere ejecutar npm test
→ allowedTools incluye Execute(npm test*) → ✅ Procede sin preguntar
Claude quiere ejecutar git commit
→ No está en allowedTools → ⚠️ Pide permiso
Developer: "y" (sí, esta vez)
Claude hace el commit.
Ejercicios prácticos
Ejercicio 1: Básico — Configurar permisos conservadores
Configura una política de permisos conservadora para un proyecto nuevo.
Requisitos:
- Claude puede leer y buscar libremente
- Claude puede escribir solo en
src/ytests/ - Claude puede ejecutar solo
npm testynpm run lint - Todo lo demás requiere aprobación
Solución
Crea .claude/settings.json:
{
"allowedTools": [
"Read",
"Grep",
"Glob",
"Write(src/**)",
"Write(tests/**)",
"Execute(npm test*)",
"Execute(npm run lint*)"
]
}
Verifica: pide a Claude que escriba un archivo en la raíz del proyecto (debería pedir permiso) y luego en src/ (no debería pedir permiso).
Ejercicio 2: Básico — Permisos personales
Configura tus permisos personales que extiendan el baseline del proyecto.
Requisitos:
- Extiende el baseline con permiso para ejecutar git (status, diff, add, commit)
- Agrega permiso para ejecutar scripts de npm
- Mantén las restricciones de escritura del baseline
- Agrega
settings.local.jsona.gitignore
Solución
Crea .claude/settings.local.json:
{
"allowedTools": [
"Read",
"Grep",
"Glob",
"Write(src/**)",
"Write(tests/**)",
"Execute(npm *)",
"Execute(git status)",
"Execute(git diff*)",
"Execute(git add *)",
"Execute(git commit *)",
"Execute(git log*)"
]
}
Agrega a .gitignore:
.claude/settings.local.json
Ejercicio 3: Intermedio — Política de equipo
Diseña una política de permisos para un equipo de 3 personas: 1 tech lead, 1 senior, 1 junior.
Requisitos:
- Baseline del proyecto restrictivo (en
settings.json) - Cada rol tiene un
settings.local.jsondiferente - El junior no puede ejecutar git push ni instalar paquetes
- El senior puede hacer git commit pero no push
- El tech lead puede hacer push a branches (no a main)
- Documenta la política en CLAUDE.md
Solución
settings.json (baseline):
{
"allowedTools": [
"Read", "Grep", "Glob",
"Write(src/**)", "Write(tests/**)",
"Execute(npm test*)", "Execute(npm run lint*)"
]
}
Junior settings.local.json:
{
"allowedTools": [
"Read", "Grep", "Glob",
"Write(src/**)", "Write(tests/**)",
"Execute(npm test*)", "Execute(npm run *)",
"Execute(git status)", "Execute(git diff*)"
]
}
Senior settings.local.json:
{
"allowedTools": [
"Read", "Grep", "Glob",
"Write(src/**)", "Write(tests/**)", "Write(docs/**)",
"Execute(npm *)",
"Execute(git status)", "Execute(git diff*)",
"Execute(git add *)", "Execute(git commit *)",
"Execute(git log*)"
]
}
Tech lead settings.local.json:
{
"allowedTools": [
"Read", "Grep", "Glob",
"Write",
"Execute(npm *)",
"Execute(git *)"
]
}
Ejercicio 4: Intermedio — Permisos + Hooks combinados
Configura un sistema donde los permisos y los hooks se complementen:
- Permisos permiten escritura en
src/ - Hook PreToolUse bloquea escritura si contiene secrets
- Hook PostToolUse ejecuta lint después de escribir
- Permiso permite
npm testsin preguntar
Solución
{
"allowedTools": [
"Read", "Grep", "Glob",
"Write(src/**)",
"Execute(npm test*)"
],
"hooks": {
"PreToolUse": [
{
"matcher": "Write",
"command": "./scripts/hooks/security-check.sh"
}
],
"PostToolUse": [
{
"matcher": "Write",
"command": "./scripts/hooks/lint.sh"
}
]
}
}
Los permisos abren la puerta (Write en src/). Los hooks validan lo que pasa por esa puerta (no secrets, lint limpio). Es defensa en profundidad.
Ejercicio 5: Avanzado — Auditoría de permisos
Crea un script que muestre los permisos activos de tu proyecto (Claude Code no tiene un hook de inicio de sesión, pero puedes ejecutar este script manualmente o integrarlo en un hook PostToolUse como auditoría).
Requisitos:
- Lee
.claude/settings.jsony.claude/settings.local.json - Muestra qué herramientas están pre-aprobadas
- Muestra si hay hooks configurados
- Muestra advertencia si los permisos son muy amplios
Solución
Crea scripts/hooks/audit-permissions.sh:
#!/bin/bash
echo "=== Permisos activos ==="
# Leer settings del proyecto
if [ -f ".claude/settings.json" ]; then
echo "📋 Proyecto (settings.json):"
grep -o '"[A-Za-z]*\([^"]*\)\?"' .claude/settings.json 2>/dev/null | while read -r tool; do
echo " ✅ $tool"
done
fi
# Leer settings personales
if [ -f ".claude/settings.local.json" ]; then
echo ""
echo "👤 Personal (settings.local.json):"
grep -o '"[A-Za-z]*\([^"]*\)\?"' .claude/settings.local.json 2>/dev/null | while read -r tool; do
echo " ✅ $tool"
done
fi
# Advertencia si Execute sin patrón está permitido
if grep -q '"Execute"' .claude/settings.json .claude/settings.local.json 2>/dev/null; then
echo ""
echo "⚠️ ADVERTENCIA: Execute sin patrón está permitido (todos los comandos)"
fi
# Verificar hooks
if grep -q '"hooks"' .claude/settings.json 2>/dev/null; then
echo ""
echo "🪝 Hooks configurados: ✅"
else
echo ""
echo "🪝 Hooks: ❌ No configurados"
fi
echo "========================"
chmod +x scripts/hooks/audit-permissions.sh
Nota: Claude Code expone el evento SessionStart para este caso — puedes configurarlo en .claude/settings.json para ejecutar el script automáticamente al inicio de cada sesión. Alternativamente, córrelo manualmente (./scripts/hooks/audit-permissions.sh) o referéncialo desde un skill que invocas con /audit-permissions.
Ejercicio 6: Challenge — Sistema completo de gobernanza
Configura un sistema completo que combine Skills, Hooks y Permissions para un proyecto:
- 3 skills (create-component, write-test, review-code)
- Hooks con los 5 eventos reales (PreToolUse, PostToolUse, Notification, Stop, SubagentStop)
- Permisos (settings.json baseline + settings.local.json personal)
- Documentación en CLAUDE.md
Entregable: El directorio .claude/ completo con skills, settings, scripts de hooks, y la sección de permisos en CLAUDE.md.
Guía
Estructura final:
.claude/
├── skills/
│ ├── create-component.md
│ ├── write-test.md
│ └── review-code.md
├── settings.json
└── settings.local.json
scripts/hooks/
├── session-start.sh
├── security-check.sh
├── safety-gate.sh
├── format.sh
├── lint.sh
└── task-summary.sh
Usa los ejemplos de las cápsulas 02, 03, 04 y 05 de este módulo como referencia. Adapta todo a las convenciones de tu proyecto.
Verifica que:
- Los skills se invocan correctamente con
/nombre - Los hooks se ejecutan en los momentos correctos
- Los permisos bloquean lo que deben bloquear
- La documentación en CLAUDE.md es clara para un nuevo developer del equipo
Resumen
Lo que aprendiste en esta cápsula:
- Claude Code pide antes de actuar: por defecto, cada acción que modifica tu sistema requiere aprobación
- 3 niveles de permiso: ask every time (default), session permission (temporal), always allow (settings)
allowedToolsen settings.json configura permisos permanentes con patrones granulares--dangerously-skip-permissionsdesactiva todo el sistema. Solo para automatización en entornos aislados (contenedores, CI/CD)- Principio de mínimo privilegio: empieza restrictivo, abre según necesites
- Permisos de equipo vs personales:
settings.json(equipo) +settings.local.json(personal) - Defensa en profundidad: permissions (qué puede hacer) + hooks (qué se valida) + CI/CD (qué se verifica en push)
Resumen del módulo completo
Has completado el Módulo 5: Skills y Hooks. Esto es lo que ahora sabes hacer:
| Cápsula | Qué aprendiste |
|---|---|
| 01 — Introducción | Mental model: Skills = comandos, Hooks = automatización, Permissions = control |
| 02 — Skills | Crear slash commands en .claude/skills/ para tareas repetitivas |
| 03 — Hooks | Configurar scripts automáticos en los 5 eventos del ciclo de vida |
| 04 — Validaciones | Construir pipelines de calidad con lint, format, tests, y security checks |
| 05 — Permissions | Controlar qué puede hacer Claude con niveles de permiso granulares |
Tu Claude Code ya no es genérico. Tiene skills personalizados, hooks de validación, y permisos configurados para tu proyecto. Es una herramienta a medida.
Siguiente módulo: 06 - Subagents — delegar trabajo a agentes especializados. Si Skills y Hooks son cómo Claude Code trabaja para ti, los subagents son cómo Claude Code delega trabajo a otros agentes.
Recursos adicionales
Documentación oficial
- Settings — Configuración completa de permisos y scopes
- Hooks — Hooks como complemento de permisos
- Interactive Mode — Permisos interactivos y shortcuts
- Headless Mode — Uso de
--dangerously-skip-permissionsen automatización
Seguridad
- Claude Code Best Practices — Recomendaciones de seguridad de Anthropic
- Plugins Reference — Cómo permisos interactúan con plugins
Complementarios
- CLI Reference — Flags de línea de comandos incluyendo
--dangerously-skip-permissions - GitHub Actions — Permisos en CI/CD