HashiCorp Vault Best Practices: Secrets Management Done Right
Dynamic secrets, auth methods, policy design, and the operational mistakes teams make when scaling Vault in production Kubernetes environments.
Why secrets management is harder than it looks
Most teams start with static secrets in environment variables or config files. It works — until it doesn't. A leaked .env file, a rotated credential that breaks three services, a shared admin password that half the team knows. HashiCorp Vault solves these problems systematically, but only if you use it correctly.
Having deployed and operated Vault across multiple Kubernetes environments, here are the patterns that matter most.
1. Use Dynamic Secrets Wherever Possible
Static secrets are Vault's least powerful feature. Dynamic secrets are where it shines. Instead of storing a database password, Vault generates a unique, time-limited credential on demand — and automatically revokes it when the lease expires.
# Enable the database secrets engine
vault secrets enable database
# Configure a PostgreSQL connection
vault write database/config/my-db \
plugin_name=postgresql-database-plugin \
connection_url="postgresql://{{username}}:{{password}}@db:5432/mydb" \
allowed_roles="app-role"
# Create a role with a short TTL
vault write database/roles/app-role \
db_name=my-db \
creation_statements="CREATE ROLE ..." \
default_ttl="1h" \
max_ttl="24h"
2. Auth Methods: Choose the Right One
In Kubernetes environments, the Kubernetes auth method is the right choice for workload identity. It lets pods authenticate to Vault using their ServiceAccount JWT token — no static credentials required.
vault auth enable kubernetes
vault write auth/kubernetes/config \
kubernetes_host="https://kubernetes.default.svc" \
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
vault write auth/kubernetes/role/my-app \
bound_service_account_names=my-app-sa \
bound_service_account_namespaces=production \
policies=my-app-policy \
ttl=1h
For human operators, prefer OIDC auth tied to your identity provider (Okta, Azure AD, Google Workspace). Avoid userpass auth in production — it's a static credential anti-pattern.
3. Policy Design: Least Privilege
Vault policies should be narrow and explicit. The biggest mistake I see is teams writing overly broad policies because it's easier than being precise.
# Bad: too broad
path "secret/*" {
capabilities = ["read", "list", "create", "update", "delete"]
}
# Good: scoped to what the app actually needs
path "secret/data/myapp/{{identity.entity.name}}/*" {
capabilities = ["read"]
}
path "database/creds/myapp-role" {
capabilities = ["read"]
}
4. Vault Agent for Kubernetes Workloads
Vault Agent Injector is the cleanest way to deliver secrets to Kubernetes pods. It injects a sidecar that authenticates to Vault, fetches secrets, and writes them as files or environment variables — without your application code ever touching Vault directly.
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "my-app"
vault.hashicorp.com/agent-inject-secret-config: "secret/data/myapp/config"
vault.hashicorp.com/agent-inject-template-config: |
{{- with secret "secret/data/myapp/config" -}}
DB_PASSWORD={{ .Data.data.db_password }}
API_KEY={{ .Data.data.api_key }}
{{- end }}
5. Operational Best Practices
Auto-unseal
Manual unseal using operator keys is a single-point-of-failure in production. Use cloud auto-unseal — AWS KMS, Azure Key Vault, or GCP Cloud KMS — so Vault automatically unseals after a restart without human intervention.
Audit logging
Enable audit devices from day one. Every request to Vault is logged, including the token used, the path accessed, and the response code. This is invaluable for incident response and compliance.
vault audit enable file file_path=/var/log/vault/audit.log
Lease management
Monitor and manage leases actively. Leaked leases consume Vault resources and can hit limits. Set aggressive TTLs and implement lease renewal in your applications rather than relying on max TTL.
Common Mistakes to Avoid
Final thoughts
Vault is one of those tools where the distance between "using it" and "using it well" is significant. The patterns above — dynamic secrets, appropriate auth methods, least-privilege policies, and Vault Agent for Kubernetes — cover the majority of what a production Vault deployment needs.
If you're starting fresh, begin with the Kubernetes auth method and KV v2. Add dynamic secrets as you identify static credentials in your stack. Build audit logging from day one. The incremental approach works well here.