CloudOpsGuide
devsecops

HashiCorp Vault for DevOps: Secrets That Expire and Rotate

Advanced
11 minutes
October 2026
CloudOpsGuide Team

HashiCorp Vault for DevOps: Secrets That Expire and Rotate

Kubernetes Secrets and CI variables solve distribution, but real organizations need more: credentials that expire, rotate, and leave an audit trail. HashiCorp Vault is the reference implementation of that idea.

Table of Contents

What Vault actually does

Vault is a secrets service: your apps and pipelines authenticate to it, receive short-lived credentials for databases/clouds/APIs, and Vault handles issuance, rotation, and revocation. Instead of a password that lives forever, you get a lease.

  • Static secrets — key/value storage (the KV engine) for API keys and config.
  • Dynamic secrets — Vault creates credentials on demand: a real Postgres user or AWS IAM key per request, auto-deleted when the lease expires.
  • Encryption as a service — the Transit engine encrypts/decrypts data so apps never hold keys.
  • Audit log — every access, every credential issued, recorded.

Dev server: try it in minutes

vault server -dev          # ephemeral, in-memory, prints root token
export VAULT_ADDR='http://127.0.0.1:8200'

vault kv put secret/myapp db_pass=s3cret api_key=abc123
vault kv get secret/myapp
vault kv list secret/

Dev mode is for learning only — production Vault runs unsealed, backed by Raft or Consul, TLS everywhere.

The production shape

  • Seal/unseal — Vault starts sealed; key shards (Shamir) or cloud KMS auto-unseal it. This is the "can't start without ceremony" property that makes stolen disks worthless.
  • Auth methods — how clients prove themselves: Kubernetes SA tokens, AWS IAM, OIDC, AppRole for machines.
  • Policies — path-based ACLs: an app can read secret/data/myapp/* and nothing else.
  • Leases + renewal — dynamic creds have TTLs; clients renew or let them die.

Dynamic database secrets: the flagship feature

vault secrets enable database

vault write database/config/mydb \
  plugin_name=postgresql-database-plugin \
  allowed_roles="readonly" \
  connection_url="postgresql://vault:pw@db:5432/app?sslmode=disable" \
  username="vault" password="pw"

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 ..." \
  default_ttl="1h" max_ttl="24h"

# every request mints a fresh, expiring DB user:
vault read database/creds/readonly

A leaked credential here is a credential that self-destructs — that changes your incident math completely.

Getting secrets into Kubernetes

The Vault Agent Injector (sidecar) renders secrets as files inside the pod — no code changes:

annotations:
  vault.hashicorp.com/agent-inject: "true"
  vault.hashicorp.com/role: "myapp"
  vault.hashicorp.com/agent-inject-secret-db: "secret/data/myapp/db"

For GitOps-friendly flows, External Secrets Operator syncs Vault paths to native Kubernetes Secrets — apps see standard Secrets, source of truth stays in Vault.

When Vault is overkill

Small teams running a few services get 90% of the value from cloud-native secret stores (AWS Secrets Manager, GCP Secret Manager) plus External Secrets. Vault earns its operational weight when you need dynamic credentials, a hardware-grade audit trail, multi-cloud identity brokering, or PKI management. It's a platform — deploy it when you have a platform problem.

Related Articles


Last Updated: October 2026 Author: CloudOpsGuide Team Difficulty: Advanced Estimated Reading Time: 11 minutes