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ón | Significado |
|---|---|
allow | Ejecutar sin confirmación |
deny | Nunca ejecutar (bloqueado completamente) |
ask | Requiere 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.
| Amenaza | Contramedida |
|---|---|
| Filtración de clave API | .env + .gitignore + Hook de escaneo de secretos |
| Eliminación no deseada | Lista de deny + Hook pre-eliminación |
| Errores en producción | Configuración específica de producción + prohibiciones en CLAUDE.md |
| Contaminación de commits | Hook 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
- Guía de permisos de Claude Code
- Casos de fallos de seguridad en Claude Code
- Guía completa de integración Claude Code + SaaS
- Mejores prácticas de CLAUDE.md
Referencias
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.
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.
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.
Artículos relacionados
7 Casos de Fallo de Seguridad con Claude Code | Incidentes Reales y Prevención
Siete incidentes de seguridad reales con Claude Code: filtraciones de .env, eliminación de BD en producción, explosiones de facturación y más — con análisis de causa raíz y código de prevención.
Guía completa de permisos de Claude Code | settings.json, Hooks y Allowlist explicados
Guía completa de permisos de Claude Code. Aprende a usar allow/deny/ask, automatización con Hooks, settings.json por entorno y patrones prácticos, todo con código funcional.
Guía completa de harness engineering: cómo construir agentes de IA al estilo Claude Code
Un buen prompt no basta para dominar un LLM. Aprende a entrelazar herramientas, contexto y bucles de control en un harness, con código funcional y la arquitectura de Claude Code como guía.