AWS with Floci
Chapter 11 — Security & Secrets
Day 1 — Secrets Manager and SSM Parameter Store
1. Concept Primer
Secrets Manager stores sensitive values (DB passwords, API keys) with built-in rotation support. Parameter Store (SSM) is a simpler key-value config store — cheaper and fine for non-rotating config, while Secrets Manager is the better fit for anything needing rotation or fine-grained access policies.
2. Hands-on Exercise
Store a secret and a plain parameter, then retrieve both back out.
3. Exact Commands
floci start && eval $(floci env)
aws secretsmanager create-secret \
--name day1/db-password \
--secret-string '{"username":"admin","password":"sup3rSecret!"}'
aws secretsmanager get-secret-value --secret-id day1/db-password \
--query 'SecretString' --output text
aws ssm put-parameter \
--name "/day1/app/log-level" \
--value "INFO" \
--type String
aws ssm get-parameter --name "/day1/app/log-level" --query 'Parameter.Value' --output text
4. Gotchas
- Secret names containing
/are fine and common (used for logical namespacing), but double check quoting in your shell — unescaped slashes rarely break things, but unescaped special characters in the JSON secret string will. - Rotation configuration (
rotate-secret+ a rotation Lambda) is a more advanced feature to verify current support depth for before relying on it — this chapter covers store/retrieve, not automated rotation.
5. Self-Check
Given a piece of config that changes constantly but isn't sensitive (like a feature flag), would Parameter Store or Secrets Manager be the more appropriate choice, and why?
Day 2 — KMS Envelope Encryption
1. Concept Primer
KMS manages encryption keys without ever exposing the raw key material to you directly. Envelope encryption is the standard pattern: KMS encrypts a small data key, you use that data key locally to encrypt your actual (possibly large) payload, then store the encrypted data key alongside the encrypted payload.
2. Hands-on Exercise
Create a KMS key, generate a data key, and use it to encrypt/decrypt a short message locally.
3. Exact Commands
eval $(floci env)
KEY_ID=$(aws kms create-key --query 'KeyMetadata.KeyId' --output text)
echo "KMS Key: $KEY_ID"
# Direct encrypt/decrypt of a small payload
aws kms encrypt --key-id $KEY_ID --plaintext "hello secret" \
--query 'CiphertextBlob' --output text > ciphertext.txt
aws kms decrypt --ciphertext-blob fileb://<(cat ciphertext.txt | base64 -d) \
--query 'Plaintext' --output text | base64 -d
# Envelope pattern: generate a data key, keep the plaintext key only in memory/briefly
aws kms generate-data-key --key-id $KEY_ID --key-spec AES_256
4. Gotchas
kms encryptoutput is base64-encoded already; piping it through an extrabase64 -dbeforedecrypt(as shown) is necessary because the CLI writes text output, not raw bytes, to a file.generate-data-keyreturns both aPlaintext(usable immediately, must never be persisted) and aCiphertextBlob(safe to store) version of the same key — mixing these up is the single most common real-world KMS mistake.
5. Self-Check
Why is it safe to store the CiphertextBlob from generate-data-key right next to your
encrypted data, but never safe to store the Plaintext version?