Skip to content

HashiCorp Vault — Operations

Scope

Production deployment, seal/unseal procedures, secret engines, audit logging, and HA patterns for HashiCorp Vault.

Deployment Patterns

HA Architectures

Pattern Storage Backend Auto-Unseal Use Case
Integrated Raft Built-in Raft AWS KMS / Azure Key Vault Most deployments
Consul Backend Consul cluster Cloud KMS Legacy, transitioning away
External PostgreSQL PostgreSQL Cloud KMS Managed DB preference
# Raft storage (recommended)
storage "raft" {
  path    = "/vault/data"
  node_id = "vault-0"
  retry_join {
    leader_api_addr = "https://vault-1:8200"
  }
}

# Auto-unseal with AWS KMS
seal "awskms" {
  region     = "us-east-1"
  kms_key_id = "alias/vault-unseal"
}

Kubernetes Deployment (Helm)

helm install vault hashicorp/vault \
  --namespace vault --create-namespace \
  --set server.ha.enabled=true \
  --set server.ha.replicas=3 \
  --set server.ha.raft.enabled=true \
  --set server.auditStorage.enabled=true \
  --set injector.enabled=true

Secret Engines

Engine Use Case Path
KV v2 Static secrets secret/
PKI TLS certificates pki/
Transit Encryption as a Service transit/
Database Dynamic DB credentials database/
AWS Dynamic IAM credentials aws/
Kubernetes Service account tokens kubernetes/

Dynamic Database Secrets

# Configure database secret engine
vault write database/config/mydb \
  plugin_name=postgresql-database-plugin \
  connection_url="postgresql://{{username}}:{{password}}@db:5432/mydb" \
  allowed_roles="readonly" \
  username="vault" \
  password="vault-password"

# Create role
vault write database/roles/readonly \
  db_name=mydb \
  creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
  default_ttl="1h" \
  max_ttl="24h"

# Get dynamic credentials
vault read database/creds/readonly

Seal/Unseal Operations

# Initialize (first time only)
vault operator init -key-shares=5 -key-threshold=3

# Manual unseal (without auto-unseal)
vault operator unseal <key1>
vault operator unseal <key2>
vault operator unseal <key3>

# Check seal status
vault status

Recovery Keys

With auto-unseal enabled, the unseal keys become recovery keys. Store them securely (e.g., in separate physical safes or HSMs).

Audit Logging

# Enable file audit
vault audit enable file file_path=/vault/audit/audit.log

# Enable syslog
vault audit enable syslog tag="vault" facility="AUTH"

Monitoring

# Token creation rate
rate(vault_token_create_count[5m])

# Authentication failures
vault_core_handle_login_request{error!=""}

# Seal status
vault_core_unsealed

# Storage backend latency
vault_barrier_put{quantile="0.99"}

Common Issues

Issue Root Cause Resolution
Vault sealed after restart No auto-unseal configured Configure cloud KMS auto-unseal
Token expired TTL misconfigured Increase default_ttl or use periodic tokens
Policy denied Insufficient permissions Review policy paths and capabilities
Raft leader election failures Network partition Check node connectivity, raft peers
High memory usage Too many leases Review lease TTLs, enable revocation