Skip to content
Security

AWS Secrets Manager vs HashiCorp Vault (2026): The Full Comparison

AWS Secrets Manager is a secret store; Vault is a secrets service. Full head-to-head on pricing at three scales, rotation vs dynamic secrets, auth methods, Kubernetes integration, and migration paths — with the decision table I use before writing any config.

A
Abhishek Patel18 min read

Infrastructure engineer with 10+ years building production systems on AWS, GCP,…

AWS Secrets Manager vs HashiCorp Vault (2026): The Full Comparison
AWS Secrets Manager vs HashiCorp Vault (2026): The Full Comparison

$400 vs $27,000: Why the Right Answer Depends on What You Actually Need

A 500-secret startup on AWS Secrets Manager pays about $200-$400/month all-in. The same 500 secrets on HCP Vault Plus (the managed HashiCorp Vault SaaS) can land in the $2,000-$4,000 range once you factor in the minimum hours billed per cluster. A Fortune-500 rollout of Vault Enterprise, fully self-managed with HA, disaster recovery replication, HSM integration, and 30-plus auth methods, routinely bills $250K-$1M a year. Three orders of magnitude separate "the right answer" for different teams, and picking wrong means either a blown budget or a security architecture that cannot support what you are trying to build.

I have migrated two companies off AWS Secrets Manager onto Vault, and one off Vault onto AWS Secrets Manager. All three migrations looked inevitable in retrospect, and all three would have been unnecessary if the team had picked correctly the first time. The pattern underneath every one of those moves: AWS Secrets Manager is a secret store. Vault is a secret service. Those are not the same product, and the difference determines whether rotation, dynamic credentials, transit encryption, PKI issuance, and multi-cloud governance are things you get natively or things you have to build on top. This guide is the full head-to-head — feature parity, pricing at every scale, rotation mechanics, auth methods, and the concrete decision criteria I now use before the first config is written.

Last updated: April 2026 — verified AWS Secrets Manager pricing (us-east-1), HCP Vault Plus per-cluster-hour pricing, Vault Enterprise 1.19 feature set, Vault 1.19 open-source capabilities, and the BSL 1.1 license change that went into effect in August 2023.

TL;DR — Which One to Pick in Under 90 Seconds

Your situationPick
You are fully on AWS, under 1,000 secrets, and mostly just need a managed store with rotationAWS Secrets Manager
You are multi-cloud, or on GCP / Azure, or self-hostedVault (OSS or HCP)
You need dynamic database credentials generated per-requestVault
You want a PKI that issues short-lived X.509 certs internallyVault
You need transit encryption (encryption-as-a-service without storing ciphertext)Vault
You need SSH certificate authority or OTP-style SSH accessVault
Your team is two engineers, no SRE, and "managed" must mean "somebody else's pager"AWS Secrets Manager
You need native rotation for RDS, Redshift, DocumentDB, MongoDB Atlas, or OpenSearchAWS Secrets Manager (native Lambda rotators ship with the service)
You need audit logs feeding into Splunk, Datadog, or an in-house SIEM with granular policy IDsVault
You already run Kubernetes everywhere and want CSI-driven secret injection with zero env-varsVault (Vault Agent Injector + Kubernetes Auth)
Total cost of ownership is the deciding factor and you have <200 secretsAWS Secrets Manager

The rest of this article is the evidence. If the table above already answered your question, you can stop here. The next ~2,000 words are for the case where it did not.

Architecture: Store vs Service

The architectural difference drives every downstream trade-off.

AWS Secrets Manager is a regional, AWS-managed secret store. You write a secret (JSON blob up to 64 KB), AWS encrypts it with a KMS key you own, and you read it back with an IAM-scoped API call. Optional rotation runs as an AWS-managed Lambda function invoked on a schedule. There is no server to operate, no cluster to scale, no auth method to configure beyond IAM. Integration with RDS, Redshift, DocumentDB, and MongoDB Atlas is one checkbox during secret creation. The price for that simplicity: every feature outside "store + rotate" is absent or requires Lambda you write yourself.

