Vault de HashiCorp para gestión de secretos
Índice de contenidos
- Puntos clave
- Qué problemas resuelve
- Arquitectura en 60 segundos
- Vault 2.x: versión actual, cambios y licencia
- Un ejemplo práctico: dynamic secrets
- Patrones operativos relevantes
- Secretos dinámicos vs. estáticos
- Auto-unseal
- Integración con Kubernetes
- Integración con CI/CD
- Qué conviene no hacer
- Alternativas
- Conclusión
- Preguntas frecuentes
- ¿Merece la pena Vault si solo voy a guardar pares clave-valor?
- ¿Qué necesito para operar Vault en producción con alta disponibilidad?
- ¿Cómo obtienen los pods de Kubernetes los secretos sin un token estático?
- ¿Vault sigue siendo de código abierto?
- Fuentes
Probado con Vault 2.1.0 · PostgreSQL 18.6 · Python 3.14 (hvac 2.4.0) · verificado
Actualizado: 2026-09-16
HashiCorp Vault centraliza la gestión de secretos con rotación automática, auditoría de cada acceso y políticas granulares por servicio. Genera credenciales efímeras que caducan en minutos, no en años. Para equipos que trabajan con ficheros .env en servidores, Vault ofrece secretos dinámicos, trazabilidad completa y control de acceso real.
La gestión de secretos es uno de esos temas donde todos saben que los .env en el servidor son mala práctica, pero que pocos equipos corrigen hasta que hay un incidente. HashiCorp Vault[1] es la solución más madura del ecosistema y, más allá del hype, resuelve problemas concretos que persisten en las infraestructuras actuales. Revisamos esta guía en septiembre de 2026 para Vault 2.1.0 y volvimos a ejecutar el ejemplo de secretos dinámicos contra PostgreSQL 18.6.
Puntos clave
-
Vault ataca tres patologías comunes: secretos estáticos distribuidos, falta de trazabilidad de acceso y separación débil entre roles.
-
Vault 2.1.0 (1 de septiembre de 2026) es la versión actual. Desde la 1.15.0 se publica con la Business Source License (BUSL), y OpenBao es el fork que conserva la Mozilla Public License 2.0 (MPL 2.0).
-
Los secretos dinámicos (credenciales efímeras generadas al pedir) son la característica diferencial más importante frente a un KV protegido.
-
Auto-unseal con AWS/GCP KMS es imprescindible para alta disponibilidad; nunca operar con un único nodo en producción.
-
La integración con Kubernetes mediante Vault Agent Injector elimina tokens de autenticación estáticos en pods.
-
El root token debe revocarse tras la configuración inicial; políticas granulares por servicio son la norma.
Qué problemas resuelve
Tres patologías típicas que Vault ataca:
-
Secretos estáticos distribuidos. El mismo password en 15 servidores, copiado manualmente, imposible de rotar sin un despliegue coordinado. Vault centraliza y rota.
-
Sin trazabilidad de acceso. Nadie sabe quién accedió a qué secreto ni cuándo. Vault audita cada operación.
-
Separación débil entre roles. Todo el equipo conoce todos los passwords. Vault ofrece políticas granulares por rol/servicio.
Arquitectura en 60 segundos
Vault funciona como servidor que almacena secretos en un backend (Consul, integrated storage, etc.) y los sirve cifrados. Sus componentes principales son:
-
Secret engines: distintos tipos de secretos: KV genérico, bases de datos dinámicas, certificados PKI, AWS IAM, SSH. Cada uno con su API específica.
-
Auth methods: cómo se autentican los clientes: tokens, userpass, Kubernetes service accounts, AWS IAM, OIDC. Determina qué políticas se aplican.
-
Policies: reglas HCL que definen qué paths del secret store puede leer/escribir un cliente. Granulares por verbo y ruta.
-
Audit devices: log de toda operación: file, syslog, socket. Imprescindible para compliance.
Vault 2.x: versión actual, cambios y licencia
La versión estable es Vault 2.1.0[2], publicada el 1 de septiembre de 2026. La rama 2.x empezó con la 2.0.0 el 14 de abril de 2026 como sucesora de la serie 1.21, y la imagen oficial[3] hashicorp/vault:2.1.0 se publica para amd64, arm64 y 386.
El cambio de la 2.0 que más procedimientos rompe afecta a la recuperación de emergencia: sys/rekey y sys/generate-root exigen ahora un token válido además de los fragmentos de la clave de desbloqueo. Lo comprobamos en la imagen 2.1.0, donde vault operator generate-root -status sin token responde 403 permission denied. Si tu procedimiento de emergencia depende de ese flujo sin token, la opción enable_unauthenticated_access de la configuración del servidor recupera el comportamiento anterior, según la página de cambios importantes de Vault[4].
La licencia cambió en 2023: la 1.15.0, del 27 de septiembre según el changelog de la serie 1.x[5], fue la primera versión con la Business Source License 1.1. En la rama 1.14, la 1.14.8 es la última con MPL 2.0 y la 1.14.9 ya usa la BUSL. La BUSL permite usar Vault en producción, pero prohíbe ofrecerlo a terceros dentro de un producto de pago que compita con las versiones de pago de Vault. Cada versión pasa a MPL 2.0 cuatro años después de publicarse.
El licenciante también está cambiando: desde un commit del 26 de marzo de 2026, el LICENSE de la rama main[6] nombra a IBM, que completó la compra de HashiCorp[7] el 27 de febrero de 2025. El de la etiqueta v2.1.0[8] todavía nombra a HashiCorp, Inc., y el resto del texto es idéntico en ambos.
Si la BUSL no encaja con tu caso, OpenBao[9] es la alternativa más cercana. Es un fork de Vault con licencia MPL 2.0 que gestiona la Open Source Security Foundation (OpenSSF) de la Linux Foundation. Parte del último código MPL de Vault, entre la 1.14.8 y la 1.14.9, y mantiene la compatibilidad con la API de Vault cuando puede. Su versión estable es la 2.6.2[10], del 18 de agosto de 2026, y los pasos de instalación están en cómo instalar OpenBao con Docker.
Un ejemplo práctico: dynamic secrets
Supongamos un servicio que necesita credenciales de base de datos. Sin Vault están en .env:
DB_USER=api_service
DB_PASSWORD=AbCdEf1234XYZ
Con Vault, el servicio pide un usuario nuevo cada vez que arranca. Para reproducirlo en local, levanta PostgreSQL 18.6 y Vault 2.1.0 en modo desarrollo, que guarda todo en memoria y arranca desbloqueado con el root token que le pases. Ese modo sirve para probar, nunca para producción:
docker network create vault-demo
docker run -d --name pg --network vault-demo \
-e POSTGRES_PASSWORD=pg_admin_pass_1234 -e POSTGRES_DB=app postgres:18.6
docker run -d --name vault --network vault-demo -p 127.0.0.1:8200:8200 \
-e VAULT_DEV_ROOT_TOKEN_ID=dev_root_token_1234 hashicorp/vault:2.1.0
until docker exec pg pg_isready -q -h 127.0.0.1; do sleep 1; done
docker exec pg psql -U postgres -d app \
-c "CREATE ROLE vault_admin LOGIN CREATEROLE PASSWORD 'vault_pass_1234'" \
-c "CREATE TABLE pedidos (id int PRIMARY KEY, total numeric)" \
-c "INSERT INTO pedidos VALUES (1, 42.50), (2, 13.00)" \
-c "GRANT SELECT ON pedidos TO vault_admin WITH GRANT OPTION"
El rol vault_admin es la cuenta con la que Vault crea los usuarios efímeros. Necesita SELECT con GRANT OPTION en cada tabla que vaya a conceder: en nuestra prueba, una tabla nueva sin ese permiso hizo fallar la emisión con permission denied for table.
Abre una shell en el contenedor con docker exec -it vault sh y configura el motor de secretos de PostgreSQL[11], la política del servicio y un dispositivo de auditoría:
export VAULT_ADDR=http://127.0.0.1:8200 VAULT_TOKEN=dev_root_token_1234
vault secrets enable database
vault write database/config/app \
plugin_name=postgresql-database-plugin allowed_roles=api_service \
connection_url="postgresql://{{username}}:{{password}}@pg:5432/app" \
username=vault_admin password=vault_pass_1234
vault write -force database/rotate-root/app
vault write database/roles/api_service db_name=app \
default_ttl=1h max_ttl=24h creation_statements="CREATE ROLE \"{{name}}\" \
LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \
GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";"
vault policy write api-service - <<'EOF'
path "database/creds/api_service" {
capabilities = ["read"]
}
EOF
vault audit enable file file_path=/vault/logs/audit.log
vault token create -policy=api-service -ttl=24h -field=token
rotate-root cambia la contraseña de vault_admin por una que solo conoce Vault. El rol api_service emite usuarios con un tiempo de vida (TTL) de 1 hora, renovable hasta 24 horas, y la política api-service solo permite leer database/creds/api_service. El último comando imprime el token de la aplicación, que empieza por hvs.
La aplicación usa hvac[12] 2.4.0 y psycopg[13] 3.3.5. Guarda este código como app.py; psycopg toma el host y la base de datos de las variables PGHOST y PGDATABASE:
import os
import hvac
import psycopg
vault = hvac.Client(url=os.environ["VAULT_ADDR"],
token=os.environ["VAULT_TOKEN"])
creds = vault.secrets.database.generate_credentials(name="api_service")
user = creds["data"]["username"]
print(user, creds["lease_duration"])
with psycopg.connect(user=user, password=creds["data"]["password"]) as db:
print(db.execute("SELECT current_user, count(*) FROM pedidos").fetchone())
Ejecútala en un contenedor efímero de Python 3.14 dentro de la misma red, con el token del paso anterior:
docker run --rm --network vault-demo -v "$PWD":/app \
-e VAULT_ADDR=http://vault:8200 -e VAULT_TOKEN=tu_token_de_aplicacion \
-e PGHOST=pg -e PGDATABASE=app python:3.14-slim \
sh -c "pip install -q hvac==2.4.0 'psycopg[binary]==3.3.5' \
&& python /app/app.py"
El script imprimió estas dos líneas (pip añade además un aviso por instalar como root):
v-token-api_serv-zb2HRy6sAXe13YOqf19g-1789591717 3600
('v-token-api_serv-zb2HRy6sAXe13YOqf19g-1789591717', 2)
Vault genera un usuario efímero en la base de datos en el momento. Su nombre combina el nombre visible del token, el rol, una parte aleatoria y la marca de tiempo Unix, y PostgreSQL lo guarda con un VALID UNTIL una hora por delante. Cuando el TTL vence, Vault lo revoca: con un rol de prueba de 30 segundos, el registro del servidor mostró revoked lease 30 segundos después de la emisión y el usuario desapareció de pg_roles. Si hay una brecha, las credenciales filtradas caducan en minutos, no en años.
El dispositivo de auditoría guardó cada lectura de database/creds/api_service en /vault/logs/audit.log, con las políticas del token y la IP de origen. El usuario y la contraseña aparecen como hmac-sha256:…, nunca en claro.
Ante un incidente no hace falta esperar al TTL. Este comando revoca todas las credenciales emitidas por el rol, y Vault responde All revocation operations queued successfully!. La revocación es asíncrona: en nuestra prueba, una consulta a pg_roles justo después todavía listaba dos usuarios v-token-*, y la siguiente ya no encontró ninguno:
vault lease revoke -prefix database/creds/api_service

