Casi todo programa necesita algún dato sensible para funcionar: la clave de una API externa, la contraseña de una base de datos, un token secreto para firmar sesiones. La pregunta es dónde guardar esos valores. Escribirlos directamente en el código parece la opción más rápida, y es justo la que provoca la mayoría de filtraciones de credenciales que acaban en titulares de seguridad.

La alternativa estándar en la industria son las variables de entorno: valores que vive fuera del código fuente, en el sistema donde se ejecuta el programa, y a los que el programa accede en tiempo de ejecución. El código nunca contiene el valor real, solo el nombre de la variable que necesita.

Qué es exactamente una variable de entorno

Una variable de entorno es un par clave-valor que vive en el sistema operativo o en el proceso que ejecuta tu aplicación, separado del código fuente. En lugar de escribir const apiKey = "sk_live_abc123" directamente en un archivo que vas a subir a un repositorio, tu código lee esa clave desde el entorno:

javascript
// Mal: la clave viaja con el código, visible para cualquiera con acceso al repo
const apiKey = "sk_live_abc123xyz";

// Bien: la clave vive fuera del código
const apiKey = process.env.API_KEY;

El valor real de API_KEY se define una vez en cada entorno donde corre la aplicación (tu máquina, el servidor de producción, el pipeline de CI/CD), pero nunca aparece escrito en el código que subes a GitHub. Si alguien accede al repositorio, ve process.env.API_KEY, no la clave en sí.

El archivo .env: variables de entorno para desarrollo local

Definir variables de entorno directamente en el sistema operativo es incómodo para desarrollo diario, así que casi todos los proyectos usan un archivo .env en la raíz, con este formato:

bash
DATABASE_URL=postgres://usuario:clave@localhost:5432/mi_app
API_KEY=sk_live_abc123xyz
NODE_ENV=development
PORT=3000

Una librería como dotenv en Node.js (o su equivalente python-dotenv en Python) lee ese archivo al arrancar la aplicación y carga cada línea como una variable de entorno accesible desde el código:

javascript
// al principio del punto de entrada de la app
require('dotenv').config();

const puerto = process.env.PORT || 3000;
const urlBaseDatos = process.env.DATABASE_URL;

console.log(`Servidor arrancando en el puerto ${puerto}`);

Esto es especialmente útil cuando montas un servidor con Node.js y Express: cada desarrollador del equipo tiene su propio .env con sus propias credenciales locales, sin que nadie tenga que compartir contraseñas por Slack.

La regla que no puedes saltarte: .env nunca va a Git

Aquí está el punto que da título a este artículo. El archivo .env contiene secretos reales y nunca debe subirse al control de versiones. La forma de garantizarlo es añadirlo a tu archivo .gitignore desde el primer commit del proyecto, no después de que ya lo hayas subido por error:

bash
# .gitignore
.env
.env.local
.env.*.local
node_modules/

Si ya subiste un .env por accidente, borrarlo del último commit no es suficiente: sigue existiendo en el historial de Git, accesible para cualquiera que clone el repositorio. Hay que revocar y regenerar todas las claves que se filtraron (tratarlas como comprometidas, sin excepción) y, si el repositorio es público, limpiar el historial con herramientas como git filter-repo. Prevenir esto con un buen .gitignore desde el principio es infinitamente más barato que arreglarlo después.

El archivo .env.example: documentar sin exponer

Como .env nunca se sube, cualquiera que clone tu repositorio no sabe qué variables necesita definir para que el proyecto arranque. La solución estándar es un archivo .env.example, que sí se sube a Git, con los nombres de las variables pero sin valores reales:

bash
# .env.example
DATABASE_URL=
API_KEY=
NODE_ENV=development
PORT=3000

Cualquier persona nueva en el proyecto copia ese archivo a .env (cp .env.example .env) y rellena sus propios valores. Es una convención tan extendida que encontrarás .env.example en la raíz de la inmensa mayoría de repositorios open source serios.

Configura bien tus variables de entorno

Sigue estos pasos en orden la próxima vez que arranques un proyecto nuevo, o revisa uno existente contra esta lista si nunca lo has hecho formalmente:

Configuración de variables de entorno

0 / 7 completados

En producción, las variables no vienen de un archivo

En tu máquina local, el archivo .env es cómodo, pero en producción la práctica habitual es configurar las variables directamente en el panel del proveedor de hosting (Vercel, Render, Railway, un servidor propio con Docker), no subiendo un archivo .env al servidor. Esto añade una capa más de seguridad: aunque alguien accediera al código desplegado, no encontraría un archivo con los secretos en texto plano.

Esta separación entre configuración y código es también uno de los principios detrás de los servicios que exponen APIs REST en distintos entornos (desarrollo, pruebas, producción) sin tener que tocar una sola línea de código para cambiar de uno a otro: solo cambian las variables de entorno que carga cada entorno.

JR

Javier Rodríguez Fernández

Programador con Grado Superior en Desarrollo de Aplicaciones Multiplataforma (DAM). Escribe en DevPulso sobre programación aplicada, sin relleno.