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
Stringtype as good enough for a secret. Fix: always useSecureStringfor anything sensitive — plainStringparameters 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.