--- name: implementing-hashicorp-vault-dynamic-secrets description: 'Implements HashiCorp Vault dynamic secrets engines for database credentials, AWS IAM keys, and PKI certificates with automatic generation, lease management, and credential rotation to eliminate static secrets in application configurations. Activates for requests involving Vault secrets engine configuration, dynamic database credentials, ephemeral cloud credentials, or automated secret rotation. ' domain: cybersecurity subdomain: identity-access-management tags: - HashiCorp-Vault - dynamic-secrets - secrets-management - database-credentials - AWS-secrets - PKI version: '1.0' author: mahipal license: Apache-2.0 nist_csf: - PR.AA-01 - PR.AA-02 - PR.AA-05 - PR.AA-06 --- # Implementing HashiCorp Vault Dynamic Secrets ## When to Use - Applications use static database credentials stored in configuration files or environment variables - AWS IAM access keys are long-lived and shared across services - Need to eliminate credential sprawl by generating short-lived, per-request secrets - Compliance requirements mandate credential rotation (PCI-DSS Requirement 8, NIST 800-53 IA-5) - Implementing zero-trust secret management where credentials are never stored at rest - Migrating from manual credential management to automated secrets lifecycle **Do not use** for storing static secrets that cannot be dynamically generated (use Vault's KV secrets engine instead); dynamic secrets are for credentials that can be programmatically created and revoked on target systems. ## Prerequisites - HashiCorp Vault 1.15+ (Community or Enterprise edition) - Vault server initialized and unsealed with auto-unseal configured (AWS KMS, Azure Key Vault, or Transit) - Target database systems with admin credentials for Vault to create/revoke dynamic accounts - AWS IAM account with permissions to create/delete IAM users and access keys - Network connectivity from Vault to all target systems - Vault policies and authentication methods configured for consuming applications ## Workflow ### Step 1: Deploy and Configure Vault Server Initialize Vault with production-grade configuration: ```hcl # vault-config.hcl - Production Vault server configuration storage "raft" { path = "/opt/vault/data" node_id = "vault-1" retry_join { leader_api_addr = "https://vault-2.corp.local:8200" } retry_join { leader_api_addr = "https://vault-3.corp.local:8200" } } listener "tcp" { address = "0.0.0.0:8200" tls_cert_file = "/opt/vault/tls/vault-cert.pem" tls_key_file = "/opt/vault/tls/vault-key.pem" } seal "awskms" { region = "us-east-1" kms_key_id = "alias/vault-unseal-key" } api_addr = "https://vault-1.corp.local:8200" cluster_addr = "https://vault-1.corp.local:8201" telemetry { prometheus_retention_time = "24h" disable_hostname = true } ui = true ``` ```bash # Initialize Vault cluster vault operator init -key-shares=5 -key-threshold=3 # Enable audit logging vault audit enable file file_path=/var/log/vault/audit.log # Enable AppRole authentication for applications vault auth enable approle # Create policy for database secret consumers vault policy write db-consumer - <, lease_id=database/creds/app-readonly/xxxxx ``` ### Step 3: Configure AWS Secrets Engine Generate ephemeral AWS IAM credentials: ```bash # Enable the AWS secrets engine vault secrets enable aws # Configure the AWS secrets engine with root credentials vault write aws/config/root \ access_key="$AWS_ACCESS_KEY_ID" \ secret_key="$AWS_SECRET_ACCESS_KEY" \ region="us-east-1" # Configure lease settings vault write aws/config/lease \ lease="30m" \ lease_max="1h" # Create IAM User role for S3 read-only access vault write aws/roles/s3-readonly \ credential_type=iam_user \ policy_document=-< vault_audit_monitor.sh << 'SCRIPT' #!/bin/bash # Monitor Vault audit logs for suspicious activity AUDIT_LOG="/var/log/vault/audit.log" # Count credential requests per hour echo "=== Dynamic Credential Requests (Last Hour) ===" jq -r 'select(.type == "response" and .request.path | startswith("database/creds/")) | "\(.time) \(.request.path) \(.auth.display_name)"' \ "$AUDIT_LOG" | tail -100 # Detect unusual credential request patterns echo "" echo "=== High-Volume Credential Consumers ===" jq -r 'select(.type == "request" and .request.path | startswith("database/creds/")) | .auth.display_name' \ "$AUDIT_LOG" | sort | uniq -c | sort -rn | head -10 # Check for failed authentication attempts echo "" echo "=== Failed Auth Attempts ===" jq -r 'select(.type == "response" and .error != null and .request.path | startswith("auth/")) | "\(.time) \(.request.path) \(.error)"' \ "$AUDIT_LOG" | tail -20 SCRIPT chmod +x vault_audit_monitor.sh ``` ## Key Concepts | Term | Definition | |------|------------| | **Dynamic Secrets** | Credentials generated on-demand by Vault with automatic expiration, ensuring each consumer receives unique short-lived credentials | | **Lease** | Time-bound agreement where Vault guarantees the credential is valid; consumers must renew before expiration or request new credentials | | **Secrets Engine** | Vault plugin that generates, stores, or encrypts data; database, AWS, PKI, and KV are common engines | | **AppRole** | Vault authentication method designed for machine-to-machine authentication using role ID and secret ID pairs | | **Root Credential Rotation** | Process of having Vault take exclusive ownership of the admin credential used to create dynamic secrets, eliminating human knowledge of the root password | | **Lease Revocation** | Immediate invalidation of dynamic credentials, used during incident response to revoke all credentials for compromised paths | ## Tools & Systems - **HashiCorp Vault**: Secrets management platform providing dynamic secrets, encryption as a service, and identity-based access control - **Vault Agent**: Sidecar process that handles Vault authentication, token renewal, and secret caching for applications - **Vault Secrets Operator**: Kubernetes operator that syncs Vault secrets into Kubernetes Secrets for pod consumption - **hvac**: Python client library for HashiCorp Vault API operations ## Common Scenarios ### Scenario: Eliminating Static Database Credentials in Microservices **Context**: 50 microservices share 3 static PostgreSQL credentials stored in environment variables across Kubernetes deployments. A credential leak requires rotating all 50 services simultaneously. **Approach**: 1. Deploy Vault with Raft storage in a 3-node HA cluster within Kubernetes 2. Configure database secrets engine with PostgreSQL connection using admin credentials 3. Create per-service Vault roles with least-privilege SQL grants 4. Deploy Vault Secrets Operator to inject dynamic credentials into pod environment variables 5. Update application connection logic to handle credential rotation via lease renewal 6. Rotate the Vault root credential to remove human knowledge of the admin password 7. Monitor lease lifecycle and set alerts for renewal failures **Pitfalls**: - Not handling credential rotation in application connection pools (connections using expired credentials fail) - Setting TTLs too short causes excessive credential generation load on the database - Not configuring proper revocation statements leaves orphaned database users after lease expiration - Running Vault without HA causes single point of failure for all application authentication ## Output Format ``` HASHICORP VAULT DYNAMIC SECRETS REPORT ========================================= Vault Version: 1.16.2 Enterprise Cluster Status: HA Active (3 nodes) Seal Type: AWS KMS (auto-unseal) SECRETS ENGINES database/: PostgreSQL, MySQL (2 connections) aws/: IAM User, Assumed Role, Federation Token pki_int/: Internal CA (EC P-256) DYNAMIC CREDENTIAL METRICS (Last 24 Hours) Total Credentials Generated: 4,287 Database (PostgreSQL): 2,891 Database (MySQL): 543 AWS STS: 612 PKI Certificates: 241 ACTIVE LEASES Total Active: 387 database/creds/app-readonly: 198 database/creds/app-readwrite: 89 aws/creds/s3-readonly: 67 pki_int/issue/web-server: 33 LEASE LIFECYCLE Average TTL: 45 minutes Renewals (24h): 12,847 Revocations (24h): 3,901 Expired (not renewed): 12 SECURITY Failed Auth Attempts (24h): 3 Root Credential Rotated: YES (all databases) Audit Logging: ENABLED (file + syslog) Policy Violations (24h): 7 (permission denied) ```