Cloud-Native Secret Stores
Cloud-Native Secret Stores
When you run workloads on AWS, you do not need a self-managed Vault cluster for every secret. AWS provides two purpose-built managed services — AWS Secrets Manager and AWS Systems Manager Parameter Store (SSM) — plus a key management backbone called KMS that underpins encryption for both. Understanding when to use each service, how KMS envelope encryption actually works under the hood, and where production teams get burned is the core of this lesson.
AWS Secrets Manager vs. SSM Parameter Store
Both services store sensitive configuration, but they target different use cases and have meaningfully different cost models and operational characteristics.
AWS Secrets Manager is the right choice when you need:
- Automatic rotation — Secrets Manager has native integration with RDS, Redshift, DocumentDB, and a Lambda-based extensible rotation framework. It handles the credential swap atomically: creates the new credential, updates the database, updates the secret, and retires the old credential — all without application downtime.
- Cross-account secret sharing — resource-based policies on a secret let you share it with other AWS accounts in your organization, which is the standard pattern for centralized secrets management in multi-account architectures.
- Per-secret audit trail — every read, write, and rotation event is a CloudTrail API call tagged to the specific secret ARN. This granularity satisfies SOC 2 and PCI DSS audit requirements.
SSM Parameter Store is the right choice when you need:
- Hierarchical configuration storage — parameters live under paths like
/prod/myapp/db/password, and IAM policies can grant access to entire path prefixes. This is powerful for applications that read all their configuration from SSM at startup. - Cost-sensitive workloads — Standard parameters are free. SecureString parameters (KMS-encrypted) are also free at the standard tier. Secrets Manager charges $0.40 per secret per month plus $0.05 per 10,000 API calls. At scale with thousands of microservices each reading multiple secrets, the cost difference is significant.
- Simple key/value config that does not require rotation — feature flags, environment names, non-rotating API keys, and structured config that does not need the full Secrets Manager lifecycle.
KMS Envelope Encryption: How Your Data Is Actually Protected
Both Secrets Manager and SSM SecureString use AWS KMS to encrypt data at rest. Understanding the envelope encryption pattern is essential — it is the same pattern used by every major cloud provider and is what makes cloud-native secret stores both secure and performant at scale.
The naive approach to encryption would be: send your secret to KMS, KMS encrypts it with the CMK (Customer Master Key), you store the ciphertext. The problem: KMS has a 4 KB payload limit and is a network call — calling KMS directly for every read would be both expensive and slow at high request rates.
Envelope encryption solves this elegantly:
- AWS generates a short-lived Data Encryption Key (DEK) using the KMS CMK. The DEK is returned in two forms: plaintext (used immediately for encryption) and ciphertext (the DEK encrypted by the CMK, stored alongside the data).
- Your data (the secret value) is encrypted locally using the plaintext DEK with AES-256-GCM. This is fast and has no payload limit.
- The plaintext DEK is discarded immediately after use. Only the encrypted DEK and the encrypted data are persisted.
- At decryption time, the encrypted DEK is sent to KMS. KMS uses the CMK to decrypt it and returns the plaintext DEK. Your data is then decrypted locally.
The result: the CMK never directly touches your plaintext data and never leaves KMS hardware. All KMS operations are logged to CloudTrail. Revoking access to the CMK immediately makes all protected data permanently inaccessible — even to AWS employees.
Working with AWS Secrets Manager
The following examples show the full lifecycle: creating a secret, retrieving it in code, and configuring automatic rotation for an RDS database credential.
GetSecretValue on every database query. Retrieve the secret once at application startup, cache it in memory, and implement a retry-on-authentication-failure pattern: if the database rejects credentials, call GetSecretValue again (rotation may have occurred) and reconnect. This pattern works correctly with Secrets Manager rotation without any application downtime.
Working with SSM Parameter Store
SSM Parameter Store is excellent for hierarchical application configuration. The path-based structure aligns well with IAM least-privilege: a microservice's task role can be granted ssm:GetParametersByPath on /prod/myapp/* and nothing else.
IAM Policy Design for Least-Privilege Access
The most critical security control for both services is the IAM policy attached to the compute role (ECS task role, EC2 instance profile, Lambda execution role). Access must be scoped to specific resource ARNs — never Resource: "*" on secret-read actions.
The kms:ViaService condition in the KMS statement is important: it restricts the kms:Decrypt permission so the role can only decrypt KMS data when the request originates through Secrets Manager. The role cannot use the same KMS key to decrypt arbitrary ciphertext directly — tightly constraining the blast radius of a compromised role.
secretsmanager:GetSecretValue with Resource: "*". Any compromised container in the account can then exfiltrate every secret. Always scope to the exact ARN prefix for the service. Use aws secretsmanager list-secrets + CloudTrail anomaly detection (GuardDuty findings: UnauthorizedAccess:IAMUser/AnomalousBehavior) to detect unauthorized enumeration.
Secrets Manager in Kubernetes and ECS
On Amazon EKS, the Secrets Store CSI Driver with the AWS provider mounts Secrets Manager or SSM Parameter Store values directly as Kubernetes volume files (or syncs them into native Kubernetes Secrets). The pod's service account IRSA role controls access. On Amazon ECS, the ECS Secrets integration injects Secrets Manager values as environment variables at container startup without any application code changes — you reference the secret ARN in the task definition.
Both patterns eliminate hardcoded credentials at the infrastructure layer. However, environment variable injection (the ECS default) has a nuance: the secret is read once at container launch and does not update if the secret rotates. For rotation-sensitive workloads on ECS, use the CSI Driver pattern (on EKS) or build refresh logic into the application.
SecretCache helper). At high request rates — a service making tens of thousands of database connections per second — caching eliminates Secrets Manager API throttling (the default quota is 10,000 API calls per second per region, shared across all principals in the account). Build caching into every high-throughput consumer from day one.