Tips & Tricks

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.

Claude Code tiene potentes capacidades de manipulación de archivos y ejecución de comandos — pero una mala configuración puede provocar accidentes irreversibles. Hacer commit de un archivo .env, borrar accidentalmente una base de datos de producción, imprimir una clave API en los logs — estos son incidentes reales causados por usar Claude Code sin las protecciones adecuadas.

Este artículo ofrece una explicación a nivel de implementación de las mejores prácticas de seguridad para Claude Code. El enfoque está en configuraciones listas para usar y código preventivo que puedes copiar y aplicar de inmediato.

Por qué Claude Code necesita medidas de seguridad

A diferencia de un editor de texto normal, Claude Code tiene las siguientes capacidades:

  • Leer, escribir y eliminar cualquier archivo (Read / Write / Edit / Bash(rm))
  • Ejecutar comandos de shell (Bash)
  • Acceso a la red (WebFetch / llamadas API)
  • Publicar en servicios externos (GitHub, Slack, etc.)

Todo esto puede ejecutarse con la aprobación del usuario. El problema es que aprobar mecánicamente cada prompt permite que operaciones no deseadas se cuelen. Las medidas de seguridad consisten en eliminar estructuralmente el margen de error.

Medida 1: Gestión de claves API — .env + .gitignore como base

Lo que NO debes hacer

// ❌ Escrito directamente en el código fuente
const client = new Anthropic({ apiKey: "sk-ant-api03-..." });

// ❌ Escrito en CLAUDE.md o archivos de configuración
// ANTHROPIC_API_KEY=sk-ant-api03-...

// ❌ Incluido en el prompt de claude -p
// Usa QIITA_TOKEN=abc123 para publicar

El enfoque correcto

# .env (excluido de git, almacenado solo en la máquina local)
ANTHROPIC_API_KEY=sk-ant-api03-...
QIITA_TOKEN=06b4441b...
SLACK_BOT_TOKEN=xoxb-...
DATABASE_URL=postgresql://...
# Siempre añadir a .gitignore
.env
.env.*
.env.local
!.env.example   # ← El archivo de ejemplo sí puede commitearse
*.pem
*.key
credentials.json
*-service-account.json
# .env.example (seguro de commitear, valores vacíos)
ANTHROPIC_API_KEY=
QIITA_TOKEN=
SLACK_BOT_TOKEN=
DATABASE_URL=

Leer variables en el código

// ✅ Leer desde variables de entorno
import { config } from "dotenv";
config();

const token = process.env.QIITA_TOKEN;
if (!token) throw new Error("QIITA_TOKEN no está configurado. Por favor, revisa tu archivo .env.");

Documentar prohibiciones en CLAUDE.md

## Prohibiciones de Seguridad
- Nunca incluir claves API o tokens en prompts
- Nunca leer y mostrar el contenido de archivos .env
- Nunca escribir valores de variables de entorno en logs o comentarios
- Nunca usar console.log con el contenido de process.env

Medida 2: Escaneo de secretos antes del commit

Incluso con .env en .gitignore, pueden ocurrir entradas accidentales en otros archivos o errores de copia-pega. Añade un escaneo automático pre-commit.

Verificación pre-commit con Hooks

.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash(git commit*)",
        "hooks": [
          {
            "type": "command",
            "command": "node scripts/secret-scan.mjs"
          }
        ]
      }
    ]
  }
}

scripts/secret-scan.mjs:

import { execSync } from "child_process";

// Obtener cambios en staging
const diff = execSync("git diff --cached").toString();

const PATTERNS = [
  { name: "Clave API de Anthropic", re: /sk-ant-api\d+-[A-Za-z0-9_-]{80,}/ },
  { name: "Clave API de OpenAI", re: /sk-[A-Za-z0-9]{48}/ },
  { name: "Clave de acceso AWS", re: /AKIA[0-9A-Z]{16}/ },
  { name: "Token de Slack", re: /xox[baprs]-[0-9A-Za-z-]{10,}/ },
  { name: "Secreto genérico", re: /[Ss]ecret[_-]?[Kk]ey\s*[:=]\s*['"][^'"]{10,}['"]/ },
];

