Skip to content

Vault by HashiCorp

Vault es una herramienta de HashiCorp para gestionar secretos y proteger datos sensibles como contraseñas, tokens, claves API y certificados. Proporciona acceso seguro a secretos mediante control de acceso estricto y auditoría completa. Entre sus características podemos destacar:

  • Centralización: Un solo lugar para todos los secretos
  • Encriptación: Datos encriptados en reposo y tránsito
  • Auditoría: Registro completo de accesos
  • Rotación automática: Para credenciales dinámicas
  • Integraciones: Soporte para múltiples plataformas
  • Control de acceso: Políticas granulares

Esta es una guía esencial para introducirse en la gestión de secretos con Vault

Conceptos clave

  • Secrets: Datos sensibles almacenados de forma segura
  • Secrets Engine: Módulo que gestiona tipos específicos de secretos (KV, database, AWS, etc.)
  • Path: Ruta donde se almacenan los secretos (ej: secret/myapp/config)
  • Token: Credencial para autenticarse en Vault
  • Policy: Reglas que definen quién puede acceder a qué secretos
  • Seal/Unseal: Estado de Vault (sellado/desellado para acceso)

Instalación y configuración de Vault

Instalación de Vault por Sistema Operativo

bash
# Linux/macOS
wget https://releases.hashicorp.com/vault/1.15.0/vault_1.15.0_linux_amd64.zip
unzip vault_1.15.0_linux_amd64.zip
sudo mv vault /usr/local/bin/

# macOS con Homebrew
brew install vault

# Verificar instalación
vault --version

Modo desarrollo (solo para pruebas)

bash
# Iniciar Vault en modo dev
vault server -dev

# En otra terminal, configurar variables
export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN='hvs.xxxxx'  # Token mostrado al iniciar

# Verificar estado
vault status

Docker

bash
docker run -d \
  --name vault \
  -p 8200:8200 \
  -e VAULT_DEV_ROOT_TOKEN_ID="myroot" \
  -e VAULT_DEV_LISTEN_ADDRESS="0.0.0.0:8200" \
  hashicorp/vault:latest

export VAULT_ADDR='http://localhost:8200'
export VAULT_TOKEN='myroot'

Operaciones básicas

Almacenar y recuperar secretos

bash
# Escribir secreto
vault kv put secret/myapp/config \
  username="admin" \
  password="secret123" \
  api_key="abc-xyz-789"

# Leer secreto
vault kv get secret/myapp/config

# Leer en formato JSON
vault kv get -format=json secret/myapp/config

# Leer campo específico
vault kv get -field=password secret/myapp/config

# Listar secretos
vault kv list secret/myapp

# Eliminar secreto
vault kv delete secret/myapp/config

Políticas de acceso

bash
# Crear política
vault policy write myapp-policy - <<EOF
path "secret/data/myapp/*" {
  capabilities = ["read", "list"]
}
EOF

# Listar políticas
vault policy list

# Crear token con política
vault token create -policy=myapp-policy

Ejemplo con JavaScript (Node.js)

Primero instalas el módulo node-vault (npm install node-vault) y como ejemplo esencial tendríamos un código como el siguiente:

javascript
const vault = require('node-vault')({
  apiVersion: 'v1',
  endpoint: 'http://localhost:8200',
  token: 'myroot'
});

async function vaultEasy() {
  try {
    // Escribir secreto
    await vault.write('secret/data/myapp/db', {
      data: {
        host: 'localhost',
        port: 5432,
        username: 'dbuser',
        password: 'dbpass123'
      }
    });
    console.log('Secret stored successfully');

    // Leer secreto
    const result = await vault.read('secret/data/myapp/db');
    const secrets = result.data.data;
    
    console.log('Database config:');
    console.log(`Host: ${secrets.host}`);
    console.log(`Port: ${secrets.port}`);
    console.log(`Username: ${secrets.username}`);
    console.log(`Password: ${secrets.password}`);

    // Listar secretos
    const list = await vault.list('secret/metadata/myapp');
    console.log('Available secrets:', list.data.keys);

  } catch (error) {
    console.error('Error:', error.message);
  }
}

vaultEasy();

Ejemplo con Java (JBang)

Semejante al anterior ejemplo, para Java podemos usar (JBang)[/docs/code/es/JBang]. Veamos el código:

java
///usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS com.bettercloud:vault-java-driver:5.1.0
//JAVA 21

import com.bettercloud.vault.*;
import com.bettercloud.vault.response.*;
import java.util.Map;

public class VaultEasy {

    public static void main(String[] args) throws VaultException {
        System.out.println("Vault with Java");
        System.out.println("===============\n");

        // Configurar Vault
        VaultConfig config = new VaultConfig()
            .address("http://localhost:8200")
            .token("myroot")
            .build();

        Vault vault = new Vault(config);

        // Escribir secreto
        System.out.println("Writing secret...");
        Map<String, Object> secrets = Map.of(
            "api_key", "sk-abc123xyz",
            "api_secret", "secret-token-456",
            "environment", "production"
        );

        vault.logical()
            .write("secret/data/myapp/api", secrets);
        System.out.println("Secret stored successfully\n");

        // Leer secreto
        System.out.println("Reading secret...");
        LogicalResponse response = vault.logical()
            .read("secret/data/myapp/api");

        Map<String, String> data = response.getData();
        System.out.println("API Configuration:");
        System.out.println("  API Key: " + data.get("api_key"));
        System.out.println("  API Secret: " + data.get("api_secret"));
        System.out.println("  Environment: " + data.get("environment"));

        // Listar secretos
        System.out.println("\nListing secrets...");
        LogicalResponse listResponse = vault.logical()
            .list("secret/metadata/myapp");
        
        System.out.println("Available secrets:");
        listResponse.getListData().forEach(key -> 
            System.out.println("  - " + key));
    }
}

Ejecutar:

bash
jbang VaultEasy.java

Ejemplos para integración con aplicaciones

Variables de entorno

bash
# Exportar secretos como variables
export DB_PASSWORD=$(vault kv get -field=password secret/myapp/db)
export API_KEY=$(vault kv get -field=api_key secret/myapp/api)

# Usar en aplicación
node app.js

Docker Compose

yaml
version: '3.8'

services:
  app:
    image: myapp:latest
    environment:
      VAULT_ADDR: http://vault:8200
      VAULT_TOKEN: ${VAULT_TOKEN}
    depends_on:
      - vault

  vault:
    image: hashicorp/vault:latest
    ports:
      - "8200:8200"
    environment:
      VAULT_DEV_ROOT_TOKEN_ID: myroot

Vault es esencial para gestionar secretos en entornos modernos, especialmente en arquitecturas de microservicios y contenedores donde la seguridad y el control de acceso son críticos.