Decision Summary
| Factor | HashiCorp Vault | AWS Secrets Manager |
|---|---|---|
| Multi-cloud | โ Any cloud + on-prem | โ AWS only |
| Dynamic secrets | โ (DB, AWS, PKI, SSH) | โ (rotation only) |
| PKI/certificates | โ Built-in CA | โ Use ACM |
| Pricing | Self-hosted: free / HCP: $$$ | $0.40/secret/month + API calls |
| Complexity | High (operate yourself) | Low (managed service) |
| K8s integration | CSI driver + injector | CSI driver + SDK |
| Audit logging | โ Detailed | โ CloudTrail |
HashiCorp Vault
Vault is a secrets lifecycle platform โ it generates, stores, rotates, and revokes secrets with fine-grained access control.
Dynamic Secrets (Killer Feature)
Vault generates short-lived, unique credentials on demand:
# Generate a unique PostgreSQL credential (TTL: 1 hour)
vault read database/creds/readonly
# Output:
# Key Value
# lease_id database/creds/readonly/abc123
# lease_duration 1h
# username v-token-readonly-xyz789
# password A1B2-c3d4-E5F6-g7h8After 1 hour, Vault automatically revokes the credential. No shared passwords, no rotation needed.
Secrets Engines
| Engine | Purpose |
|---|---|
kv | Static key-value secrets |
database | Dynamic DB credentials (Postgres, MySQL, MongoDB) |
aws | Dynamic AWS IAM credentials |
pki | X.509 certificate authority |
ssh | SSH certificate signing |
transit | Encryption as a service |
totp | Time-based OTP generation |
Kubernetes Integration
# Vault Agent Injector (sidecar)
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
template:
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "app-role"
vault.hashicorp.com/agent-inject-secret-db: "database/creds/app"
vault.hashicorp.com/agent-inject-template-db: |
{{- with secret "database/creds/app" -}}
export DB_USER={{ .Data.username }}
export DB_PASS={{ .Data.password }}
{{- end -}}
spec:
serviceAccountName: app
containers:
- name: app
image: myapp:latestVault Strengths
- Dynamic secrets โ no static credentials to leak
- Multi-cloud โ one platform for AWS, Azure, GCP, on-prem
- PKI โ full certificate authority with auto-renewal
- Encryption as a service โ encrypt data without managing keys
- Namespaces โ multi-tenant secret isolation
- Disaster recovery โ replication across regions
Vault Challenges
- Operational complexity โ unsealing, HA setup, upgrades
- Learning curve โ policies, auth methods, engines
- Cost โ HCP Vault starts at $0.03/hr ($~22/month) for dev; production is $$$
- Self-hosted burden โ backups, monitoring, scaling
AWS Secrets Manager
AWS Secrets Manager is a managed secret storage service with automatic rotation support.
Basic Usage
import boto3
import json
client = boto3.client('secretsmanager', region_name='eu-west-1')
# Store a secret
client.create_secret(
Name='prod/app/database',
SecretString=json.dumps({
'username': 'app_user',
'password': 'super-secret-123',
'host': 'db.example.com',
'port': 5432
})
)
# Retrieve a secret
response = client.get_secret_value(SecretId='prod/app/database')
secret = json.loads(response['SecretString'])Automatic Rotation
# Lambda rotation function (simplified)
def lambda_handler(event, context):
secret_id = event['SecretId']
step = event['Step']
if step == 'createSecret':
# Generate new password
new_password = generate_password()
client.put_secret_value(
SecretId=secret_id,
ClientRequestToken=event['ClientRequestToken'],
SecretString=json.dumps({'password': new_password}),
VersionStages=['AWSPENDING']
)
elif step == 'setSecret':
# Update the database with new password
update_db_password(new_password)
elif step == 'testSecret':
# Verify new password works
test_db_connection(new_password)
elif step == 'finishSecret':
# Promote pending to current
client.update_secret_version_stage(...)Kubernetes Integration
# External Secrets Operator
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: app-secrets
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets-manager
kind: ClusterSecretStore
target:
name: app-secrets
data:
- secretKey: DB_PASSWORD
remoteRef:
key: prod/app/database
property: passwordSecrets Manager Strengths
- Zero ops โ fully managed, no infrastructure
- Native AWS integration โ IAM policies, CloudTrail, RDS rotation
- Simple โ store and retrieve, rotation via Lambda
- Cross-account sharing โ resource-based policies
- Versioning โ automatic version history
Secrets Manager Limitations
- AWS only โ no multi-cloud
- No dynamic secrets โ rotation is scheduled, not on-demand
- No PKI โ use ACM for certificates
- Cost at scale โ $0.40/secret/month ร 1000 secrets = $400/month
- API cost โ $0.05 per 10,000 API calls
Cost Comparison (1000 secrets, 100 apps)
| Component | Vault (self-hosted) | Vault (HCP) | Secrets Manager |
|---|---|---|---|
| Platform | $0 (OSS) | ~$800/mo | $400/mo |
| Infrastructure | ~$200/mo (HA cluster) | Included | Included |
| API calls | $0 | Included | ~$50/mo |
| Total | ~$200/mo | ~$800/mo | ~$450/mo |
When to Choose
Choose Vault when:
- Multi-cloud or hybrid infrastructure
- Need dynamic secrets (database, cloud, SSH)
- PKI / certificate management required
- Encryption as a service needed
- Complex access policies across teams
- On-premises secrets management
Choose Secrets Manager when:
- AWS-only infrastructure
- Simple store-and-retrieve use case
- Want zero operational burden
- RDS/Aurora automatic rotation needed
- Small-medium secret count (under 500)
- Team lacks Vault expertise
Use Both:
Many enterprises use Vault as the central secrets platform but sync specific secrets to Secrets Manager for AWS-native service integration (Lambda, ECS, RDS).