Configuración de permisos: Cuánto sueltas y cuánto aprietas, tú decides
📚 Navegación de la serie: El artículo anterior 19 Gestión de contexto te enseñó cómo manejar la "mesa de trabajo" de Claude y evitar que se sature su memoria. Este artículo cambia de dimensión: ya no se trata de "cuánto recuerda", sino de "cuánto se atreve a tocar". Desde pedirte permiso para cada línea de comando hasta darle total libertad, cuán apretadas llevas las riendas es decisión tuya.
"¿Cómo te atreves a usar --dangerously-skip-permissions? La palabra 'dangerous' (peligroso) está literalmente en el nombre."
"Estoy en un sandbox, ¿de qué voy a tener miedo? Incluso si le hace rm -rf a todo el directorio, solo borra un contenedor de un solo uso; se crea otro y listo."
Yo mismo he estado en ambos lados de esta conversación: ejecutando refactorizaciones masivas en contenedores aislados en la nube con el modo peligroso activado sin pensarlo dos veces, borrando y empezando de nuevo sin cargo de conciencia; pero cuando vuelvo a mi máquina local, al directorio con el código real del equipo, dudo un par de segundos incluso antes de usar acceptEdits. Resumiendo: no hay "bien o mal" con los permisos, solo "dónde los usas". El mismo modo peligroso que es un "acelerador" en un contenedor aislado, es una "bomba de relojería" en la máquina que tiene el código en producción.
En el artículo 07 tuvimos un pequeño adelanto: Claude se detiene para preguntarte antes de modificar archivos. Pero eso es solo la punta del iceberg. Hoy revelaremos el iceberg entero: cuáles son los modos de permiso de Claude Code, cómo cambiarlos con un clic, y cómo usar archivos de configuración para definir con precisión "puedes hacer esto, pero nunca aquello".
Al terminar este artículo, sabrás:
- Cuáles son los seis modos de permiso, y en qué escenarios usarlos (resumido en una tabla).
- Cómo usar la memoria muscular de
Shift+Tabpara cambiar de modo, y cómo especificar el modo directamente al iniciar. - La sintaxis en
settings.jsonpara definir reglas deallow,askydeny, con control detallado por herramienta y comando. - Dos plantillas de configuración listas para usar: "Relajada para proyectos personales" y "Estricta para proyectos en producción".
- Cuándo atreverse realmente a usar
--dangerously-skip-permissions, y dónde está la línea roja.
01 Primero lo primero: ¿Qué controla el sistema de permisos?
Primero, la conclusión: Por defecto, Claude Code es un "becario que pregunta antes de actuar", y la configuración de permisos es el "código de conducta" que tú le pones.
El sistema clasifica todas las acciones en tres tipos, que por defecto reciben un trato completamente diferente. Esta tabla de la documentación oficial es la base para entender todo lo que sigue:
| Tipo de herramienta | Ejemplos | ¿Requiere aprobación por defecto? |
|---|---|---|
| Solo lectura | Leer archivos, buscar con Grep | No, pasa automáticamente |
| Comandos Bash | Ejecutar comandos shell | Sí |
| Modificación de archivos | Editar con Edit / Write | Sí |
Analogía: ¿Te pregunta el becario antes de meter mano? A un buen becario, si le dices "échale un ojo a este código", va y lo mira sin problemas (solo lectura, riesgo cero). Pero si va a "modificar la configuración de producción" o "ejecutar un comando de borrado", lo normal es que levante la cabeza y te diga: "Jefe, ¿puedo tocar esto?". Por defecto, Claude Code actúa igual: leer es libre, pero para modificar hay que reportarse antes.
Hay un concepto clave aquí, en el que yo mismo caí: Los permisos los impone a la fuerza el programa Claude Code, no es algo que dependa de la "buena voluntad del modelo".
En su momento escribí en mi CLAUDE.md: "No ejecutes git push", pensando que así lo bloqueaba; pero una vez hizo un push sin dudarlo. ¿Por qué? Porque CLAUDE.md es solo una indicación "suave" sobre "qué debe intentar hacer", pero las restricciones estrictas deben ir en las reglas de permisos. No fue hasta que puse esa regla en deny que se estuvo quieto. La documentación oficial es clara:
Las reglas de permisos son aplicadas forzosamente por Claude Code, no por el modelo. Tus prompts o instrucciones en
CLAUDE.mdafectarán a las acciones que Claude intente, pero no cambiarán lo que Claude Code permita ejecutar.
Recuerda esto, y sabrás dónde debes construir tu "línea de defensa".
💡 Resumen en una frase: Leer es libre, actuar requiere aprobación, esa es la regla por defecto; si quieres bloquear de verdad una operación, tienes que usar las reglas de permisos, decírselo en
CLAUDE.mdno basta.
02 Los seis modos de permiso: Del "preguntar paso a paso" al "haz lo que quieras"
El modo de permisos (permission mode) controla una cosa: la "frecuencia" con la que Claude se detiene a preguntarte antes de actuar. Desde "parar y esperar a que asientas en cada paso" hasta "hacer sin preguntar nada", es un espectro continuo.
Analogía: Seguimos con el becario, el modo es su "nivel de autonomía". El primer día, pregunta por cada cosa (default); cuando tiene más experiencia, modifica código sin preguntar, pero para borrar la base de datos te llama (acceptEdits); si te vas de viaje y confías ciegamente en él, le dejas que se las arregle solo (bypassPermissions).
Oficialmente hay seis modos. Aquí tienes una tabla que resume "¿Preguntará antes de hacer algo?" y "Escenarios ideales" para cada uno. Esta es la tabla más importante que debes memorizar:
| Modo | Cosas que puede hacer sin preguntar | ¿Preguntará antes de actuar? | Escenario ideal |
|---|---|---|---|
default | Solo lectura | Pregunta para modificar archivos y ejecutar comandos | Empezando, tareas delicadas |
acceptEdits | Solo lectura + edición de archivos + comandos de sistema comunes (mkdir, mv, cp, etc.) | No pregunta para editar archivos ni comandos comunes, pregunta para otros Bash | Iterar rápido sobre código que estás revisando |
plan | Solo lectura (investiga y planea, no toca tu código) | Mismas reglas que default | Investigar y planear antes de tocar nada |
auto | Todo, pero con un clasificador de seguridad en segundo plano | Raramente pregunta, el clasificador bloquea excesos | Tareas largas, menos interrupciones (versión preview de investigación) |
dontAsk | Solo herramientas aprobadas de antemano | No pregunta ni se detiene, rechaza directamente lo no aprobado | CI/CD bloqueado, scripts |
bypassPermissions | Todo, se salta todos los chequeos | No pregunta nada en absoluto | Solo contenedores aislados / VMs |
Algunos puntos donde los novatos suelen confundirse, para aclararlos:
plan (Plan Mode) no es más "relajado", de hecho es el más conservador. Hace que Claude solo lea archivos y ejecute comandos de solo lectura para entender el contexto, y luego te dé un plan de "así es como pienso cambiarlo", sin modificar ni una coma de tu código fuente. Para cualquier proyecto desconocido, el primer paso siempre debería ser usar plan para que se lo lea entero, es mucho más seguro que dejarle cambiar cosas a ciegas.
acceptEdits es el punto dulce para el día a día. Aprueba automáticamente la edición de archivos de tu directorio de trabajo y varios comandos de sistema comunes (mkdir, touch, rm, rmdir, mv, cp, sed), pero te sigue preguntando para otros comandos shell o si intenta escribir fuera del directorio. Es como decir "no me preguntes para cada línea de código que cambies, pero las acciones peligrosas sí necesitan mi permiso".
auto y bypassPermissions pueden parecer que "no preguntan", pero su seguridad es muy diferente. auto es una versión previa de investigación, tiene un modelo clasificador independiente que revisa cada acción; si se pasa de la raya (por ejemplo curl | bash, hacer push a main, o borrar almacenamiento en la nube), lo bloquea. bypassPermissions es correr desnudo por la calle, no te protege ni contra inyección de prompts. La documentación oficial es muy clara:
bypassPermissionsno ofrece protección contra inyección de prompts o acciones accidentales. Para verificaciones de seguridad en segundo plano sin preguntas, usa en su lugar el modo auto.
Por lo tanto, si quieres "tranquilidad pero con un límite de seguridad", usa auto, no te vayas directo a bypassPermissions.
💡 Resumen en una frase:
defaultpregunta todo,acceptEditsno pregunta para código,plansolo mira,autotiene red de seguridad,bypassPermissionsno tiene red. Recuerda este espectro de estricto a relajado y elige el que te convenga.