HashiCorp Vault is a secrets service. You deploy a cluster (or pay HCP to run one for you), then activate secrets engines — pluggable backends that do very different things. The KV engine stores secrets like AWS does. The Database engine generates short-lived credentials on demand. The PKI engine issues X.509 certs. The Transit engine encrypts and decrypts data without storing the ciphertext. The SSH engine signs SSH public keys or issues one-time passwords. Every one of those is a separate capability layered on the same cluster, with a single audit log and a single policy language controlling access. This is the capability gap that drives most migrations toward Vault.

Deployment Topology

AWS Secrets Manager:
  Your app  →  AWS SDK  →  Regional API endpoint  →  KMS-encrypted store

HashiCorp Vault (self-managed):
  Your app  →  Vault Agent  →  Vault cluster (3-5 nodes, HA storage)  →  Raft / Consul / etcd
                                  │
                                  ├─ KV engine      (store)
                                  ├─ DB engine      (generate)
                                  ├─ PKI engine     (issue)
                                  ├─ Transit engine (encrypt)
                                  └─ SSH engine     (sign)

Pricing at Three Real Scales

Pricing is where most teams pick wrong. AWS Secrets Manager looks cheap per-secret but scales linearly. Vault (OSS) looks free but the operational cost is real. HCP Vault looks expensive at the entry tier but flattens out at scale.

Startup Tier — 50 Secrets, 10M API calls/month

ComponentAWS Secrets ManagerHCP Vault PlusSelf-managed Vault OSS
Platform / license$0$0.03/hr × 730 = ~$22/cluster/mo (Development)$0 (BSL license, internal use is free)
Per-secret50 × $0.40 = $20Unlimited on cluster tierUnlimited
API calls10M × $0.05 / 10K = $50UnlimitedUnlimited
Infrastructure$0 (fully managed)$0 (fully managed)~$80-150 (3 × t3.small + EBS + LB)
Engineering time~1 hr/mo~2 hr/mo~10-20 hr/mo
Estimated monthly~$70~$22 (licence only) + eng time~$100-150 + real SRE time

At 50 secrets, AWS Secrets Manager is cheapest once you price your own time. Vault OSS is nominally free but costs a real SRE 10-20 hours a month to keep the cluster healthy — worth it at scale, overkill at 50 secrets.

Mid-Size — 500 Secrets, 100M API calls/month, multi-region

ComponentAWS Secrets ManagerHCP Vault PlusSelf-managed Vault OSS
Platform / license$0$0.50/hr × 730 × 2 clusters = ~$730$0
Per-secret500 × $0.40 × 2 regions = $400UnlimitedUnlimited
API calls100M × $0.05 / 10K = $500UnlimitedUnlimited
Infrastructure$0$0~$400-600 (5 × t3.medium × 2 regions + Raft storage)
Engineering time~5 hr/mo~5 hr/mo~40 hr/mo (HA, backups, upgrades, DR)
Estimated monthly~$900-1,100~$730 + eng~$500-700 + substantial SRE

At this tier, AWS and HCP Vault are roughly at parity once you account for engineering time. Vault OSS wins on dollars but costs a full-time SRE partial allocation. The real decision criterion at mid-scale is capability: do you need dynamic creds, PKI, and transit? If yes, Vault's cost suddenly looks cheap because AWS Secrets Manager cannot do those things regardless of budget.

Enterprise — 5,000+ Secrets, 1B API calls/month, compliance-heavy

ComponentAWS Secrets ManagerVault Enterprise (self-managed)
Platform / license$0$0.03-$0.10/hr/node, negotiated (~$150K-$600K/yr)
Per-secret5,000 × $0.40 × 3 regions = $6,000Unlimited
API calls1B × $0.05 / 10K = $5,000Unlimited
Infrastructure$0~$8K-15K (HSM, performance replicas, DR cluster)
Compliance featuresCloudTrail audit onlyHSM, Seal Wrap, PR/DR replication, namespaces, control groups
Annual~$130K-150K~$250K-1M (licence dominant)

