Skip to content

Secret Stores

Once a secret can't live in code, it has to live somewhere — a system built specifically to hold sensitive values, control who can read them, and hand them out on request. This page covers the three stores a DevOps junior actually runs into: HashiCorp Vault, AWS Secrets Manager, and AWS Systems Manager (SSM) Parameter Store.

TL;DR — in 30 seconds:

  • A secret store's core promise: the real value lives in one place, protected by access control, and everything that needs it authenticates and asks at runtime — instead of every consumer carrying its own copy.
  • Vault is the general-purpose, any-cloud option with dynamic secrets (short-lived credentials generated on demand). Secrets Manager and Parameter Store are AWS-native and simpler to adopt if you're already all-in on AWS.
  • Secrets Manager costs more but rotates automatically for supported services; Parameter Store is cheaper (a free tier for standard parameters) but rotation is manual/self-built.

1. The core idea: ask, don't carry

flowchart LR
    A["App / pipeline / pod"] -->|"1. authenticate"| B["Secret store"]
    B -->|"2. authorized? return the value"| A
    A -->|"3. use it, don't persist a copy"| C["Downstream call"]

Every consumer — a running service, a CI/CD job, a pod — authenticates to the store using its own identity (an IAM role, a Kubernetes service account, an app token), and the store decides, based on policy, whether that identity is allowed to read the specific secret requested. No secret is copy-pasted into config files scattered across every consumer; there's one source of truth, one place to rotate, and one place to audit who accessed what.

2. HashiCorp Vault

Vault is a standalone secret-management server usable on any cloud (or on-prem). Two ideas make it distinct from a plain key-value store:

  • KV secrets engine — the simplest mode: store and retrieve static values (an API key, a password), versioned so you can see or roll back to a prior value.
  • Dynamic secrets — Vault's signature feature: instead of storing a static database password, Vault generates a brand-new, short-lived credential the moment something asks for one (with a database engine, a cloud engine, etc.), and automatically revokes it after its lease expires. Nothing long- lived exists to leak in the first place.

Access is governed by policies attached to an authentication method (tokens, Kubernetes service account auth, cloud IAM auth) — the same least-privilege idea as everywhere else in this module: a policy grants read access to exactly the paths a given identity needs, nothing more.

3. AWS Secrets Manager

A managed, AWS-native secret store built around rotation: for supported services (RDS, DocumentDB, and others via a Lambda rotation function), Secrets Manager can rotate the credential on a schedule without any manual intervention, updating both the stored secret and the underlying service's credential together. Access is controlled the same way as everything else in AWS: IAM policies naming which principal (role, user) can GetSecretValue on which secret ARN.

Costs more per secret per month than Parameter Store — the built-in rotation and versioning are what you're paying for.

4. AWS Systems Manager (SSM) Parameter Store

A simpler, cheaper AWS-native option for both plain configuration values and secrets. A parameter can be type String (plain) or SecureString (encrypted with a KMS key) — using SecureString for anything sensitive is what makes it a legitimate secret store rather than a configuration store. Standard parameters are free; advanced parameters and higher throughput cost extra. No built-in automatic rotation — teams that need scheduled rotation on Parameter Store build it themselves (e.g. a Lambda function on a schedule) or pick Secrets Manager instead.

5. Choosing between them

Vault Secrets Manager Parameter Store
Cloud-agnostic Yes No (AWS-only) No (AWS-only)
Dynamic (short-lived) secrets Yes Limited (rotation, not per-request generation) No
Built-in automatic rotation Via engines Yes (supported services) No (self-built)
Cost Self-hosted or Vault Cloud Higher per-secret Low / free tier
Typical fit Multi-cloud, dynamic-credential-heavy setups AWS-native app secrets needing managed rotation AWS-native config + secrets on a budget

Common gotchas

  • Treating Parameter Store's String type as good enough for a secret. Fix: always use SecureString for anything sensitive — plain String parameters are not encrypted and are readable by anyone with basic read access to the parameter path.
  • Assuming Secrets Manager rotates everything automatically. Fix: automatic rotation only works out of the box for specific supported services; anything else needs a custom rotation Lambda, or rotation is effectively manual.
  • Reaching for Vault's dynamic secrets before understanding static ones. Fix: start with the KV engine and a clear access policy — dynamic secrets solve a real problem (long-lived credential sprawl) but add operational complexity that's wasted if the simpler static case isn't understood first.
Check yourself — a team is all-in on AWS, needs automatic rotation for an RDS database password, and doesn't want to run extra infrastructure. Which store fits best, and why?

AWS Secrets Manager — it natively supports scheduled automatic rotation for RDS without running any additional infrastructure, which is exactly the requirement; Parameter Store would need a self-built rotation Lambda, and Vault would mean standing up and operating a separate system for a single-cloud, already-AWS-native need.

Check yourself — what does Vault's 'dynamic secret' actually change compared to a static one stored in a KV engine?

Instead of one long-lived value that's stored once and reused, Vault generates a new credential on each request and automatically revokes it after a lease expires — so there's no long-lived value sitting around to leak, and a compromised credential is only valid for a limited window.

You can defend this when you can justify, for a given scenario, which of the three stores fits best — not just "use a secret manager" — by naming the specific tradeoff (cloud-agnosticism, dynamic secrets, built-in rotation, cost) that decided it.