HashiCorp Vault Secrets Management

February 13, 2026 | Security Vault Secrets

Dynamic credentials and K8s auth.

HashiCorp Vault: Secrets Management Guide

HashiCorp Vault provides centralized secrets management with dynamic credentials, encryption as a service, and fine-grained access control. For Kubernetes environments, Vault eliminates the need to store secrets in environment variables, config files, or even Kubernetes Secrets.

Why Vault over Kubernetes Secrets?

  • Dynamic secrets — Generate short-lived database credentials on demand
  • Automatic rotation — Credentials rotate without application changes
  • Audit logging — Every secret access is logged
  • Encryption as a service — Encrypt/decrypt data without managing keys in your application
  • Multi-platform — Works across Kubernetes, VMs, serverless, and CI/CD

Vault Architecture on Kubernetes

helm repo add hashicorp https://helm.releases.hashicorp.com
helm install vault hashicorp/vault \
  --namespace vault \
  --create-namespace \
  --set server.ha.enabled=true \
  --set server.ha.replicas=3 \
  --set server.ha.raft.enabled=true \
  --set injector.enabled=true

Kubernetes Authentication

Configure Vault to trust Kubernetes service accounts:

# Enable Kubernetes auth method
vault auth enable kubernetes

# Configure the auth method
vault write auth/kubernetes/config \
  kubernetes_host="https://kubernetes.default.svc:443"

# Create a role for your application
vault write auth/kubernetes/role/api-service \
  bound_service_account_names=api-service-sa \
  bound_service_account_namespaces=production \
  policies=api-secrets \
  ttl=1h

Static Secrets

# Store a secret
vault kv put secret/production/api-service \
  database_url="postgresql://user:pass@db:5432/app" \
  api_key="sk_live_xxxxx"

# Vault policy for the application
path "secret/data/production/api-service" {
  capabilities = ["read"]
}

Dynamic Database Credentials

Vault generates unique, short-lived database credentials for each request:

# Configure database secrets engine
vault secrets enable database

vault write database/config/postgres \
  plugin_name=postgresql-database-plugin \
  connection_url="postgresql://{{username}}:{{password}}@postgres:5432/app" \
  allowed_roles="api-role" \
  username="vault_admin" \
  password="admin_password"

# Create a role that generates credentials
vault write database/roles/api-role \
  db_name=postgres \
  creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
  default_ttl=1h \
  max_ttl=24h

Vault Agent Sidecar Injection

Automatically inject secrets into pods:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-service
spec:
  template:
    metadata:
      annotations:
        vault.hashicorp.com/agent-inject: "true"
        vault.hashicorp.com/role: "api-service"
        vault.hashicorp.com/agent-inject-secret-config: "secret/data/production/api-service"
        vault.hashicorp.com/agent-inject-template-config: |
          {{- with secret "secret/data/production/api-service" -}}
          DATABASE_URL={{ .Data.data.database_url }}
          API_KEY={{ .Data.data.api_key }}
          {{- end -}}
    spec:
      serviceAccountName: api-service-sa
      containers:
      - name: api
        image: api:latest
        # Secrets are available at /vault/secrets/config

Secret Rotation

  • Dynamic secrets — Automatically expire and regenerate (no rotation needed)
  • Static secrets — Use Vault's rotation API or external triggers
  • PKI certificates — Vault can issue and auto-renew TLS certificates

Eazy SaaS Tip: We deploy Vault with dynamic database credentials as standard for production environments. Each application request gets unique, time-limited credentials — if a credential is compromised, it expires within an hour. This is a game-changer for database security.