Patrones operativos relevantes
Secretos dinámicos vs. estáticos
Vault admite ambos. Los dinámicos (generados al pedir) son más seguros, pero no todos los sistemas los admiten bien. Los estáticos con rotación automática (Vault rota el secreto periódicamente) son un buen término medio para sistemas legacy.
Auto-unseal
Al arrancar, Vault está «sellado»: los secretos cifrados no son accesibles hasta usar una clave maestra. Auto-unseal con AWS KMS, Azure Key Vault, GCP Cloud KMS o el motor Transit elimina la necesidad de introducir claves manualmente (lista completa de seals[14]). Imprescindible para alta disponibilidad.
Integración con Kubernetes
Vault Agent Injector[15] inyecta secretos en pods como ficheros montados, sincronizados automáticamente. El pod nunca ve un token de autenticación estático; autentica con su ServiceAccount de Kubernetes.
Integración con CI/CD
GitHub Actions, GitLab CI y Jenkins pueden autenticarse a Vault con tokens de corta duración generados por OIDC o JWT. El pipeline pide los secretos al ejecutar, sin almacenarlos en variables de entorno persistentes.
Flujo de Terraform, otra herramienta de HashiCorp: control de versiones, plan y apply (Imagen: dsmscm, CC BY-SA 4.0, vía Wikimedia Commons)
Qué conviene no hacer
Estos son los errores que se repiten:
-
Usar Vault solo como «KV bonito». Si solo almacenas pares clave-valor estáticos, la ganancia sobre un
.envbien protegido es marginal. El valor viene de dynamic secrets, rotación y auditoría. -
Dejar el root token activo. Tiene permisos completos y no debe usarse más allá de la configuración inicial. Revocarlo después de generar tokens y políticas operativas.
-
Una sola instancia sin HA. Vault caído = despliegues caídos. En producción, al menos 3 nodos con raft o Consul.
-
Políticas permisivas tipo wildcard.
path "*" { capabilities = ["read"] }anula el valor de Vault. La granularidad por servicio es la norma.
Alternativas
Además de OpenBao, que conserva la API de Vault con licencia MPL 2.0, hay otras opciones válidas:
-
AWS Secrets Manager / GCP Secret Manager / Azure Key Vault: si estás 100 % en un solo cloud, la integración nativa puede ser suficiente.
-
Infisical[16]: plataforma de código abierto con licencia MIT (salvo el directorio
ee) e interfaz más amigable; sus secretos dinámicos[17] requieren el plan de pago Advanced. -
1Password for Teams[18]: adecuado para equipos pequeños donde los secretos son mayormente humanos.
-
Sealed Secrets + External Secrets Operator: patrón GitOps para K8s sin necesidad de Vault.
Ver también cómo la directiva NIS2 refuerza la necesidad de gestión formal de secretos en ciertos sectores, y ataques a la cadena de suministro, vector habitual de intrusión cuando las credenciales están comprometidas.
Conclusión
Vault es la opción más completa para gestión de secretos, pero también la más exigente operativamente. Para equipos que todavía viven con .env distribuidos, el primer paso es decidir si la inversión operativa de Vault se justifica o si una alternativa más simple cubre el caso. Desde 2023 esa decisión incluye la licencia: BUSL en Vault, MPL 2.0 en OpenBao. Lo que no es opción es «seguir como estamos».
Preguntas frecuentes
¿Merece la pena Vault si solo voy a guardar pares clave-valor?
Poco: si solo almacenas secretos estáticos, la ganancia sobre un .env bien protegido es marginal. El valor de Vault está en los secretos dinámicos, que generan credenciales efímeras al pedirlas con un TTL configurable (por ejemplo 1 hora) y las revocan automáticamente. También está en la rotación automática para sistemas legacy y en la auditoría de cada operación. Si una credencial se filtra, caduca en minutos, no en años.
¿Qué necesito para operar Vault en producción con alta disponibilidad?
Al menos 3 nodos con raft o Consul, porque un Vault caído significa despliegues caídos. Añade auto-unseal con AWS KMS, Azure Key Vault, GCP Cloud KMS o el motor Transit para que los nodos no requieran introducir la clave maestra a mano al arrancar. Revoca también el root token tras la configuración inicial, define políticas HCL granulares por servicio en lugar de wildcards como path "*" y activa un audit device (file, syslog o socket) para compliance. Si actualizas a Vault 2.x, revisa tus procedimientos de generate-root y rekey, que ahora exigen un token válido.
¿Cómo obtienen los pods de Kubernetes los secretos sin un token estático?
Mediante Vault Agent Injector, que inyecta los secretos en el pod como ficheros montados y los sincroniza automáticamente. El pod nunca ve un token de autenticación estático: se autentica ante Vault con su ServiceAccount de Kubernetes y las políticas se aplican según ese método de autenticación. Para CI/CD el patrón equivalente son tokens de corta duración generados por OIDC o JWT en GitHub Actions, GitLab CI o Jenkins.
¿Vault sigue siendo de código abierto?
Su código sigue siendo público, pero desde Vault 1.15.0 y 1.14.9 la licencia es la Business Source License 1.1 en lugar de la MPL 2.0. La BUSL permite usarlo en producción, pero prohíbe ofrecerlo a terceros dentro de un producto de pago que compita con las versiones de pago de Vault. Cada versión pasa a MPL 2.0 cuatro años después de publicarse. Si necesitas la licencia MPL hoy, OpenBao es el fork de Vault que mantiene la OpenSSF, con la 2.6.2 como versión estable en septiembre de 2026.
Fuentes
- HashiCorp Vault
- Vault 2.1.0
- imagen oficial
- cambios importantes de Vault
- changelog de la serie 1.x
- LICENSE de la rama main
- completó la compra de HashiCorp
- de la etiqueta v2.1.0
- OpenBao
- 2.6.2
- motor de secretos de PostgreSQL
- hvac
- psycopg
- lista completa de seals
- Vault Agent Injector
- Infisical
- secretos dinámicos
- 1Password for Teams
- Documentación oficial de HashiCorp Vault
- OWASP Secrets Management Cheat Sheet