Configuración y Secretos

Variables de entorno, config maps, gestión segura de secretos y herramientas como Vault para proteger datos sensibles.

El principio: separar configuración del código

Una de las reglas fundamentales del despliegue moderno es que la configuración no debe vivir en el código. El mismo artefacto (imagen Docker, binario, bundle) debe poder ejecutarse en cualquier entorno — lo único que cambia es la configuración.

Esto incluye:

  • URLs de bases de datos y servicios externos
  • Credenciales y tokens de acceso
  • Feature flags y parámetros de comportamiento
  • Niveles de logging y timeouts
  • Claves de API de terceros

Variables de entorno

Las variables de entorno son el mecanismo más básico y universal para inyectar configuración en una aplicación.

Ventajas

  • Soportadas por todos los lenguajes y plataformas
  • Fáciles de configurar en contenedores, CI/CD y cloud providers
  • No requieren librerías adicionales

Buenas prácticas

# Nombres descriptivos en UPPER_SNAKE_CASE
DATABASE_URL=postgres://user:pass@host:5432/db
REDIS_URL=redis://localhost:6379
LOG_LEVEL=info
API_TIMEOUT_MS=5000
FEATURE_NEW_CHECKOUT=true
  • Usar un archivo .env.example en el repositorio documentando todas las variables necesarias (sin valores reales)
  • Nunca commitear archivos .env con valores reales
  • Validar las variables al arrancar la aplicación — fallar rápido si falta alguna requerida

Validación al inicio

function validateEnv() {
  const required = ['DATABASE_URL', 'REDIS_URL', 'JWT_SECRET'];
  const missing = required.filter(key => !process.env[key]);
  if (missing.length > 0) {
    throw new Error(`Missing env vars: ${missing.join(', ')}`);
  }
}

ConfigMaps en Kubernetes

En Kubernetes, los ConfigMaps permiten almacenar configuración no sensible como pares clave-valor y montarlos en los pods.

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  LOG_LEVEL: "info"
  API_TIMEOUT: "30s"
  MAX_CONNECTIONS: "100"
  FEATURE_FLAGS: |
    {
      "newCheckout": true,
      "darkMode": false
    }

Inyectar como variables de entorno

spec:
  containers:
    - name: my-app
      envFrom:
        - configMapRef:
            name: app-config

Montar como archivo

spec:
  containers:
    - name: my-app
      volumeMounts:
        - name: config-volume
          mountPath: /app/config
  volumes:
    - name: config-volume
      configMap:
        name: app-config

Gestión de secretos

Los secretos (contraseñas, tokens, claves privadas) requieren un tratamiento especial. Nunca deben estar en:

  • El código fuente
  • Archivos de configuración commiteados
  • Logs de la aplicación
  • Imágenes Docker

Kubernetes Secrets

Kubernetes ofrece un recurso Secret para datos sensibles:

apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
type: Opaque
stringData:
  DATABASE_PASSWORD: "mi-password-seguro"
  JWT_SECRET: "mi-jwt-secret"
  API_KEY: "mi-api-key"

Limitación importante: los Secrets de Kubernetes se almacenan en etcd codificados en base64, pero no están encriptados por defecto. Para mayor seguridad, habilitar encryption at rest o usar un gestor de secretos externo.

HashiCorp Vault

Vault es la herramienta más popular para gestión centralizada de secretos:

  • Almacenamiento seguro: los secretos se encriptan en reposo
  • Acceso controlado: políticas granulares de quién puede leer qué secretos
  • Rotación automática: los secretos pueden rotarse sin redesplegar
  • Auditoría: registro completo de quién accedió a qué secreto y cuándo
  • Secretos dinámicos: genera credenciales temporales bajo demanda (ej: credenciales de DB que expiran en 1 hora)

Otras herramientas

  • AWS Secrets Manager: gestión de secretos nativa en AWS con rotación automática
  • Google Secret Manager: equivalente en GCP
  • Azure Key Vault: equivalente en Azure
  • SOPS: encripta archivos de configuración que se pueden commitear de forma segura

Rotación de secretos

Los secretos deben rotarse periódicamente para minimizar el impacto de una filtración:

  1. Generar nuevo secreto: crear la nueva credencial en el gestor de secretos
  2. Actualizar la aplicación: la aplicación lee el nuevo secreto (idealmente sin reinicio)
  3. Verificar funcionamiento: confirmar que todo funciona con el nuevo secreto
  4. Revocar el secreto anterior: eliminar la credencial antigua

Rotación sin downtime

Para rotar secretos sin downtime, la aplicación debe soportar dual credentials temporalmente:

  • Aceptar tanto el secreto viejo como el nuevo durante un período de transición
  • Una vez confirmado que todo funciona, revocar el viejo

Buenas prácticas generales

  1. Principio de mínimo privilegio: cada servicio solo accede a los secretos que necesita
  2. No loguear secretos: sanitizar los logs para que nunca muestren credenciales
  3. Encriptar en tránsito y en reposo: TLS para comunicación, encryption at rest para almacenamiento
  4. Auditar accesos: registrar quién accede a qué secretos y cuándo
  5. Automatizar la rotación: no depender de procesos manuales para rotar credenciales
  6. Separar configuración de secretos: la configuración no sensible va en ConfigMaps, los secretos en un gestor dedicado

Resumen

La configuración y los secretos son aspectos críticos del despliegue. Las variables de entorno y ConfigMaps manejan la configuración no sensible, mientras que herramientas como Vault, AWS Secrets Manager o Kubernetes Secrets protegen los datos sensibles. La clave es separar configuración del código, validar al inicio y rotar secretos periódicamente.