VersionControl:PRs/maybelle-config/265

From PickiPedia: A knowledge base of bluegrass, old time psychedelic jams, and other public domain music
Jump to navigationJump to search
maybelle-config#265: hunter: ship each container only the secrets it reads (least privilege, step 1)
State 🟣 merged 2026-11-02 03:05:18
Worked on by magent, justin, re
Moods #emergence
Deploy redeploy hunter
Branch least-privilege-1 β†’ production, by magent-cryptograss
Opened Β· last pushed 2026-11-01 19:25:54 Β· 2026-11-01 19:38:12
Justin, #emergence, 16:39–19:23Z: no container should hold secrets it doesn't use.

**Before** (from `docker inspect`, names only): every container was given the same shared set, `POSTGRES_PASSWORD`, `GH_TOKEN`, `PICKIPEDIA_BOT_PASSWORD`, the Blue Railroad bot, `DELIVERY_KID_API_KEY`, `DJANGO_SECRET_KEY`, the Sentry DSN, `CODE_SERVER_PASSWORD`, and the memory-lane preview role. That was true whether or not anything in the container read them.

**After:**

| secret | emergent-magent | workbench | emergent-re / emergent-blu | why |
|---|---|---|---|---|
| `POSTGRES_PASSWORD` (the magent DB role) | β€” | β€” | β€” | memory-lane previews use the `memory_lane_preview` role; this was only their fallback |
| `MEMORY_LANE_PREVIEW_DB_PASSWORD` | βœ“ | βœ“ | β€” | where the magent user runs memory-lane previews |
| `GH_TOKEN` (magent-cryptograss) | βœ“ | βœ“ | β€” | re and blu run as their own users; their pollers never saw it |
| `PICKIPEDIA_BOT_PASSWORD` (Magent) | βœ“ | βœ“ | β€” | re and blu use their own `AGENT_<NAME>_PICKIPEDIA_BOT_PASSWORD` |
| `CODE_SERVER_PASSWORD` | β€” | βœ“ | β€” | code-server runs only in workbench |
| Blue Railroad bot | β€” | β€” | β€” | read on maybelle and delivery-kid, not on hunter |
| `DELIVERY_KID_API_KEY`, Sentry DSN | β€” | β€” | β€” | only a PickiPedia preview read them, and none starts: emergent-* are agents, and workbench is a Mood's kind |
| `DJANGO_SECRET_KEY` | β€” | β€” | β€” | never set (empty everywhere) |

The emergents' own keys are unchanged: each one's runner key, wiki bot password and model keys, plus my Claude token and OpenRouter key, which only my poller gets.

**What earlier deploys left behind is cleaned up too.** Taking a secret out of the environment doesn't take it out of the files that were written from it. At startup, `container_startup.py` now:
- removes `export NAME=` lines from `/home/magent/.bashrc` for managed variables the container no longer has (`prune_exports`, with 3 tests). My `.bashrc` still exports `POSTGRES_PASSWORD`, so this matters.
- removes gh's `hosts.yml` and the credential helper when there's no `GH_TOKEN`.
- removes the wiki MCP's `config.json` (Magent's password) and the MCP entry when there's no `PICKIPEDIA_BOT_PASSWORD`.

**Not in this PR:** step 2 (files under `/run/secrets` instead of environment variables), and the dead PickiPedia-preview code in `container_startup.py`, which can go in its own cleanup.

**Checked:** hunter's 67 tests pass (3 new). CI's render-diff shows each container's environment.

Deploy: redeploy hunter
Worked on by: magent, Justin, re, in #emergence