const found = PATTERNS.filter(({ re }) => re.test(diff));

if (found.length > 0) {
  console.error("🚨 ¡Secreto detectado! Abortando el commit:");
  found.forEach(({ name }) => console.error(`  - ${name}`));
  console.error("\nSolución: ejecuta `git reset HEAD <archivo>` para retirar el archivo del staging");
  process.exit(1);  // Código de salida 1 → El Hook bloquea el comando
}

console.log("✓ Escaneo de secretos: sin problemas encontrados");
process.exit(0);

Esto significa que en el momento en que Claude Code intenta ejecutar git commit, se lanza automáticamente un escaneo y cualquier filtración detectada queda bloqueada.

Medida 3: Configuración de modos de permisos

La configuración de permitir/denegar de Claude Code puede controlarse de forma detallada a nivel de archivo.

Configuración de permisos en .claude/settings.json

{
  "permissions": {
    "allow": [
      "Read(**)",
      "Glob(**)",
      "Grep(**)"
    ],
    "deny": [
      "Bash(rm -rf*)",
      "Bash(git push --force*)",
      "Bash(git reset --hard*)",
      "Bash(DROP TABLE*)",
      "Bash(truncate*)",
      "Bash(curl * | bash)",
      "Bash(wget * | sh)"
    ],
    "ask": [
      "Write(**)",
      "Edit(**)",
      "Bash(git commit*)",
      "Bash(git push*)",
      "Bash(npm publish*)",
      "Bash(wrangler pages deploy*)"
    ]
  }
}
ConfiguraciónSignificado
allowEjecutar sin confirmación
denyNunca ejecutar (bloqueado completamente)
askRequiere aprobación cada vez

Principio clave: Los comandos destructivos van en deny, las operaciones de escritura en ask, las operaciones de lectura en allow.

Archivo de configuración específico para producción

Para entornos de producción, restringir a solo lectura es el enfoque más seguro.

// .claude/settings.production.json
{
  "permissions": {
    "allow": ["Read(**)", "Glob(**)", "Grep(**)", "Bash(git log*)", "Bash(git diff*)"],
    "deny": ["Write(**)", "Edit(**)", "Bash(git push*)", "Bash(rm*)", "Bash(*deploy*)"],
    "ask": []
  }
}
# Especificar explícitamente al trabajar en producción
CLAUDE_SETTINGS=.claude/settings.production.json claude

Medida 4: Protección del entorno de producción

Separar explícitamente los destinos de conexión

## CLAUDE.md — Reglas del entorno de producción

## Detección de entorno
- Si DATABASE_URL contiene 'prod' o 'production', es un **entorno de producción**
- En producción, nunca ejecutar:
  - DROP / TRUNCATE / DELETE (sin cláusula WHERE)
  - Migraciones (requieren confirmación previa)
  - Eliminaciones masivas de archivos

## Flujo de confirmación
Todos los cambios en producción deben:
1. Probarse primero en un entorno de staging
2. Recibir confirmación del usuario
3. Reportar resultados tras la ejecución

Controlar conexiones con variables de entorno

// scripts/db-query.mjs
const env = process.env.NODE_ENV ?? "development";
const dbUrl = process.env.DATABASE_URL;

if (env === "production" && process.argv.includes("--write")) {
  console.error("❌ Escribir en producción requiere el flag --force-production");
  process.exit(1);
}

Medida 5: Protecciones para operaciones de archivos

Automatizar copias de seguridad antes de eliminar

// Hooks en .claude/settings.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash(rm *)",
        "hooks": [
          {
            "type": "command",
            "command": "echo '⚠️  Un comando de eliminación está a punto de ejecutarse. Presiona Ctrl+C para cancelar.' && sleep 3"
          }
        ]
      }
    ]
  }
}