At enterprise scale, AWS Secrets Manager stays cheap on dollars but buys a fraction of the capability Vault Enterprise ships. The tradeoff here is almost never about price — it's about whether you need HSM-backed seal keys, performance replication, control groups (two-person-rule approvals), and namespaces for hard-isolated tenants. If you do, Vault Enterprise is non-negotiable. If you don't, AWS Secrets Manager is fine and saves half a million dollars a year.

Rotation: The Feature That Sells Both Products

Both products advertise rotation. They do fundamentally different things.

AWS Secrets Manager: Lambda-Based Rotation

AWS ships pre-built rotation Lambdas for RDS (MySQL, PostgreSQL, MariaDB, Oracle, SQL Server), Amazon DocumentDB, Amazon Redshift, and MongoDB Atlas. Attach a rotation Lambda to a secret, set a schedule (1-365 days), and Secrets Manager invokes the Lambda to generate a new password, test it, and update the target database. The rotation uses a four-step state machine: createSecret, setSecret, testSecret, finishSecret. For anything outside the supported list, you write your own rotation Lambda that implements the same four-step interface.

# Minimal custom rotation Lambda for a non-AWS database
import boto3, json
client = boto3.client('secretsmanager')

def lambda_handler(event, context):
    secret_id = event['SecretId']
    token = event['ClientRequestToken']
    step = event['Step']

    metadata = client.describe_secret(SecretId=secret_id)
    if step == 'createSecret':
        # Generate new password, stage as AWSPENDING version
        new_secret = {...}
        client.put_secret_value(
            SecretId=secret_id,
            ClientRequestToken=token,
            SecretString=json.dumps(new_secret),
            VersionStages=['AWSPENDING'],
        )
    elif step == 'setSecret':
        # Apply pending secret to the external system
        pending = client.get_secret_value(SecretId=secret_id, VersionStage='AWSPENDING')
        # ... update external system with pending['SecretString']
    elif step == 'testSecret':
        # Verify pending credential works
        ...
    elif step == 'finishSecret':
        # Promote AWSPENDING to AWSCURRENT
        client.update_secret_version_stage(
            SecretId=secret_id,
            VersionStage='AWSCURRENT',
            MoveToVersionId=token,
            RemoveFromVersionId=metadata['VersionIdsToStages'][...],
        )

Vault: Dynamic Secrets Instead of Rotation

Vault's big idea is to skip rotation entirely by generating short-lived credentials on demand. The Database secrets engine accepts a connection with a privileged account (once), then issues per-application database users with a TTL you set. A service asks Vault for a DB credential, gets back a username/password pair that Vault created on the database 50ms ago and will revoke in 60 minutes. No rotation schedule, no Lambda, no shared credential sitting anywhere. The blast radius of a leaked credential is the remaining TTL, not "how often does rotation run."

# Configure Vault's database engine once
vault secrets enable database
vault write database/config/prod-postgres \
    plugin_name=postgresql-database-plugin \
    allowed_roles="app-read,app-write" \
    connection_url="postgresql://{{username}}:{{password}}@db.internal:5432/prod" \
    username="vault_admin" \
    password="$(cat /etc/vault-admin-secret)"

# Define a role that creates users on demand
vault write database/roles/app-read \
    db_name=prod-postgres \
    creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \
        GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
    default_ttl="1h" \
    max_ttl="24h"

# App asks Vault for a credential
vault read database/creds/app-read
# Output:
#   lease_id    database/creds/app-read/7f2a...
#   lease_duration  1h
#   username    v-token-app-read-1Qb...
#   password    4Nx-qRz...

The database user v-token-app-read-1Qb... did not exist 50ms ago, expires in an hour, and when it expires Vault automatically executes a revocation statement that drops the user. There is no rotation schedule because there is nothing long-lived to rotate.

Auth Methods: How Applications Prove Who They Are

