HashiCorp Vault Guide
Manage secrets with HashiCorp Vault: dev server quick start, KV, policies, auth methods, dynamic database credentials, unsealing and production pitfalls.
What it is and when to use it
HashiCorp Vault is a secrets management and data protection platform. It stores static secrets, generates short-lived dynamic credentials, encrypts data as a service, and issues certificates, all behind authentication, fine-grained policies and a complete audit log.
Use Vault when secrets are scattered across environment files and CI variables, when you need to rotate credentials automatically, or when you must prove who accessed what. For a small project with a handful of secrets, a cloud provider secret manager may be enough.
Quick start
The dev server runs in memory and is unsealed automatically. Never use it in production.
vault server -dev -dev-root-token-id=root &
export VAULT_ADDR=http://127.0.0.1:8200
export VAULT_TOKEN=root
vault status
vault kv put -mount=secret app/db username=app password=s3cret
vault kv get -mount=secret app/db
vault kv get -mount=secret -field=password app/db
The KV version 2 engine versions each secret, so you can inspect history with vault kv metadata get and roll back with vault kv rollback.
Core concepts
Secrets engines are pluggable backends mounted at paths: KV for static secrets, database for dynamic credentials, PKI for certificates, transit for encryption as a service, and cloud engines for AWS or Azure keys.
Auth methods verify identity and return a token. Humans use OIDC or LDAP, machines use AppRole, Kubernetes service accounts or cloud IAM. Avoid sharing the root token after initial setup.
Policies grant capabilities per path and are deny-by-default.
path "secret/data/app/*" {
capabilities = ["read", "list"]
}
path "database/creds/readonly" {
capabilities = ["read"]
}
vault policy write app-read app-read.hcl
vault auth enable approle
vault write auth/approle/role/web token_policies=app-read token_ttl=1h token_max_ttl=4h
vault read auth/approle/role/web/role-id
vault write -f auth/approle/role/web/secret-id
Leases and TTLs. Every dynamic secret and token has a lease. Vault revokes it when it expires, and clients can renew or revoke earlier.
Dynamic database credentials
Instead of sharing one long-lived password, Vault creates a unique database user per request.
vault secrets enable database
vault write database/config/pg \
plugin_name=postgresql-database-plugin \
allowed_roles=readonly \
connection_url="postgresql://{{username}}:{{password}}@db:5432/app" \
username=vaultadmin password=changeme
vault write database/roles/readonly \
db_name=pg \
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
vault read database/creds/readonly
Pitfalls
- Lost unseal keys. Production Vault starts sealed. With Shamir sharing you need a threshold of key holders, so distribute keys carefully or use auto-unseal with a cloud KMS or HSM.
- Using the root token day to day. Revoke it after bootstrapping and use scoped policies.
- No TLS. Always enable TLS on the listener in production, since tokens and secrets cross the wire.
- Single node storage. Use integrated Raft storage with at least three nodes, take regular snapshots with
vault operator raft snapshot save, and test restores. - Audit device blocking. If every enabled audit device fails, Vault stops serving requests. Enable more than one and monitor disk space.
- Overly broad policies such as a wildcard on all paths defeat the model.
- Never-expiring tokens. Use short TTLs and renewals.
- Applications that read secrets once at startup cannot handle rotation. Use Vault Agent or the CSI and sidecar injectors to refresh them.
How it fits an architecture
Vault sits as a central trust service. Workloads authenticate with their platform identity, for example a Kubernetes service account, and retrieve only what their policy allows. Vault Agent templates secrets into files or environment variables, CI pipelines request short-lived credentials through OIDC federation, and databases receive per-pod users that expire automatically. Run it as a highly available cluster across zones, ship audit logs to your log platform, and alert on seal status and failed authentications.
Key takeaways
- Vault centralizes secrets, identity-based access, leasing and auditing.
- Prefer dynamic, short-lived credentials over static shared ones.
- Write least-privilege policies; avoid the root token after setup.
- Plan unsealing, Raft storage and snapshots before going live.
- Enable TLS and at least two audit devices.
- Let Vault Agent or injectors handle renewal and rotation.