3.1.3. AWS Secrets Manager for Application Secrets
First Principle: AWS Secrets Manager securely stores, rotates, and retrieves sensitive application secrets, preventing hardcoding of credentials and enhancing the security posture of your applications.
Sensitive information such as API keys, database credentials, and OAuth tokens should never be hardcoded directly into your application code or stored in plain text configuration files. AWS Secrets Manager helps you protect access to your applications, services, and IT resources.
- Secure Storage: Encrypts secrets at rest using AWS KMS.
- Automated Rotation: Automatically rotates secrets for supported databases (Amazon RDS, Amazon Redshift), Amazon DocumentDB, and other services via AWS Lambda functions. This significantly reduces the attack surface from long-lived credentials.
- Centralized Management: Manage all your secrets from a single place.
- Integration: Easily retrieve secrets programmatically using AWS SDKs or AWS CLI from your application code, Lambda functions, or CodeBuild projects. Code calls
GetSecretValue(needssecretsmanager:GetSecretValue) to get the decrypted value.DescribeSecretandListSecretsreturn only metadata. - Random secrets:
GetRandomPasswordgenerates a password that meets your length and character rules. Parameter Store has no equivalent. - Least Privilege: Control access to secrets using IAM policies.
- Parameter Store for configuration: stores
String,StringListandSecureString(KMS-encrypted) values in a path hierarchy (/app/dev/db_url), with IAM access control and no built-in rotation. The Standard tier is free for up to 10,000 parameters of 4 KB each. The Advanced tier raises that to 100,000 parameters of 8 KB and adds parameter policies, for a charge. A typical split is non-sensitive config (a log level) or a static API key in Parameter Store, and credentials that must rotate in Secrets Manager. - Lambda environment variables: key-value settings on the function's configuration (e.g., a database endpoint or
LOG_LEVEL) that keep configuration out of the code. The code reads them like any OS variable (os.environ/process.env). Lambda encrypts them at rest with KMS, but with the default AWS managed key anyone who can view the function's configuration sees the plaintext (a customer managed key limits that to users withkms:Decrypton it). For a sensitive value, use the console's encryption helpers (client-side KMS encryption, decrypted in your code), or better, store it in Secrets Manager and fetch it with the execution role.
AWS KMS Encryption for Developers
AWS Key Management Service (KMS) underpins encryption across nearly every AWS service. Developers need to understand three key distinctions:
AWS managed keys vs. customer managed keys (CMKs): AWS managed keys are created and rotated automatically by AWS services (e.g., the aws/s3 key). Customer managed keys give you control over key policies, rotation schedules, and cross-account access — use them when you need fine-grained access control or compliance requirements. Only a customer managed key lets you edit its key policy, disable it temporarily, turn automatic rotation on or off, and share it with another account. For cross-account use, the key policy in the owning account grants the other account, whose own IAM policy must also allow use of the key. Automatic rotation is available only for symmetric encryption keys whose key material KMS generated, so not asymmetric, HMAC or imported-material keys. AWS managed keys rotate every year on their own.
Server-side encryption (SSE) vs. client-side encryption: With SSE, AWS encrypts your data after receiving it (e.g., SSE-S3, SSE-KMS, SSE-C for S3). With client-side encryption, you encrypt data before sending it to AWS — only you hold the decryption keys. The exam tests when each is appropriate: SSE-KMS when you need audit trails via CloudTrail, SSE-C when the customer must control keys, and client-side when data must never exist unencrypted on AWS.
With SSE-C, S3 does not store your key: every PUT and GET must carry the key, its MD5 digest and the algorithm in x-amz-server-side-encryption-customer-* headers, over HTTPS. Since April 2026, new general purpose buckets block SSE-C by default, so it must first be allowed with PutBucketEncryption. Encryption at rest by default: DynamoDB encrypts every table with an AWS owned key unless you choose an AWS managed or customer managed key. S3 applies SSE-S3 to all new objects through the bucket's default encryption, which you can switch to SSE-KMS. EBS encrypts new volumes, including root volumes, once you turn on EBS encryption by default for the Region.
Envelope encryption is how KMS handles data larger than 4 KB. The KMS Encrypt API only accepts 4 KB of plaintext. For larger data, you call GenerateDataKey — KMS returns a plaintext data key AND an encrypted copy. You encrypt your data locally with the plaintext key, discard it, and store the encrypted data key alongside the ciphertext. To decrypt, KMS decrypts the data key, and you use it locally. The AWS Encryption SDK handles this pattern automatically.
Direct Encrypt/Decrypt: for data up to 4 KB, your code passes the plaintext itself to Encrypt. Decrypt of symmetric ciphertext does not need the key ID, which is embedded in the ciphertext metadata, but the caller's role must have kms:Decrypt on the key that encrypted it. kms:Encrypt, kms:GenerateDataKey or kms:DescribeKey do not grant decryption.
Key rotation: Automatic rotation (yearly for customer managed keys) generates new key material but keeps the same key ID — your applications don't need code changes. Old data encrypted with previous key material can still be decrypted because AWS retains all previous versions. Manual rotation creates a new key ID entirely, requiring alias updates.
⚠️ Exam Trap: 'Encrypt a 5 GB file with KMS' → you CANNOT send it to the KMS Encrypt API (4 KB limit). The answer is envelope encryption using GenerateDataKey.
Classifying and Sanitizing Sensitive Data
- Classify first: label data as public, internal, confidential, PII (anything that identifies a person, such as a national ID number or a full name combined with a home address; an anonymized UUID or an aggregate count is not) or PHI (health records). The classification decides the controls: sensitive classes must be encrypted at rest and in transit, with access restricted to least privilege and audited.
- Keep it out of logs: build a redacted copy of the event (drop or mask email, phone and similar fields) before logging it, rather than logging raw payloads or switching logging off. CloudWatch Logs data protection policies can also mask sensitive patterns as a backstop.
- Encode output: untrusted input that later appears in a web page must be HTML-encoded when it is rendered, to stop cross-site scripting (XSS). Encrypting it at rest or choosing a NoSQL store does nothing against XSS.
Scenario: You're developing an application that connects to an Amazon RDS database. The database credentials are highly sensitive and should not be stored directly in your application's configuration files. You also need these credentials to be rotated frequently for security best practices.
⚠️ Exam Trap: Secrets Manager automatically rotates secrets. Systems Manager Parameter Store does NOT (you must implement rotation yourself). If a question requires automatic rotation, Secrets Manager is the answer — even though Parameter Store is cheaper.