AWS Secrets Manager has exactly one auth method: IAM. If your code is on AWS, you get an IAM role attached to the instance, container, or Lambda, and the SDK handles credential chaining. Outside AWS, you need to manage IAM user access keys yourself — which recreates the exact problem Secrets Manager is supposed to solve.

Vault supports roughly 20 built-in auth methods: AppRole (role_id + secret_id), AWS (IAM or EC2 identity), Azure (managed identity), GCP (IAM or GCE identity), Kubernetes (service account token), JWT/OIDC (any provider), LDAP, Username/Password, TLS client certs, GitHub, Okta, Radius, Kerberos, Cert, Token, and more via plugins. The practical impact: a single Vault cluster can authenticate Kubernetes pods on GKE using service account tokens, EC2 instances on AWS using IAM, Azure VMs using managed identity, and your engineering team via Okta SSO — all with one audit log and one policy language.

Auth methodAWS Secrets ManagerVault
IAM (AWS)
GCP IAM
Azure Managed Identity
Kubernetes Service AccountVia IRSA only✓ (native)
JWT / OIDC
LDAP / AD
TLS client certificates
GitHub teams
AppRole (machine-to-machine)
Okta / Azure AD SSOVia IAM Identity Center

Integration With Kubernetes

If your workloads run on Kubernetes, the integration model matters.

AWS Secrets Manager on EKS

The AWS-native path is the Secrets Store CSI Driver with the AWS provider. Mount secrets as files under /mnt/secrets-store, backed by Secrets Manager. Authentication uses IRSA (IAM Roles for Service Accounts), so no static credentials sit in pods. Rotation propagates to pods only if your app re-reads the mounted file — Secrets Manager does not push updates.

apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: prod-db
spec:
  provider: aws
  parameters:
    objects: |
      - objectName: "prod/db/password"
        objectType: "secretsmanager"
---
apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      serviceAccountName: api-sa  # IRSA-bound to IAM role
      containers:
      - name: api
        volumeMounts:
        - name: secrets
          mountPath: /mnt/secrets-store
          readOnly: true
      volumes:
      - name: secrets
        csi:
          driver: secrets-store.csi.k8s.io
          readOnly: true
          volumeAttributes:
            secretProviderClass: "prod-db"

Vault on Kubernetes

Two dominant patterns. The Vault Agent Injector uses a mutating webhook to add a sidecar that authenticates via Kubernetes service account, fetches secrets, renders them into the pod filesystem from Go templates, and renews leases. The CSI driver + Vault CSI provider mounts secrets as files without a sidecar. Both support dynamic secrets, both support auto-renewal, and both remove the need for the app to know Vault exists.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  template:
    metadata:
      annotations:
        vault.hashicorp.com/agent-inject: "true"
        vault.hashicorp.com/role: "api-role"
        vault.hashicorp.com/agent-inject-secret-db.env: "database/creds/app-read"
        vault.hashicorp.com/agent-inject-template-db.env: |
          {{- with secret "database/creds/app-read" -}}
          DATABASE_USERNAME={{ .Data.username }}
          DATABASE_PASSWORD={{ .Data.password }}
          {{- end }}

Notice what's happening: the pod gets a dynamic PostgreSQL credential, renewed on a schedule by the Vault Agent, with no application code change. AWS Secrets Manager cannot do this because it doesn't generate credentials — it only stores them.

Audit Logging and Compliance

Both products log access. The usefulness differs.

AWS Secrets Manager emits CloudTrail events: who called which API, when, from which IP, with which IAM principal. Those events flow to S3, CloudWatch Logs, or a SIEM. Parsing them for "which user/role read secret X in the last 30 days" requires a CloudTrail Lake query or an Athena table over S3.

Vault has a dedicated audit device that logs every request and response to a file, syslog, or socket. The log is tagged with the Vault policy that granted access, the auth method used, the requester's identity, the path touched, and the HMAC of any secret data (not the plaintext). This makes it trivially searchable: one grep 'policy:"prod-dba"' against the audit log shows every access granted by that policy.

