Secrets
After this you can answer: How does the API get the database password without it being in the code or the image?
Picture it
Section titled “Picture it”flowchart TB TD["api task definition<br/>secrets: ARNs only"] --> ECS["ECS starts a task"] ECS -->|"execution role:<br/>GetSecretValue"| SM["Secrets Manager"] SM --> C["container env:<br/>DB_USER, DB_PASSWORD, REDIS_URL"]How it works
Section titled “How it works”- The value is stored once, in Secrets Manager, encrypted. Pulumi state and the code only ever see the ARN.
- The task definition maps a secret to an env var. For JSON secrets it can pick one key:
<arn>:password::becomesDB_PASSWORD. - At task start, ECS reads it with the execution role, which may call
secretsmanager:GetSecretValueon exactly those ARNs. - The value is read once. A running task keeps the value it started with, even if the secret changes later.
In MiniTickets
Section titled “In MiniTickets”| Secret | Holds | Read by |
|---|---|---|
rds!db-… | Postgres user and password (JSON) | api execution role, at task start |
minitickets/dev/redis-url | rediss://:<auth token>@<endpoint>:6379 | api execution role |
minitickets/dev/revalidate-secret | 64 random characters | api and web execution roles |
minitickets/dev/ticket-signing | the HMAC key for ticket QR codes | the tickets Lambda, at run time |
The database secret is made by RDS itself (manageMasterUserPassword), so the password never
exists in our code, config or Pulumi state. RDS rotates it every 7 days by default. The Redis URL
is built in infra/src/data/secrets.ts → createSecrets.
| From → to | What happens | What allows it |
|---|---|---|
| API ECS service → RDS master password secretonly when computeEnabled = true | ECS reads the database user and password when a task starts |
|
See it in AWS
Section titled “See it in AWS”Secrets Manager → Secrets → minitickets/dev/redis-url → Overview. Do not press “Retrieve
secret value”.
aws secretsmanager describe-secret --secret-id minitickets/dev/redis-url shows metadata only,
never the value.
The mapping into env vars: infra/src/compute/task.ts → createApiTask.
Break it
Section titled “Break it”| Symptom | Cause | Where to look |
|---|---|---|
| Tasks stop with ResourceInitializationError | Wrong ARN or JSON key, or the role may not read it | ECS → stopped task → Stopped reason |
| “password authentication failed” after a rotation | Running tasks hold the old password | Rotation date; restart the service |
| API cannot connect to Valkey | URL starts with redis://, but TLS is required | The URL format in secrets.ts |
Say it in an interview
Section titled “Say it in an interview”Follow-ups
Section titled “Follow-ups”How would you handle rotation without restarts?
Read the secret in code with a short cache and reconnect on an auth error. That needs the task role
to have GetSecretValue, which widens what the code may do. Today a restart is the simpler fix.
Why is the origin secret for CloudFront not in Secrets Manager?
No running code reads it. Only two configurations hold it, CloudFront and the ALB listener, so Pulumi keeps it as an encrypted secret in its state.
Why must the book never show get-secret-value?
It prints the secret in plain text into your terminal and its history. describe-secret answers
every debugging question (does it exist, when was it rotated) without the value.
Advanced: Details per secret
The Redis and revalidate secrets use recoveryWindowInDays: 0, so switching a layer off and on
does not collide with a name still scheduled for deletion. The ticket signing key has no rotation
on purpose: replacing it would make every issued ticket invalid
(infra/src/tickets/storage.ts → createTicketStorage).
Checkpoint
Section titled “Checkpoint”Answer these without scrolling up. If one feels hard, reread that section.
- What does the task definition hold instead of the password?
- Which role reads the secrets, and when?
- What happens to a running task when RDS rotates the password?
- Which secret is read at run time instead of at start, and by what?
- Why does the Redis URL start with
rediss://?
Redraw it from memory: task definition (ARNs) → ECS with the execution role → Secrets Manager → container env vars
Try this: on the map, select the RDS master password secret and open 'Who can touch me' in the Permissions tab
Read this book online: https://book.theversehub.in/