All Articles

HashiCorp Vault vs AWS Secrets Manager vs External Secrets Operator — Which to Use in 2026?

Comparing the top three secrets management solutions for Kubernetes and cloud environments in 2026. Pricing, features, complexity, and when to pick each.

DevOpsBoysApr 2, 20266 min read
Share:Tweet

Secrets management is one of those things every team handles differently until a credential leak forces a rethink. Here's an honest comparison of the three most common approaches in 2026.


TL;DR

Use CasePick This
Already on AWS, want simplest setupAWS Secrets Manager
Multi-cloud or on-prem, need dynamic secretsHashiCorp Vault
Kubernetes-native, want secrets synced to K8sExternal Secrets Operator
All three can work togetherESO + AWS SM or ESO + Vault

The Problem They All Solve

You have secrets: database passwords, API keys, TLS certificates, tokens. You need to:

  • Store them securely (not in Git, not in plaintext env vars)
  • Get them into your applications at runtime
  • Rotate them without redeploying apps
  • Audit who accessed what and when

Each tool solves this differently.


AWS Secrets Manager

AWS Secrets Manager is a managed service that stores, retrieves, and rotates secrets. Simple to start, deeply integrated with AWS.

How it works

Store a secret:

bash
aws secretsmanager create-secret \
  --name prod/myapp/db-password \
  --secret-string '{"username":"admin","password":"supersecret"}'

Retrieve in your application:

python
import boto3
import json
 
client = boto3.client('secretsmanager', region_name='us-east-1')
response = client.get_secret_value(SecretId='prod/myapp/db-password')
secret = json.loads(response['SecretString'])
db_password = secret['password']

Automatic rotation

AWS SM can rotate RDS, Redshift, and DocumentDB passwords automatically — it runs a Lambda function that generates a new password, updates it in the DB, and stores the new version. Zero application changes required.

bash
aws secretsmanager rotate-secret \
  --secret-id prod/myapp/db-password \
  --rotation-rules AutomaticallyAfterDays=30

What's great

  • Zero infrastructure to manage — fully managed, no servers
  • Native AWS integration — works seamlessly with IAM, ECS, Lambda, EKS via IRSA
  • Automatic rotation — for AWS databases, rotation is a checkbox
  • Versioning — keeps previous versions, gradual rotation without downtime
  • Audit trail — CloudTrail logs every read and write

What's not great

  • AWS-only — if you have workloads on GCP or Azure, you need separate solutions
  • Cost — $0.40/secret/month + $0.05 per 10,000 API calls. With 100 secrets and frequent reads, costs add up fast
  • No dynamic secrets — can't generate short-lived database credentials on demand (Vault can)
  • No templating or secrets composition — can't combine multiple secrets dynamically

Pricing (2026)

$0.40 per secret/month + $0.05 per 10,000 API calls. 100 secrets = $40/month minimum.


HashiCorp Vault

Vault is the most powerful secrets management solution — supports any cloud, any platform, dynamic secrets, PKI, and fine-grained policies. It's also the most complex to operate.

How it works

Start Vault (production uses HA with etcd/Raft backend):

bash
vault server -config=vault.hcl
vault operator init
vault operator unseal

Store and retrieve secrets:

bash
# Enable KV secrets engine
vault secrets enable -path=secret kv-v2
 
# Write secret
vault kv put secret/myapp/database \
  username=admin \
  password=supersecret
 
# Read secret
vault kv get secret/myapp/database

Dynamic secrets — Vault's killer feature

Instead of storing static passwords, Vault generates short-lived credentials on demand. When a Kubernetes pod needs DB access, Vault creates a new PostgreSQL user valid for 1 hour:

bash
# Configure DB secrets engine
vault secrets enable database
 
vault write database/config/my-postgres \
    plugin_name=postgresql-database-plugin \
    allowed_roles="my-role" \
    connection_url="postgresql://{{username}}:{{password}}@postgres:5432/mydb" \
    username="vault" \
    password="vault-password"
 
vault write database/roles/my-role \
    db_name=my-postgres \
    creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';" \
    default_ttl="1h" \
    max_ttl="24h"

Now your app gets a unique username/password that expires in 1 hour. Even if leaked, it's useless after expiry. No static credentials anywhere.

Vault in Kubernetes

The Vault Agent Sidecar injector automatically injects secrets into pods:

yaml
# Annotate your pod
annotations:
  vault.hashicorp.com/agent-inject: "true"
  vault.hashicorp.com/role: "my-app-role"
  vault.hashicorp.com/agent-inject-secret-db-config: "secret/myapp/database"
  vault.hashicorp.com/agent-inject-template-db-config: |
    {{- with secret "secret/myapp/database" -}}
    DB_PASSWORD={{ .Data.data.password }}
    {{- end }}

