Capítulo 16 — settings.json vs. settings.local.json

Por: Artiko
claude-codeanthropicpartner-badgesettings-jsonpermisos

settings.json vs. settings.local.json

Módulo 4 · Configuración y personalización · Lección 3 de 5

Al terminar esta lección sabrás qué va en el archivo de configuración compartido y qué en el personal, para no confirmar nunca una sobrescritura personal en la configuración del equipo.

Dos archivos. Uno compartido y uno tuyo.

Los dos archivos

Mismo formato, propósitos opuestos

Ambos archivos usan el mismo formato JSON y viven en el directorio .claude/ de tu proyecto. La diferencia es completamente una cuestión de propiedad y de visibilidad.

Compartido · .claude/settings.json: la configuración del equipo

Se confirma en git. Cada desarrollador que clona este repositorio recibe estos ajustes automáticamente. Úsalo para todo lo que deba aplicarse de forma consistente en todo el equipo:

  • Reglas de permisos allow/deny.
  • Definiciones de hooks.
  • Configuraciones aprobadas de servidores MCP.
  • Anuncios de la empresa.

Personal · .claude/settings.local.json: tu configuración

Git lo ignora automáticamente cuando Claude Code lo crea. Nunca se confirma. Úsalo para sobrescrituras personales, configuración experimental y todo lo que sea específico de tu máquina:

  • Preferencias personales de modo de permisos.
  • Configuración experimental que estás probando.
  • Rutas de herramientas específicas de tu máquina.
  • Excluir ruido de los CLAUDE.md de otros equipos.

Qué va en cada archivo

Si solo funciona en tu máquina, no va en el archivo compartido

Este es un archivo de configuración de proyecto bien estructurado para un despliegue en equipo. Es lo que confirmarías en el repositorio al inicio de un engagement.

.claude/settings.json · confirmado en git

// .claude/settings.json (compartido con el equipo)
{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test *)",
      "Bash(git status)",
      "Bash(git log *)"
    ],
    "deny": [
      "Bash(curl *)",
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)"
    ]
  },
  "companyAnnouncements": [
    "Review our coding guidelines at docs.acme.com/claude"
  ]
}

Observa lo que no aparece en el archivo compartido: la preferencia model (es un ajuste de usuario), las variables de entorno con credenciales (nunca en un archivo confirmado) y cualquier sobrescritura de defaultMode (eso va en el archivo local del desarrollador). La línea $schema activa el autocompletado y la validación en línea en VS Code y Cursor; vale la pena incluirla en cada archivo de configuración de proyecto que prepares para un cliente.

Estructura de permisos

Deny se evalúa primero. Luego ask. Luego allow.

Las reglas de permisos siguen un orden de evaluación fijo y se combinan entre ámbitos en lugar de sobrescribirse. La lista allow local de un desarrollador se suma a las reglas del proyecto; no las reemplaza.

  1. Las reglas deny se evalúan primero. Si alguna regla deny coincide con el uso de la herramienta, se bloquea, sin importar lo que digan las reglas allow. Úsalo para proteger archivos sensibles y bloquear comandos de riesgo. Ejemplo: Read(./.env)
  2. Después, las reglas ask. Si ninguna regla deny coincide pero sí una regla ask, Claude pide confirmación. Es útil para operaciones de riesgo que quieres que aprueben personas. Ejemplo: Bash(git push *)
  3. Después, las reglas allow. Si existe una regla allow que coincida, el uso de la herramienta continúa sin pedir confirmación. Úsalo para comandos seguros y frecuentes que no quieres que interrumpan el flujo de trabajo. Ejemplo: Bash(npm run test *)
  4. Por defecto: ask. Ninguna regla coincide y Claude pide confirmación. Es el valor seguro por defecto: los usos de herramientas desconocidos requieren aprobación humana.
flowchart TD
    A["Uso de una herramienta"] --> B{"¿Coincide una regla deny?"}
    B -- "Sí" --> X["Bloqueado"]
    B -- "No" --> C{"¿Coincide una regla ask?"}
    C -- "Sí" --> D["Claude pide confirmación"]
    C -- "No" --> E{"¿Coincide una regla allow?"}
    E -- "Sí" --> F["Se ejecuta sin pedir confirmación"]
    E -- "No" --> G["Por defecto: ask (pide confirmación)"]

Comprueba tu comprensión

Escenario: ¿Dónde va esta decisión de configuración?

Aplica lo que has aprendido a una decisión de despliegue real.

Un equipo de 15 desarrolladores está comenzando un despliegue de Claude Code. El arquitecto principal quiere preaprobar npm run test y npm run lint para todos y bloquear los comandos curl. Además, quiere que cada desarrollador pueda experimentar con reglas allow adicionales en su propia máquina sin afectar a nadie más. ¿Cuál es el enfoque correcto?

  • A. Poner todas las reglas en el ~/.claude/settings.json de cada desarrollador. Distribuir el archivo de configuración a los ajustes de usuario de cada uno para que todos empiecen con la misma configuración.
  • B. Reglas del equipo en .claude/settings.json; experimentos personales en .claude/settings.local.json. Confirmar las reglas allow/deny compartidas en el repositorio y pedir a los desarrolladores que usen el archivo local para sus propias adiciones.
  • C. Poner todo en .claude/settings.local.json para mantenerlo flexible. Usar la configuración local para toda la configuración, de modo que los desarrolladores la ajusten según necesiten.
Ver respuesta

