Why Static Secrets Are a Liability
Every static credential is a liability that grows with time. It gets copied to laptops, CI systems, documentation, and Slack messages. Vault makes secrets dynamic and short-lived.
Vault Auto-Unseal with AWS KMS
seal "awskms" {
region = "us-east-1"
kms_key_id = "mrk-..."
}
storage "raft" {
path = "/opt/vault/data"
node_id = "vault-01"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/etc/vault.d/tls/vault.crt"
tls_key_file = "/etc/vault.d/tls/vault.key"
}
Dynamic Database Credentials
vault secrets enable database
vault write database/config/myapp \
plugin_name=postgresql-database-plugin \
allowed_roles="myapp-role" \
connection_url="postgresql://{{username}}:{{password}}@db:5432/myapp" \
username="vault" \
password="vaultpassword"
vault write database/roles/myapp-role \
db_name=myapp \
default_ttl="1h" \
max_ttl="24h"
AppRole Auth for Applications
vault auth enable approle
vault write auth/approle/role/myapp token_policies="myapp-policy" token_ttl=1h
ROLE_ID=$(vault read -field=role_id auth/approle/role/myapp/role-id)
SECRET_ID=$(vault write -f -field=secret_id auth/approle/role/myapp/secret-id)
vault write auth/approle/login role_id=$ROLE_ID secret_id=$SECRET_ID
Defensive Takeaways
- Enable audit logging — every secret read should be logged
- Use response wrapping for initial secret delivery (
vault write -wrap-ttl=60s) - Set appropriate TTLs — 1h for app credentials, shorter for break-glass access
- Test disaster recovery: practice Vault unsealing from backup at least annually
Keep going
Get the next writeup in your inbox
New posts delivered when I publish. No spam.