Esta imagen muestra los seis modos en un espectro "de más estricto a más relajado": la zona verde a la izquierda con plan / default (solo lectura, preguntar siempre, lo más seguro), pasando por acceptEdits y auto, hasta llegar a la zona roja de la derecha con bypassPermissions (correr desnudo); el rojo te avisa de que "cuanto más relajado, más cuidado debes tener".
03 Cambiar de modo: Shift+Tab para alternar rápidamente
Ya conoces los modos, ¿cómo los cambias? La forma más común es con un simple atajo: Shift+Tab.
Si pulsas Shift+Tab mientras estás en la sesión, irás rotando por tres modos:
default → acceptEdits → plan → (vuelve a default)Puedes ver en qué modo estás mirando la barra de estado. Por ejemplo, al pasar a acceptEdits, verás en la barra algo como ⏵⏵ accept edits on.
Presta atención a un detalle de la documentación oficial, para que no te vuelvas loco buscando un modo: la rotación por defecto solo incluye default / acceptEdits / plan. Para entrar a los otros tres, hay métodos diferentes: auto aparecerá en la rotación automáticamente si tu cuenta cumple los requisitos; bypassPermissions requiere usar el parámetro de inicio --permission-mode bypassPermissions para entrar en el ciclo; dontAsk nunca entra en la rotación, solo se puede establecer con el parámetro de inicio --permission-mode dontAsk (lo veremos a continuación).
Analogía: Es como el interruptor "Sonido / Vibración / Silencio" de tu móvil. Usas ese botón para moverte por esos tres estados. Shift+Tab es el botón de Claude Code; al pulsarlo cambias entre "Preguntar siempre / No preguntar para código / Solo mirar".
Si no quieres tener que cambiarlo manualmente cada vez que entras, tienes dos formas de dejar el modo "fijo":
Forma 1: Especificarlo al iniciar mediante parámetros (solo vale para esa sesión):
claude --permission-mode planPuedes cambiar plan por acceptEdits, dontAsk u otro. bypassPermissions es un poco especial: la forma --permission-mode bypassPermissions equivale a --dangerously-skip-permissions, pero en el día a día se suele usar el segundo porque su nombre ya es una advertencia, como veremos en la sección 05.
Forma 2: Dejarlo como predeterminado en settings.json (se aplica siempre al arrancar). En el .claude/settings.json de tu proyecto:
{
"permissions": {
"defaultMode": "acceptEdits"
}
}⚠️ Una restricción de la que avisa la documentación oficial: Si pones
defaultModecomo"auto", la configuración del proyecto y la local se ignoran (para evitar que un repositorio active el modo automático a escondidas). Para usarautopor defecto, tienes que ponerlo en el archivo a nivel de usuario~/.claude/settings.json.
Un consejo útil: no fijes el modo en la configuración del proyecto, hazlo siempre a mano con Shift+Tab. A veces querrás que trabaje rápido (en acceptEdits) y otras solo querrás un plan (en plan), fijarlo es engorroso. defaultMode solo suele ponerse en default cuando se trata de un proyecto en el que hay que ser estricto sí o sí.
💡 Resumen en una frase: Dentro de la sesión,
Shift+Tabrota entre "preguntar todo / no preguntar código / solo mirar", mira la barra de estado; si quieres fijar un modo, usa--permission-modeal inicio odefaultModeensettings.json.
04 Control preciso: las reglas allow / ask / deny
El modo es un ajuste "grueso", fija la línea general. Para un ajuste "fino", para poder decir exactamente "puedes ejecutar este comando pero aquel no", están las tres reglas de settings.json.
Cada regla se traduce finalmente en una de estas tres acciones:
| Acción | Efecto | Uso típico |
|---|---|---|
allow | Paso automático sin aprobación | Operaciones frecuentes de bajo riesgo (ej: git status, npm run build) |
ask | Muestra aviso para que tú decidas | Algo de riesgo que requiere confirmación (ej: git push) |
deny | Bloqueado por completo, ni se ejecuta ni avisa | Operaciones prohibidas y peligrosas (ej: rm -rf, leer .env) |
La prioridad es estricta: deny → ask → allow, gana la primera regla que coincida. Por lo tanto, deny siempre manda. Si escribes una regla en allow y otra en deny, gana el deny. Y tiene sentido: "prohibir" debe tener más peso que "permitir".
Las reglas se escriben poniendo NombreHerramienta o NombreHerramienta(especificación). Algunos ejemplos:
| Regla | Qué coincide |
|---|---|
Bash | Todos los comandos de Bash |
Bash(npm run build) | Solo el comando exacto npm run build |
Bash(npm run *) | Todos los comandos que empiezan por npm run (como build, test...) |
Read(./.env) | Leer el archivo .env del directorio actual |
WebFetch(domain:github.com) | Solicitudes de red a github.com |
El comodín * tiene un detalle con el espacio en el que los novatos siempre caen, y que la documentación oficial enfatiza:
Bash(ls *)coincide conls -lapero no conlsof, mientras queBash(ls*)coincide con ambos.
Un solo espacio cambia el significado. ls * (con espacio) exige que haya un espacio tras ls, dejando fuera a lsof; ls* (sin espacio) incluye a lsof. Para ser preciso, incluye el espacio.
Aquí tienes una configuración completa, que permite usar npm y git commit, pero bloquea git push:
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git commit *)"
],
"deny": [
"Bash(git push *)"
]
}
}Y un último detalle crítico de seguridad: las reglas de deny para Read / Edit no bloquean la lectura/escritura "indirecta" realizada desde un subproceso de Bash.
¿Qué quiere decir esto? Si tienes deny: Read(./.env) para evitar que Claude lea el .env directamente, pero él lanza un script en Python como open('.env').read(), ese deny no sirve de nada, porque la lectura la hace el subproceso de Python, no la herramienta interna de Claude. La documentación oficial avisa:
No se aplican a subprocesos arbitrarios que lean o escriban archivos de forma indirecta, como un script de Python o Node abriendo el archivo. Para forzar a nivel del SO e impedir que todos los procesos accedan a una ruta, usa el sandbox (caja de arena).
Es fácil sorprenderse por esto, pensando que un deny .env es seguro. Si realmente quieres blindar archivos sensibles, usa reglas de permisos + Sandbox juntos para una defensa en profundidad (el sandbox es el aislamiento a nivel de sistema operativo, entraremos en detalle en el próximo artículo de "Seguridad").
💡 Resumen en una frase: La prioridad es
deny → ask → allow, dondedenysiempre manda; ten cuidado con los espacios en las reglas; perodenyno detiene los scripts indirectos, los archivos delicados requieren Sandbox.
05 Relajado para juguetes, estricto para producción: Dos plantillas + línea roja del "modo peligroso"
Después de tanta teoría, vayamos al grano: cuanto más "juguete" sea el proyecto, más te puedes relajar; cuanto más "en producción" esté, más debes apretar.
Te dejo dos configuraciones listas para usar, escoge según el proyecto.
Plantilla 1: Proyecto de juguete / personal (Relajado para ir rápido). Si lo rompes, lo vuelves a crear, no pasa nada. Usa acceptEdits para que no te pregunte al modificar código, y pon un par de restricciones clave en deny:
{
"permissions": {
"defaultMode": "acceptEdits",
"deny": [
"Bash(rm -rf *)",
"Bash(git push *)"
]
}
}Plantilla 2: Producción / Proyecto de empresa (Estricto como control). Por defecto, te pregunta todo. Deja la lectura libre para que pueda explorar, pero para escribir o usar comandos peligrosos, tendrás que aprobarlo manualmente. Archivos sensibles totalmente bloqueados:
{
"permissions": {
"defaultMode": "default",
"allow": [
"Bash(git status *)",
"Bash(git diff *)",
"Bash(npm run *)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(git push *)",
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)"
]
}
}Ojo al escribir esos deny: como vimos antes, bloquear .env no evita que lo lea un script; si es entorno de producción de verdad, tienes que usar Sandbox además de esta capa. No confíes solo en el deny.
Para terminar, hablemos de la línea roja, de la protagonista del principio: --dangerously-skip-permissions (equivalente al modo bypassPermissions).
Se salta todos los chequeos de permisos y de seguridad, ejecutando las herramientas inmediatamente. El "dangerously" (peligrosamente) del nombre no es para asustar por asustar. La documentación oficial delimita claramente su uso:
Utiliza este modo únicamente en entornos aislados (como contenedores, máquinas virtuales, o dev containers sin acceso a Internet) donde Claude Code no pueda causar ningún daño al sistema host.
Memoriza esta tabla sobre cuándo atreverse a usarlo:
| Escenario | ¿Me atrevo con --dangerously-skip-permissions? |
|---|---|
| Contenedor aislado / VM / dev container | ✅ Sí, lo que se borra es de usar y tirar |
| Tareas únicas en un pipeline CI | ✅ Sí, pero añade deny por encima como red de seguridad |
| Tu máquina local donde programas a diario | ❌ No, más vale ir lento que romper algo |
| Un servidor con código de producción de la empresa | ❌ Absolutamente NO, es una bomba de relojería |
La herramienta tiene dos "seguros" para tu tranquilidad: primero, incluso en este modo, intentar borrar el directorio raíz o el directorio de usuario (rm -rf / o rm -rf ~) te seguirá pidiendo confirmación, para evitar accidentes fatales; segundo, en Linux / macOS, no puedes iniciarlo como usuario root o con sudo, directamente no arranca. Pero no confíes en los seguros: la regla es "usarlo solo en entornos aislados donde no te importe perder todo".
💡 Resumen en una frase:
acceptEditspara ir rápido en juguetes,defaultpara ir seguro en producción (plantillas listas);--dangerously-skip-permissionses exclusivo para entornos aislados, prohibido en la máquina local o servidores en producción.
06 Manos a la obra: Crea tus primeras reglas de permiso en 5 minutos
Con la teoría aprendida, toca practicar. Vamos a darle reglas a un proyecto de prueba para que veas en tiempo real cómo funcionan el allow y el deny. Todo en un entorno sencillo.
Paso 1: Crea el proyecto de juguete y el directorio de configuración (Mac / Linux)
mkdir perm-demo
cd perm-demo
mkdir .claudeResultado esperado: Un directorio .claude vacío dentro de perm-demo. (Usa ls -a para comprobarlo).
Paso 2: Escribe tu settings.json
Abre tu editor y en el archivo perm-demo/.claude/settings.json pega lo siguiente:
{
"permissions": {
"defaultMode": "default",
"allow": [
"Bash(git status *)"
],
"deny": [
"Bash(git push *)"
]
}
}La regla es: Preguntar en cada paso por defecto, dejar pasar git status sin preguntar, y bloquear git push por completo.
Paso 3: Arranca Claude y verifica las reglas
claudeUna vez dentro escribe:
/permissionsResultado esperado: Se abre la ventana de gestión de permisos, donde puedes ver las reglas que acabas de escribir: git status * está en la lista de permitidos (Allow), y git push * en la de prohibidos (Deny), con el nombre del settings.json del que proceden. Si ves estas dos reglas, es que se han cargado correctamente.
Paso 4: Pon a prueba el bloqueo del deny
Dile que haga lo que has prohibido:
Haz un git push origin mainResultado esperado: Claude no lo ejecutará, y ni siquiera te preguntará si lo apruebas: simplemente te dirá que la operación fue bloqueada por las reglas de permisos. Así de efectivo es el deny: bloquea de forma silenciosa e irrevocable.
Paso 5: Compara con la fluidez del allow
Ahora pide algo que tienes permitido:
Hazme un git statusResultado esperado: Como encaja con allow: Bash(git status *), se ejecutará sin preguntarte ni pedir tu aprobación (daría igual si te da un error diciendo que "no es un repositorio git", eso es problema de git, lo que importa es que no te ha pedido permiso, demostrando que allow funciona).
Al hacer esto, has completado la secuencia "Escribir regla → Cargar → Bloquear con deny → Aprobar con allow". A partir de ahora, cualquier configuración de permisos usa este mismo mecanismo.
💡 Resumen en una frase: Crea
.claude/settings.json, usa/permissionspara revisar si cargó, y haz que Claude ejecute algo prohibido y algo permitido; comprobar esto a mano es mucho mejor que memorizar la sintaxis de las reglas.
07 Resumen
En este artículo hemos repasado las "riendas" de los permisos en Claude Code: lo permisivo o restrictivo que seas con él, depende totalmente de ti y de tus reglas de configuración.
Repasemos los conceptos principales:
| Qué tienes que hacer | Cómo hacerlo | Punto clave |
|---|---|---|
| Ajustar la "frecuencia de preguntas" | Seis modos de permiso | Espectro desde default (preguntar todo) a bypassPermissions (correr desnudo) |
| Cambiar de modo en una sesión | Shift+Tab | Alterna entre default / acceptEdits / plan |
| Fijar el modo por defecto | defaultMode | Lo pones en settings.json; el modo auto va a nivel de usuario |
| Control preciso por comando | Reglas allow / ask / deny | Prioridad deny → ask → allow, donde deny gana siempre |
| Bloquear archivos delicados | deny + Sandbox | Un deny no puede parar a un subproceso que lea por su cuenta |
A partir de ahora podrás: Entender cuándo usar cada uno de los seis modos; cambiarlos ágilmente con Shift+Tab; escribir en settings.json reglas para permitir y denegar comandos por herramientas concretas; dotar de la configuración adecuada tanto a proyectos de prueba como a sistemas en producción; y saber que --dangerously-skip-permissions solo debe usarse en entornos aislados. Tener esta capacidad de dar o quitar permisos a tu antojo es lo que te permitirá dejar a Claude hacer el trabajo sin miedo a que cause un desastre.
En el próximo artículo, 21 "Seguridad y límites del riesgo", no solo veremos "cómo configurar permisos", pues la configuración es solo una herramienta. La verdadera pregunta es: ¿Deberías confiar en la IA para que toque tu código y sistema? ¿Cuáles son las verdaderas zonas de riesgo alto? ¿Cómo de peligrosas son las inyecciones de prompts y las filtraciones de datos sensibles, y cómo evitarlas? Ya tienes las riendas, el próximo paso es hablar del "criterio": cuándo apretar y cuándo aflojar.