Skip to content

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+Tab para cambiar de modo, y cómo especificar el modo directamente al iniciar.
  • La sintaxis en settings.json para definir reglas de allow, ask y deny, 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 herramientaEjemplos¿Requiere aprobación por defecto?
Solo lecturaLeer archivos, buscar con GrepNo, pasa automáticamente
Comandos BashEjecutar comandos shell
Modificación de archivosEditar con Edit / Write

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.md afectará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.md no 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:

ModoCosas que puede hacer sin preguntar¿Preguntará antes de actuar?Escenario ideal
defaultSolo lecturaPregunta para modificar archivos y ejecutar comandosEmpezando, tareas delicadas
acceptEditsSolo lectura + edición de archivos + comandos de sistema comunes (mkdir, mv, cp, etc.)No pregunta para editar archivos ni comandos comunes, pregunta para otros BashIterar rápido sobre código que estás revisando
planSolo lectura (investiga y planea, no toca tu código)Mismas reglas que defaultInvestigar y planear antes de tocar nada
autoTodo, pero con un clasificador de seguridad en segundo planoRaramente pregunta, el clasificador bloquea excesosTareas largas, menos interrupciones (versión preview de investigación)
dontAskSolo herramientas aprobadas de antemanoNo pregunta ni se detiene, rechaza directamente lo no aprobadoCI/CD bloqueado, scripts
bypassPermissionsTodo, se salta todos los chequeosNo pregunta nada en absolutoSolo 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:

bypassPermissions no 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: default pregunta todo, acceptEdits no pregunta para código, plan solo mira, auto tiene red de seguridad, bypassPermissions no tiene red. Recuerda este espectro de estricto a relajado y elige el que te convenga.

Espectro de modos de permisos: Del paso a paso al descontrol total

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:

text
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):

bash
claude --permission-mode plan

Puedes 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:

json
{
  "permissions": {
    "defaultMode": "acceptEdits"
  }
}

⚠️ Una restricción de la que avisa la documentación oficial: Si pones defaultMode como "auto", la configuración del proyecto y la local se ignoran (para evitar que un repositorio active el modo automático a escondidas). Para usar auto por 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+Tab rota entre "preguntar todo / no preguntar código / solo mirar", mira la barra de estado; si quieres fijar un modo, usa --permission-mode al inicio o defaultMode en settings.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ónEfectoUso típico
allowPaso automático sin aprobaciónOperaciones frecuentes de bajo riesgo (ej: git status, npm run build)
askMuestra aviso para que tú decidasAlgo de riesgo que requiere confirmación (ej: git push)
denyBloqueado por completo, ni se ejecuta ni avisaOperaciones 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:

ReglaQué coincide
BashTodos 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 con ls -la pero no con lsof, mientras que Bash(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:

json
{
  "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, donde deny siempre manda; ten cuidado con los espacios en las reglas; pero deny no 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:

json
{
  "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:

json
{
  "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: acceptEdits para ir rápido en juguetes, default para ir seguro en producción (plantillas listas); --dangerously-skip-permissions es 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)

bash
mkdir perm-demo
cd perm-demo
mkdir .claude

Resultado 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:

json
{
  "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

bash
claude

Una vez dentro escribe:

text
/permissions

Resultado 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:

text
Haz un git push origin main

Resultado 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:

text
Hazme un git status

Resultado 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 /permissions para 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 hacerCómo hacerloPunto clave
Ajustar la "frecuencia de preguntas"Seis modos de permisoEspectro desde default (preguntar todo) a bypassPermissions (correr desnudo)
Cambiar de modo en una sesiónShift+TabAlterna entre default / acceptEdits / plan
Fijar el modo por defectodefaultModeLo pones en settings.json; el modo auto va a nivel de usuario
Control preciso por comandoReglas allow / ask / denyPrioridad deny → ask → allow, donde deny gana siempre
Bloquear archivos delicadosdeny + SandboxUn 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.


Lecturas recomendadas