Proteger archivos críticos de ediciones accidentales

## CLAUDE.md — Archivos que no deben modificarse

Los siguientes archivos **nunca deben editarse**:
- .env (contiene variables de entorno y claves secretas)
- wrangler.toml (configuración de producción de Cloudflare)
- scripts/deploy.sh (script de despliegue)
- .github/workflows/*.yml (configuración de CI/CD)

Si se necesitan cambios, consultar primero con el usuario.

5 errores comunes

1. Añadir .gitignore después del hecho es demasiado tarde Un archivo .env ya commiteado permanece en el historial de git aunque se añada más tarde a .gitignore.

# Eliminación completa del historial (atención: requiere force push)
git filter-branch --force --index-filter \
  "git rm --cached --ignore-unmatch .env" \
  --prune-empty --tag-name-filter cat -- --all

# Alternativamente, usar BFG Repo Cleaner

Si el archivo ya se subió a GitHub, siempre rota tus claves API primero antes de limpiar el historial.

2. Almacenar archivos JSON de cuentas de servicio en el repositorio Las claves de cuentas de servicio de Google Cloud o AWS suelen distribuirse como archivos .json, pero almacenarlos en un repositorio es peligroso. Conviértelos en variables de entorno o migra a un Secret Manager (AWS Secrets Manager / GCP Secret Manager).

3. Ejecutar comandos interactivos con la herramienta Bash Durante la ejecución sin cabeza con claude -p, los comandos que requieren entrada interactiva como sudo o vim harán que el proceso se cuelgue. Usa solo comandos no interactivos.

4. Incluir credenciales en mensajes de error

// ❌ Peligroso: la clave API aparece en los logs
throw new Error(`Autenticación fallida: token=${process.env.TOKEN}`);

// ✅ Seguro: no exponer el valor
throw new Error(`Autenticación fallida: por favor revisa la variable de entorno TOKEN`);

5. Reutilizar la misma configuración de permisos en todos los proyectos Usar el mismo settings.json para proyectos personales y de trabajo significa que la configuración laxa del proyecto personal puede sobrescribir los requisitos más estrictos del proyecto de trabajo. Gestiona .claude/settings.json por separado para cada proyecto.

Lista de verificación de seguridad

Una lista de verificación para configurar un proyecto de Claude Code:

### Configuración básica
- [ ] .env creado y añadido a .gitignore
- [ ] .env.example creado y compartido con el equipo
- [ ] Verificado mediante git log que los commits existentes no contienen secretos

### Configuración de permisos
- [ ] Lista de deny configurada en .claude/settings.json
- [ ] Comandos destructivos (rm -rf, DROP TABLE, etc.) añadidos a deny
- [ ] Comandos de despliegue en producción configurados como ask

### Automatización
- [ ] Hook de escaneo de secretos pre-commit configurado
- [ ] Prohibiciones de seguridad documentadas en CLAUDE.md

### Operaciones
- [ ] Calendario de rotación de claves API establecido (recomendado: cada 90 días)
- [ ] settings.production.json dedicado para producción
- [ ] Flujo de respuesta a incidentes documentado

Resumen

La seguridad en Claude Code no se trata de “imponer restricciones” — se trata de construir una estructura donde los accidentes no puedan ocurrir.

AmenazaContramedida
Filtración de clave API.env + .gitignore + Hook de escaneo de secretos
Eliminación no deseadaLista de deny + Hook pre-eliminación
Errores en producciónConfiguración específica de producción + prohibiciones en CLAUDE.md
Contaminación de commitsHook PreToolUse para escaneo pre-commit

Una vez configurados, estos ajustes son prácticamente libres de mantenimiento. Dedicar 30 minutos hoy puede prevenir un incidente mayor en el futuro.

Artículos relacionados

Referencias

#claude-code #security #api-key #permissions #devops #best-practices

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.

Gratis

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.

Masa

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.