Correcta: confirma las reglas del equipo en el archivo del proyecto y usa el archivo local para las adiciones personales. El .claude/settings.json del proyecto es el lugar adecuado para las reglas allow/deny compartidas: cada desarrollador que clona el repositorio las recibe automáticamente, sin distribución manual. El archivo local está ignorado por git, así que los desarrolladores pueden añadir reglas allow personales sin riesgo de confirmarlas por error ni de afectar a sus compañeros. La opción A (ajustes de usuario) requeriría sincronizar el archivo manualmente en 15 máquinas y no se aplicaría automáticamente a los nuevos miembros del equipo.

Simulación: Arquitectura de permisos en Apex

Apex Logistics está a tres semanas de salir a producción y tú configuras Claude Code para el equipo de plataforma. Tres decisiones, seis puntos. Las decisiones tienen consecuencias.

Decisión 1 de 3 · Barrera transversal

La seguridad de Apex exige que WebFetch(domain:internal-ledger.apex.com) esté bloqueado en la máquina de cada ingeniero, no solo en el repositorio de plataforma. ¿Dónde va?

  • A. Poner una regla deny en .claude/settings.json: una regla de proyecto que el repositorio de plataforma hereda al clonarse.
  • B. Configurarla como política gestionada por TI: una política de toda la organización que TI distribuye a cada máquina, por encima de la configuración de proyecto y local.
  • C. Añadirla al settings.local.json de cada desarrollador: pedir a cada ingeniero que añada la regla deny a su archivo personal ignorado por git.
Ver respuesta
  • A · 1 punto (parcial). Esto cubre el repositorio. Las reglas deny de ámbito de proyecto no pueden eliminarse con la configuración local. Pero solo se aplica a este repositorio: los ingenieros que trabajen en otros lugares no tendrán la protección.
  • B · 2 puntos (mejor opción). Correcta. Managed se aplica a cada sesión en cada máquina. Es el único ámbito que cubre a todos los ingenieros, en todos los repositorios, de forma fiable.
  • C · 0 puntos. No es exigible. Cada desarrollador tiene su propia copia, y quien no la configure no tendrá la restricción.

Decisión 2 de 3 · Probar un servidor MCP

Quieres probar un nuevo servidor MCP interno en local antes de recomendarlo al equipo. ¿Dónde lo configuras?

  • A. Añadirlo a .claude/settings.json: confirmar el servidor en la configuración compartida desde el principio.
  • B. Añadirlo a .claude/settings.local.json: configurarlo en tu archivo local ignorado por git, limitado a este proyecto.
  • C. Añadirlo a ~/.claude/settings.json: añadirlo a tus ajustes de usuario para que se cargue en cada proyecto que abras.
Ver respuesta
  • A · 0 puntos. Incorrecta. Esto expone un servidor MCP sin probar a todo el equipo de inmediato. Si tiene problemas, todos se ven afectados.
  • B · 2 puntos (mejor opción). Correcta. El ámbito Local es personal y está ignorado por git. Puedes probar el servidor MCP a fondo antes de confirmarlo en la configuración compartida.
  • C · 1 punto (parcial). Funciona en parte. Esto lo mantiene fuera del repositorio del equipo, pero activa el servidor MCP en todos tus proyectos. settings.local.json es más específico.

Decisión 3 de 3 · Una regla allow para todo el equipo

El equipo acuerda preaprobar Bash(docker compose up *) para todos los desarrolladores. ¿Dónde va la regla allow?

  • A. .claude/settings.json: confirmar la regla allow en la configuración compartida del proyecto.
  • B. .claude/settings.local.json para todos: pedir a cada desarrollador que añada la misma regla allow a su archivo local.
  • C. Dejarla sin configurar y aprobar manualmente cada vez: omitir la regla y aprobar el comando a mano en cada ejecución.
Ver respuesta
  • A · 2 puntos (mejor opción). Correcta. El ámbito de proyecto se confirma en git, así que cada colaborador lo recibe al hacer pull. Los acuerdos del equipo pertenecen a la configuración compartida.
  • B · 1 punto (parcial). Frágil. Cada persona necesita su propia copia, y quien lo olvide no tendrá la aprobación. Un acuerdo de equipo en la configuración local no se sostiene.
  • C · 0 puntos. Incorrecta. El equipo lo acordó. Codifícalo. La aprobación manual en cada ejecución de docker compose es exactamente la fricción que elimina el archivo de configuración.
Ver cierre de la simulación
  • 6 puntos · Arquitectura sólida. Arquitectura limpia. Sabes cuándo recurrir a Managed, Project o Local, y no compartes en exceso una configuración que aún no está lista para compartirse.
  • 3–5 puntos · Sólido, con exposición. Buen criterio en los casos habituales. La distinción entre Managed y Project es la que aparece en las conversaciones de seguridad con los clientes.
  • 0–2 puntos · Revisa los ámbitos. La arquitectura de permisos es donde los requisitos de seguridad se cumplen o se eluden en silencio. Conviene repasarla antes de estar frente al CISO del cliente.

Ideas clave

La distinción entre settings.json y settings.local.json es simple, pero equivocarse genera desviaciones de configuración en el equipo. Confirma la base compartida, deja que cada persona la amplíe en local, y el despliegue se mantiene consistente.

  • Usa .claude/settings.json para lo que debe aplicarse a todo el equipo (reglas allow/deny, hooks y servidores MCP aprobados) y confírmalo en git.
  • Usa .claude/settings.local.json para sobrescrituras personales, pruebas y todo lo que solo funcione en tu máquina. Git lo ignora automáticamente.
  • Las reglas de permisos se evalúan en este orden: deny, después ask y después allow. Si ninguna coincide, Claude pide confirmación.
  • Las reglas de permisos se combinan entre ámbitos: un archivo local puede añadir reglas, pero no eliminar un deny de proyecto o gestionado.
  • Nunca confirmes credenciales en un archivo compartido: las variables de entorno con credenciales van fuera de él.

Siguiente: Slash commands personalizados