Vault Agent writes the secret to /vault/secrets/db-config as a file. The Vault Secrets Operator (VSO) — the newer approach — syncs Vault secrets to Kubernetes Secrets objects automatically.

What's great

  • Multi-cloud/multi-platform — works the same on AWS, GCP, Azure, on-prem
  • Dynamic secrets — short-lived credentials for databases, AWS, SSH
  • PKI — issue and rotate TLS certificates automatically (massive for internal services)
  • Fine-grained policies — path-based access control, what each app can read
  • Lease system — secrets have TTLs and are auto-revoked

What's not great

  • Operational complexity — you run and manage Vault yourself (HA setup, unsealing, backup)
  • HCP Vault — HashiCorp's managed cloud offering reduces ops burden but costs more
  • Learning curve — policies, auth methods, secrets engines are powerful but non-trivial
  • License change — Vault is now BSL licensed; OpenBao is the open-source fork if that matters

Pricing (2026)

Self-hosted Vault CE: free (BSL license). HCP Vault: starts at ~$0.03/hr for development, $0.83/hr for production. OpenBao: fully open-source (CNCF).


External Secrets Operator (ESO)

ESO is a Kubernetes operator that syncs secrets from external providers (AWS SM, GCP SM, Vault, Azure Key Vault, etc.) into Kubernetes Secrets. It's not a secrets store — it's a bridge.

How it works

Install ESO:

bash
helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets -n external-secrets

Create a SecretStore that points to AWS Secrets Manager:

yaml
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: aws-secretsmanager
  namespace: default
spec:
  provider:
    aws:
      service: SecretsManager
      region: us-east-1
      auth:
        jwt:
          serviceAccountRef:
            name: external-secrets-sa  # Uses IRSA

Create an ExternalSecret that pulls from AWS SM into a Kubernetes Secret:

yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-credentials
  namespace: default
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secretsmanager
    kind: SecretStore
  target:
    name: db-credentials  # Creates this K8s Secret
    creationPolicy: Owner
  data:
    - secretKey: password
      remoteRef:
        key: prod/myapp/db-password
        property: password

ESO creates a Kubernetes Secret db-credentials populated with the value from AWS SM. Pods use it like any normal Kubernetes Secret. ESO refreshes it every hour — if you rotate the secret in AWS SM, it automatically updates in Kubernetes.

What's great

  • Kubernetes-native — secrets appear as standard K8s Secrets, no app changes needed
  • Multi-provider — single operator, multiple backends (AWS SM + Vault + GCP SM in same cluster)
  • Auto-rotationrefreshInterval keeps K8s Secrets in sync with source
  • CNCF sandbox project — well-maintained, widely adopted
  • GitOps compatible — ExternalSecret CRDs are safe to commit to Git (they reference secrets, don't contain them)

What's not great

  • Secrets still exist in etcd — they're synced INTO Kubernetes Secrets, which means they're in etcd (encrypted at rest if configured, but still there)
  • Not a replacement for a secrets store — you still need AWS SM or Vault behind it
  • Refresh delay — rotation in the source takes up to refreshInterval to reach pods (add kubectl rollout restart to rotation workflow)

Pricing (2026)

Open-source, free. You pay for the underlying secret store (AWS SM, Vault, etc.).


Side-by-Side Comparison

FeatureAWS Secrets ManagerHashiCorp VaultExternal Secrets Operator
Dynamic secretsNoYesNo (bridges to Vault)
Multi-cloudNoYesYes (multi-provider)
Kubernetes integrationVia ESO or CSIVault Agent / VSONative
PKI/certificate managementNoYesNo
Managed serviceYesVia HCPN/A (operator)
Operational overheadLowHighLow (operator only)
Cost$0.40/secret/monthFree (self-hosted)Free
Audit loggingCloudTrailVault audit logsVia underlying store
Auto-rotationAWS databasesAll databasesVia underlying store

AWS-only startup: AWS Secrets Manager + External Secrets Operator. Simple, managed, cost-effective.

Multi-cloud enterprise: HashiCorp Vault (self-hosted or HCP) + External Secrets Operator for Kubernetes sync.

Pure Kubernetes team: External Secrets Operator + AWS Secrets Manager (or Vault) depending on existing cloud.

Security-heavy regulated industry: HashiCorp Vault for dynamic secrets + ESO for K8s sync + full audit logging to SIEM.


Resources

Newsletter

Stay ahead of the curve

Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.

Related Articles

Comments