Skip to content
Learni
View all tutorials
Infrastructure et Sécurité

How to Secure Secrets with HashiCorp Vault in 2026

Lire en français

Introduction

HashiCorp Vault is the leading solution for centralizing the management of secrets, tokens, and certificates. In a modern DevOps context, storing plaintext passwords in code or environment variables poses a major risk. This tutorial guides you step by step through deploying Vault, configuring it, and integrating it into an application. You will learn how to create dynamic policies and access secrets securely. The progressive approach takes you from a development environment to a production-ready configuration.

Prerequisites

  • Docker and Docker Compose installed
  • Basic command-line knowledge
  • Basic understanding of TypeScript and Node.js
  • Administrator access on your machine

Deployment with Docker Compose

docker-compose.yml
version: '3.8'
services:
  vault:
    image: hashicorp/vault:1.18
    container_name: vault
    ports:
      - "8200:8200"
    environment:
      VAULT_DEV_ROOT_TOKEN_ID: "dev-only-token"
      VAULT_DEV_LISTEN_ADDRESS: "0.0.0.0:8200"
    cap_add:
      - IPC_LOCK

This file starts Vault in development mode with a fixed root token. Dev mode is ideal for testing but never for production.

Initialization and Unsealing

init-vault.sh
#!/bin/bash
export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN='dev-only-token'
vault status
vault secrets enable -path=secret kv-v2
vault kv put secret/app/config username="admin" password="s3cr3t"

Enables the KV v2 engine and stores an initial key-value pair. The dev token provides immediate access without full initialization.

Creating a Policy

app-policy.hcl
path "secret/data/app/config" {
  capabilities = ["read"]
}
path "secret/metadata/app/*" {
  capabilities = ["list"]
}

This policy allows only reading the application's secrets. Limiting permissions is essential to follow the principle of least privilege.

Applying the Policy

apply-policy.sh
vault policy write app-policy app-policy.hcl
vault token create -policy=app-policy -ttl=1h

Creates a token with the restricted policy. The application will use this token to read secrets without administrative rights.

Node.js Client to Read Secrets

src/vault-client.ts
import * as vault from 'node-vault';

const client = vault({
  apiVersion: 'v1',
  endpoint: 'http://127.0.0.1:8200',
  token: process.env.VAULT_TOKEN
});

export async function getAppConfig() {
  const result = await client.read('secret/data/app/config');
  return result.data.data;
}

The client uses the limited token to retrieve secrets. Always validate the token's presence before any request in production.

Integration into an Express API

src/server.ts
import express from 'express';
import { getAppConfig } from './vault-client';

const app = express();
app.get('/config', async (req, res) => {
  try {
    const config = await getAppConfig();
    res.json(config);
  } catch (error) {
    res.status(500).json({ error: 'Impossible to retrieve secrets' });
  }
});
app.listen(3000, () => console.log('Server started'));

The API exposes configuration data without ever hard-coding it. Handle errors to prevent leaks of sensitive information.

Best Practices

  • Always use short-lived tokens and renew them automatically
  • Enable audit logging to track all secret accesses
  • Prefer the KV v2 engine for versioning and secure deletion
  • Separate environments using namespaces or distinct Vault instances
  • Integrate Vault into CI/CD pipelines using dynamic authentication roles

Common Mistakes to Avoid

  • Leaving dev mode enabled in production
  • Granting overly broad permissions to application tokens
  • Forgetting to encrypt data at rest with an external KMS
  • Storing the root token in source code or environment variables

Going Further

Explore Kubernetes authentication and dynamic database secrets. Discover our advanced security training.