Secrets Management Guide
A zero-trust secrets architecture guide with production-ready HashiCorp Vault configurations and cloud-native secrets manager integrations. Covers the full lifecycle — generation, storage, access, rotation, and revocation — with working HCL configs, Python scripts, and patterns that eliminate hardcoded credentials.
Key Features
- HashiCorp Vault Setup — Complete HCL configurations for Vault server, including Raft storage, auto-unseal with cloud KMS, and HA clustering.
- Dynamic Secrets Engine — Generate short-lived database credentials, cloud IAM keys, and PKI certificates on demand.
- Rotation Automation — Python scripts for rotating passwords, API keys, and TLS certificates on schedule.
- Access Policy Templates — Vault ACL policies implementing least-privilege for devs, CI/CD, and apps.
- Cloud Secrets Integration — Wrapper scripts for AWS Secrets Manager, Azure Key Vault, and GCP Secret Manager.
- Emergency Revocation — Runbooks for immediate credential revocation and key rotation.
- Secret Detection Scanner — Python script scanning codebases for committed secrets.
Quick Start
# Extract the guide
unzip secrets-management-guide.zip
cd secrets-management-guide/
# Scan your codebase for hardcoded secrets
python3 scripts/secret_scanner.py --path /path/to/your/project --output findings.json
# Deploy Vault with the provided config
cp configs/vault/vault.hcl /etc/vault.d/vault.hcl
vault server -config=/etc/vault.d/vault.hcl
# Initialize and unseal
vault operator init -key-shares=5 -key-threshold=3
vault operator unseal # Repeat with 3 different keys
Vault Server Configuration
# configs/vault/vault.hcl — Production Vault configuration
storage "raft" {
path = "/opt/vault/data"
node_id = "vault-node-1"
}
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"
tls_disable = false
}
# Auto-unseal with cloud KMS (eliminates manual unseal keys)
seal "awskms" {
region = "us-east-1"
kms_key_id = "YOUR_KMS_KEY_ID_HERE"
}
api_addr = "https://vault.example.com:8200"
cluster_addr = "https://vault-node-1.example.com:8201"
ui = true
Architecture / How It Works
Application ──► Auth Method ──► Vault Server ──► Secrets Engine
(AppRole, │ (KV, DB, PKI, AWS)
K8s SA) │
▼
Application ◄── Short-lived Rotation Scheduler
Credential (auto-rotate on schedule)
(auto-renew)
Every secret has a lease. Applications fetch credentials at runtime and renew before expiry. No secret is permanent.
Usage Examples
Secret Scanner
import re
from pathlib import Path
class SecretScanner:
"""Detect hardcoded secrets in source code."""
PATTERNS: dict[str, str] = {
"aws_access_key": r"AKIA[0-9A-Z]{16}",
"private_key": r"-----BEGIN (?:RSA |EC )?PRIVATE KEY-----",
"generic_api_key": r"(?i)(?:api[_-]?key|apikey)\s*[=:]\s*['\"][A-Za-z0-9]{20,}",
"generic_secret": r"(?i)(?:secret|password|passwd)\s*[=:]\s*['\"][^'\"]{8,}",
}
def __init__(self, project_path: str):
self.project_path = Path(project_path)
def scan(self) -> list[dict]:
findings = []
ignore = {".pyc", ".png", ".jpg", ".gif", ".ico"}
for fp in self.project_path.rglob("*"):
if not fp.is_file() or fp.suffix in ignore:
continue
try:
text = fp.read_text(encoding="utf-8", errors="ignore")
except OSError:
continue
for num, line in enumerate(text.splitlines(), 1):
for stype, pat in self.PATTERNS.items():
if re.search(pat, line):
findings.append({"file": str(fp.relative_to(self.project_path)),
"line": num, "type": stype, "severity": "CRITICAL"})
return findings
Vault ACL Policy — Application Role
# policies/app-readonly.hcl — Least-privilege for applications
path "secret/data/apps/{{identity.entity.aliases.auth_approle_12345.metadata.app_name}}/*" {
capabilities = ["read"]
}
path "auth/token/renew-self" { capabilities = ["update"] }
path "sys/leases/renew" { capabilities = ["update"] }
path "secret/data/apps/*" { capabilities = ["deny"] }
path "sys/*" { capabilities = ["deny"] }
Password Rotation
import secrets
import string
def generate_secure_password(length: int = 32) -> str:
"""Generate a cryptographically secure password meeting complexity requirements."""
alphabet = string.ascii_letters + string.digits + "!@#$%^&*"
while True:
pw = "".join(secrets.choice(alphabet) for _ in range(length))
if (any(c.islower() for c in pw) and any(c.isupper() for c in pw)
and any(c.isdigit() for c in pw) and any(c in "!@#$%^&*" for c in pw)):
return pw
Configuration
| Parameter | Default | Description |
|---|---|---|
vault.address |
https://vault.example.com:8200 |
Vault server URL |
vault.auth_method |
approle |
Auth method for apps |
vault.token_ttl |
1h |
Token time-to-live |
rotation.schedule |
30d |
Default rotation interval |
rotation.password_length |
32 |
Generated password length |
scanner.exclude_dirs |
[".git", "venv"] |
Dirs to skip |
Best Practices
- Never store secrets in code — Use environment variables locally, Vault/Secrets Manager for everything else.
- Use dynamic secrets — Short-lived credentials on demand beat static passwords.
- Rotate on schedule AND on suspicion — 30-day automated rotation is baseline; rotate immediately on compromise.
- Audit all access — Every secret read/write should produce an immutable audit entry.
- Separate environments strictly — Dev, staging, and prod must use separate secret paths and credentials.
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
| Vault sealed after restart | Auto-unseal not configured or KMS key inaccessible | Verify KMS key permissions; check seal stanza in vault.hcl
|
| Application gets 403 from Vault | Policy too restrictive or wrong auth role | Check vault policy read <policy> and verify AppRole bindings |
| Secret scanner false positives | Pattern matches example code or test fixtures | Add file paths to scanner.ignore_paths in config |
| Rotation script fails silently | Database connection rejected during password change | Use dual-password rotation: set new password before revoking old |
This is 1 of 9 resources in the Security Engineer Pro toolkit. Get the complete [Secrets Management Guide] with all files, templates, and documentation for $29.
Or grab the entire Security Engineer Pro bundle (9 products) for $119 — save 30%.
Top comments (0)