Topic 14.11
Secrets, Encryption & Password Storage
In one line
Three different jobs that often get mixed up. Secrets (API keys, database passwords) live in a secrets manager, are injected at runtime, scoped to one service, and rotated. Data is encrypted in transit (TLS) and at rest, with keys held in a KMS and envelope encryption for large data. User passwords are never encrypted or stored: they're hashed with a slow, salted algorithm (Argon2id or bcrypt) so a stolen database doesn't reveal them.
Think of it like this
A hotel. Room keys for staff live in a locked key cabinet with a sign-out log (secrets manager). Guests' valuables go in a safe whose master key is in the bank (KMS). And the front desk never writes down guests' PINs: they only keep a scrambled fingerprint of each PIN that can check a guess but can't be turned back into the PIN (password hashing).
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- Secrets manager
- A service that stores secrets securely, controls who can read them, logs access, and supports rotation.
- KMS
- Key Management Service: holds encryption keys and performs operations with them without exposing the keys.
- Envelope encryption
- Encrypting data with a data key and encrypting that key with a master key in a KMS.
- Password hashing
- Turning a password into a one-way value that can verify a guess but can't be reversed.
- Salt
- A random value stored with each password hash so identical passwords produce different hashes.
- Argon2id / bcrypt
- Deliberately slow password-hashing algorithms designed to make guessing expensive.
Step by step
01Where each kind of sensitive data goes
Tiffin's security review sorts sensitive data into three groups, each with its own tool.
02Hashing passwords properly
The login service stores only an Argon2id hash, which includes the algorithm parameters and a random salt. Verifying a password recomputes the hash with the same parameters.
// Argon2id: salt 16 bytes, hash 32 bytes, parallelism 1, memory 19 MiB, iterations 2
PasswordEncoder encoder = new Argon2PasswordEncoder(16, 32, 1, 19_456, 2);
String stored = encoder.encode("correct horse battery staple");
// $argon2id$v=19$m=19456,t=2,p=1$<salt>$<hash>
boolean ok = encoder.matches(attempt, stored); // constant-time comparison inside
// Use encoder.upgradeEncoding(stored) to re-hash with stronger settings on next login03Envelope encryption for KYC documents
Rider KYC documents in S3 are encrypted with KMS keys. Each object has its own data key, encrypted by a master key that only the KYC service's role may use, and every decryption is logged in CloudTrail.
04Rotating a database password without downtime
The secrets manager rotates the database password monthly: it creates a new password, updates the database user, and stores it as the current version. Apps fetch the secret on startup and refresh it periodically, and connection pools pick it up as connections are recycled.
Break it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
Fast hashes for passwords
An old service stores passwords as unsalted SHA-256 hashes, and its database backup leaks.
Myth vs fact
Myth
Encrypting passwords is safer than hashing them.
Fact
Encryption is reversible: whoever gets the key gets every password. Passwords should be hashed with a slow algorithm, never decryptable.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
Plan for a leaked secret before it happens: know how to rotate each secret in minutes (Git course, Topic 7.5), keep secrets short-lived where possible, and alert on unusual use (for example a key used from an unexpected IP or region).
Remember this
- 1
Secrets: store in a secrets manager (AWS Secrets Manager, Vault, GCP Secret Manager), never in code, images, or git. Each service gets only its own secrets via its identity, and secrets are rotated regularly and after any exposure.
- 2
Prefer no secret at all: workload identities (IAM roles, OIDC, managed identities) give short-lived credentials automatically, so there's nothing long-lived to leak.
- 3
Encryption in transit: TLS everywhere, including inside the network for sensitive traffic (mTLS between services).
- 4
Encryption at rest with envelope encryption: data is encrypted with a data key, and the data key is encrypted with a master key held in a KMS that never leaves it. Rotating or revoking the master key controls access to everything, and access to the KMS is logged.
- 5
Passwords: hash with a slow, memory-hard function and a unique salt per user: Argon2id (preferred) or bcrypt. Never MD5/SHA-256 alone (too fast to brute-force), never reversible encryption.
- 6
Defence in depth for logins: rate limiting, breached-password checks, multi-factor authentication, and passkeys reduce what a stolen password is worth.
Explain it without notes
Why does envelope encryption use two layers of keys?
Why should password hashing be slow?
Practice
Move a database password from an environment file to a secrets manager.
Choose Argon2id parameters for your login service.
Trade-offs
- ↔
Stronger password hashing costs CPU and memory per login, which matters at large scale (rate limiting helps). Envelope encryption with KMS adds latency and cost per key operation, so cache data keys briefly for high-volume encryption.
Run it in production
You've designed it. Now build, operate, and break the same idea hands-on in the DevOps courses:
Done when you can
Secrets live in a secrets manager, scoped and rotated.
Data is encrypted in transit and at rest with KMS keys.
Passwords are hashed with Argon2id or bcrypt, never encrypted.