Compliance note: For SOC2, HIPAA, and PCI audits, both tools can be made compliant. Vault's audit granularity often makes the compliance evidence gathering noticeably easier — policies and identities are first-class log attributes, not IAM principals you later correlate. AWS Secrets Manager's simpler model is easier to get right for smaller scopes; Vault's richer model is easier to demonstrate for complex scopes.

Migration Paths

AWS Secrets Manager → Vault

  1. Deploy Vault (HCP or self-managed). Enable KV v2 engine and the auth method your workloads use (usually IAM for AWS or Kubernetes Auth for EKS).
  2. Mirror secrets. Read every secret from Secrets Manager, write it to Vault under a parallel path. Automate with AWS CLI + vault kv put.
  3. Update application auth. Replace the Secrets Manager SDK call with Vault Agent sidecar injection or a Vault SDK call. Dual-read period of 1-2 weeks where both systems serve the same secret.
  4. Cut over. Flip the application to read from Vault only. Monitor error rates and latency for a week.
  5. Revoke IAM permissions. Remove secretsmanager:GetSecretValue from application IAM roles. Let Secrets Manager secrets age out.
  6. Introduce dynamic secrets. This is where the real value unlocks — migrate one database credential from static stored-in-Vault to dynamic database engine.

Vault → AWS Secrets Manager

  1. Enumerate every Vault secret engine in use. Dynamic engines (database, PKI, transit) cannot migrate — you lose those capabilities.
  2. Accept the capability loss, or carve those capabilities out of scope before migration.
  3. Mirror KV secrets. Read from Vault KV, write to AWS Secrets Manager with aws secretsmanager put-secret-value.
  4. Update applications to use IAM + Secrets Manager SDK. Enable IRSA on EKS if applicable.
  5. Cut over after a dual-read validation period. Retire Vault cluster.

Vault → AWS migrations are rare because you usually lose things you were depending on. The common reason to do it anyway: the team that ran Vault left, the remaining team cannot operate Vault, and the risk of running a security-critical cluster with no expertise exceeds the capability loss.

Production Failure Modes I Have Hit

AWS Secrets Manager: The Throttle You Didn't Plan For

Default account limit is 5,000 GetSecretValue calls per second across the region. Hit a thundering herd at pod startup with 200 pods each fetching 3 secrets and you are instantly at 600 RPS, one retry storm away from the cap. Fix: use the AWS Secrets Manager Caching Client in-process, or sidecar a cache. The CSI driver also caches — use it.

Vault: The Auto-Unseal That Wasn't

A regional KMS outage left a self-managed Vault cluster sealed because the auto-unseal key came from the outaged region. Cluster stayed down until the region recovered because nobody remembered where the Shamir recovery keys were stored. Fix: store recovery keys in a geographically separate provider (we now use HSM in a different region), and practice unseal drills quarterly.

AWS Secrets Manager: The Rotation That Locked the App Out

A custom rotation Lambda successfully updated a RabbitMQ password but the RabbitMQ cluster cached the old hash for 90 seconds. Running pods authenticated successfully with the old password for 89 seconds, failed catastrophically at second 90, and took 15 minutes to recover because the ECS service had a slow restart policy. Fix: rotations must be tested in staging against the real system's caching behavior, not just "does the new credential work."

Vault: The Lease Storm

A misconfigured database role had a 60-second TTL with no max TTL cap, and the application renewed leases too aggressively. Vault accumulated 1.2 million active leases in 4 hours, Raft commits slowed to a crawl, and the cluster nearly stopped responding. Fix: always set max_ttl, audit active lease counts with vault list sys/leases/lookup/<mount>, and configure the lease expiration manager to prune aggressively.

Feature Parity Matrix

