Vault: Secrets Management for the Modern Stack
Database passwords in config files. API keys in environment variables. AWS credentials in source code. We've all done it—we needed to move fast, and security took a backseat. But in a world where data breaches make headlines daily, this approach is untenable.
Enter HashiCorp Vault—the tool that has become the industry standard for secrets management. Whether you need to store API keys, encrypt database credentials, or manage access to sensitive infrastructure, Vault has you covered.
What Is Vault?
Vault is a tool for securely storing and accessing secrets. Developed by HashiCorp (the same company behind Terraform, Consul, and Nomad), Vault provides a unified interface to manage secrets while enforcing strict access controls and maintaining detailed audit logs.
But Vault isn't just a key-value store. It handles:
- Secrets storage — API keys, passwords, certificates
- Encryption as a service — Encrypt data without storing it
- Dynamic secrets — Generate short-lived credentials on demand
- Access management — Fine-grained policies and authentication
- Audit logging — Comprehensive access trails
Core Concepts
Secrets Engines
Vault organizes secrets into "mounts" called secrets engines. Each engine handles a specific type of secret:
- KV — Simple key-value storage (v1 and v2)
- Database — Dynamic database credentials
- AWS — Dynamic AWS credentials
- PKI — Certificate management
- Transit — Encryption as a service
- SSH — One-time SSH passwords
Authentication Methods
Vault supports multiple ways to authenticate:
- Token — The default method
- AppRole — Machine authentication
- Kubernetes — Authenticate from within K8s
- AWS IAM — Cloud identity
- LDAP/Active Directory — Enterprise identity
- OIDC — OAuth/OIDC providers
Policies
Vault policies define what paths a user or service can access:
# Read-only access to database credentials
path "database/creds/readonly" {
capabilities = ["read"]
}
# Full access to KV secrets
path "kv/data/myapp/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
Getting Started
# Download and extract Vault
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/
# Start Vault in dev mode (for testing)
vault server -dev
# Export VAULT_ADDR and VAULT_TOKEN
export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN='your-token-here'
# Check status
vault status
Writing Secrets
# Enable KV secrets engine
vault secrets enable -path=secret kv
# Write a secret
vault kv put secret/myapp api_key=abc123 password=secretpass
# Read a secret
vault kv get secret/myapp
# Delete a secret
vault kv delete secret/myapp
Dynamic Secrets
One of Vault's most powerful features is dynamic secrets—credentials generated on-demand that automatically expire:
# Enable AWS secrets engine
vault secrets enable aws
# Configure AWS credentials
vault write aws/config/root \
access_key=AKIAIOSFODNN7EXAMPLE \
secret_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY \
region=us-east-1
# Generate temporary AWS credentials
vault read aws/creds/my-role
# Result:
# Key Value
# --- -----
# access_key ASIA...
# secret_key ...
# expiration 2024-01-15T15:30:00Z
These credentials will automatically expire after the TTL. No need to rotate them manually.
Encryption as a Service
Need to encrypt data but don't want to manage keys? Use the transit secrets engine:
# Enable transit secrets engine
vault secrets enable transit
# Create an encryption key
vault write -f transit/keys/my-key
# Encrypt data
vault transit encrypt transit/plaintext $(echo "sensitive data" | base64)
# Decrypt data
vault transit decrypt transit/ciphertext vault:v1:abc123...
Integrations
Vault integrates with practically everything:
- Kubernetes — Vault Agent Injector for automatic secret injection
- Terraform — Provider for managing Vault resources
- Databases — MySQL, PostgreSQL, MongoDB, and more
- Clouds — AWS, GCP, Azure
- Applications — SDKs for every language
Kubernetes Integration
The Vault Agent Injector automatically injects secrets into pods:
# Annotate a deployment to receive secrets
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "myapp"
vault.hashicorp.com/agent-inject-secret-config: "secret/data/myapp"
Secrets appear in /vault/secrets/config inside the container—never exposed in environment variables or config files.
Production Considerations
Running Vault in production requires planning:
High Availability
For production, use HA mode with Consul, etcd, or Raft storage:
# Raft storage (simpler, no external dependency)
vault operator init
# Unseal with key shares (requires 3 of 5 by default)
vault operator unseal
Audit Logging
Enable audit devices to track all access:
# Enable file audit log
vault audit enable file file_path=/var/log/vault/audit.log
Namespaces
For multi-tenant environments, use namespaces to isolate secrets:
# Create namespace
vault namespace create dev
# Switch to namespace
export VAULT_NAMESPACE=dev
Why Vault Matters
In an era where credential theft is among the most common attack vectors, Vault addresses a critical need:
- No more hardcoded secrets — Everything retrieved dynamically
- Automatic rotation — Dynamic secrets expire and rotate automatically
- Fine-grained access — Policies ensure least privilege
- Complete audit trail — Know who accessed what, when
- Encryption without complexity — Encrypt data without managing keys
Secrets are like Easter eggs—the more places you hide them, the harder they are to manage.
Getting Started
- Try the dev server —
vault server -devto learn the basics - Explore the KV engine — Store and retrieve simple secrets
- Set up dynamic credentials — Try database or AWS secrets
- Write policies — Practice access control
- Add audit logging — See what's being accessed
- Integrate an app — Use the SDK in your code
Whether you're running a small project or managing enterprise infrastructure, Vault scales with you. Start simple, add complexity as needed, and sleep better knowing your secrets are secure.