Secretos y variables de entorno en producción: guía práctica

Aprende a gestionar secretos y variables de entorno en producción con esta guía práctica, segura y aplicable a servidores reales.

Cuando desarrollamos una aplicación, es habitual tener las credenciales en un archivo .env local. El problema llega cuando esa misma aplicación viaja a producción y seguimos con la misma filosofía. Gestionar secretos y variables de entorno no es un lujo, es una necesidad para no acabar con una fuga de datos o con un git log mostrando contraseñas en texto plano.

La clave está en separar la configuración (lo que no es sensible) de los secretos (lo que sí lo es), y aplicar políticas de rotación y acceso mínimo. Vamos a ver cómo hacerlo de forma práctica.

1. Variables de entorno: la base (y sus límites)

Las variables de entorno son el estándar para configurar una app en doce factores. Son fáciles de leer y no ensucian el código. Pero ojo: no son sinónimo de seguridad.

Un error común es hacer esto:

export DB_PASSWORD="SuperSecreto123!"

Y luego dejarlo en el .bashrc. Eso es un secreto en texto plano en el disco. Para entornos de desarrollo es aceptable usar un .env, pero en producción debemos inyectarlas desde el orquestador o el sistema de despliegue.

Ejemplo correcto con systemd:

[Service]
EnvironmentFile=/etc/myapp/secrets.env
ExecStart=/usr/bin/myapp

Y el archivo /etc/myapp/secrets.env debe tener permisos 600 (solo lectura para root y el grupo del servicio). Nada de 644.

2. Herramientas de gestión de secretos: Vault y sops

Para producción seria, las variables de entorno no bastan. Necesitas un gestor de secretos. Hashicorp Vault es el rey, pero tiene curva de aprendizaje. Si buscas algo más simple, sops (Secrets OPerationS) de Mozilla es excelente.

Con sops cifras archivos YAML/JSON con claves de KMS, PGP o age. El flujo es:

# Cifrar un archivo .env
sops -e -i --age age1qy... .env.prod

# Editar de forma segura
sops .env.prod

El archivo queda cifrado en el repositorio, y solo se descifra en el momento del despliegue. Para Vault, la integración típica es que la app obtenga los secretos en tiempo de ejecución:

vault kv get -mount=secret mi-app/db

Y en tu aplicación, usas el SDK de Vault en lugar de process.env. Esto añade latencia, pero ganas en centralización y auditoría.

3. Inyección en contenedores y orquestadores

Si usas Docker o Kubernetes, la cosa cambia. Nunca pongas secretos en el Dockerfile con ENV, porque quedan en las capas de la imagen. La opción correcta es pasarlos en runtime.

Con Docker Compose:

services:
  app:
    image: mi-app:latest
    secrets:
      - db_password
    environment:
      - DB_PASSWORD_FILE=/run/secrets/db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt

Con Kubernetes, usa Secrets montados como volúmenes, no como variables de entorno (el comando kubectl get secret -o yaml los muestra en base64, que no es cifrado):

apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  password: <base64>

Y en el pod:

spec:
  containers:
    - name: app
      volumeMounts:
        - name: secrets
          mountPath: /etc/secrets
  volumes:
    - name: secrets
      secret:
        secretName: db-secret

La app lee /etc/secrets/password. Así no queda en el env del proceso y es más fácil de rotar.

4. Rotación y auditoría: el hábito que te salva

Generar un secreto y olvidarte es un error. Debes rotarlos periódicamente. Con Vault, puedes usar dynamic secrets (genera credenciales temporales de BD). Con sops, la rotación es manual, pero puedes automatizarla con un cron que re-ejecute el cifrado con una clave nueva.

Además, activa auditoría. En Vault:

vault audit enable file file_path=/var/log/vault-audit.log

Esto te dice quién accedió a qué secreto y cuándo. En producción, si no sabes quién tocó un secreto, es como si no tuvieras puerta de entrada.

Conclusión

Empieza pequeño: saca los secretos del código, ponlos en archivos con permisos restrictivos y usa sops para cifrarlos en el repo. Cuando el equipo crezca, migra a Vault o a los Secrets de Kubernetes. La gestión de secretos no es un proyecto, es una disciplina. Tu yo del futuro (y tu auditor de seguridad) te lo agradecerán.