FeatureAWS Secrets ManagerVault OSS / HCP / Enterprise
KV secret storage
Versioning✓ (labels)✓ (KV v2)
Rotation (scheduled)✓ (Lambda)✓ (rotation_period on DB roles)
Dynamic database credentials✓ (Postgres, MySQL, MongoDB, Oracle, MSSQL, Elastic, etc.)
Dynamic cloud credentials✗ (use STS separately)✓ (AWS, GCP, Azure secrets engines)
PKI certificate issuance✗ (use ACM Private CA)✓ (native PKI engine, subordinate CA support)
SSH CA / OTP SSH
Transit encryption (encryption-as-a-service)✗ (use KMS directly)
Policy as codeIAM JSONVault HCL policies + Sentinel (Enterprise)
Multi-cloud support✗ (AWS only)
Native Kubernetes integrationVia CSI + IRSA✓ (Agent Injector, CSI, Kubernetes Auth)
HSM-backed seal✗ (KMS-backed)✓ (Enterprise only)
Disaster recovery replicationCross-region replication (async)✓ (DR + Performance replication, Enterprise only)
Audit log granularityCloudTrail (API-level)Native audit device (request/response-level)
Geographic limitationsAWS regions onlyAny cloud or on-prem
Open source✓ (BSL 1.1 — free for internal use)

Frequently Asked Questions

Vault moved from MPL 2.0 to BSL 1.1 (Business Source License) in August 2023. Under BSL, internal use is unrestricted — you can self-host Vault OSS free of charge. The restriction is that you cannot offer Vault as a managed service competing with HashiCorp. OpenBao is an open-source fork maintained by the Linux Foundation that stays on MPL 2.0 if the license change is a blocker for your organization.

Yes, via the AWS SDK and an IAM access key. But this defeats the purpose — you now have a long-lived IAM key that itself needs to be stored and rotated. Teams outside AWS are better served by Vault or a cloud-native alternative (GCP Secret Manager on GCP, Azure Key Vault on Azure).

Vault supports static secret rotation via the Database secrets engine's rotation_period configuration, introduced in Vault 1.10. For most use cases, however, Vault's dynamic secrets are the better answer — they replace rotation with short-lived credentials that expire automatically.

Both are SOC2-compatible when configured correctly. AWS Secrets Manager is SOC2 Type II certified at the infrastructure level — you inherit that in your own SOC2 scope. Vault self-managed requires you to configure audit logging, access controls, and rotation policies to meet the controls yourself. HCP Vault is SOC2 Type II certified and simplifies evidence gathering.

Vault. AWS Secrets Manager works only on AWS. Vault runs anywhere, authenticates workloads on any cloud via native auth methods, and provides a single source of truth across GCP, Azure, AWS, and on-prem.

Yes, and some teams do. A common pattern: Vault as the primary secrets service (dynamic creds, PKI, transit), with critical long-lived secrets replicated to AWS Secrets Manager as a break-glass backup. The reverse also works — AWS Secrets Manager as the store of record, Vault for dynamic database creds and transit encryption only.

Bottom Line

Pick AWS Secrets Manager if you are on AWS, have under 1,000 secrets, and need a managed store with scheduled rotation. Pick Vault if you are multi-cloud, need dynamic credentials, PKI, transit encryption, or SSH CA, or if audit granularity and policy expressiveness matter. The cost difference at small scale favors AWS; the capability difference at any scale favors Vault. The correct first question is not "which is cheaper?" but "will I need dynamic secrets within 18 months?" If yes, adopt Vault now and avoid the migration. If no, AWS Secrets Manager is almost always the pragmatic choice.

For a broader secret-management framework that also covers Kubernetes Secrets and the operational patterns across all three, see Secret Management: Vault vs AWS Secrets Manager vs Kubernetes Secrets. For the adjacent question of how to hand secrets to applications without environment variables, see Kubernetes resource requests and secret mounting patterns.

A

Written by

Abhishek Patel

Infrastructure engineer with 10+ years building production systems on AWS, GCP, and bare metal. Writes practical guides on cloud architecture, containers, networking, and Linux for developers who want to understand how things actually work under the hood.

Related Articles

Enjoyed this article?

Get more like this in your inbox. No spam, unsubscribe anytime.

Comments

Loading comments...

Leave a comment

Stay in the loop

New articles delivered to your inbox. No spam.