fix(security): fail fast on a missing/placeholder/public LYRA_SECRET_KEY

.env.example shipped a valid, PUBLIC base64 key — if a user didn't replace it,
every credential got encrypted with a publicly-known key and everything still
"worked," so the footgun was silent.

- .env.example now ships an obvious placeholder (CHANGE_ME_generate_with_...)
  with a "you MUST replace this" note and the openssl hint.
- web + worker validate LYRA_SECRET_KEY at startup: missing / placeholder /
  wrong-length ⇒ loud FATAL banner and refuse to start (web via the Next.js
  instrumentation hook, worker via _require_secret_key before touching the DB).
  The old public example key ⇒ a loud WARNING but not fatal, since an existing
  install may have encrypted its creds under it (rotating needs re-entry).
- Validation lives in an edge-safe web/src/lib/secret-key.ts (no node:crypto)
  so the instrumentation hook bundles for both runtimes; crypto.ts re-exports.
- README emphasizes generating a fresh key + keeping it stable.

Verified live: worker exits 1 on placeholder/unset before any DB call; web
instrumentation throws and refuses to serve on the placeholder. web 138 tests,
worker 204/7-skip, tsc clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jonathan
2026-07-14 10:19:46 +02:00
parent 190e0ef4b6
commit 8cd5392ec3
9 changed files with 201 additions and 2 deletions
+7
View File
@@ -90,6 +90,13 @@ cp .env.example .env # then edit: set LYRA_SECRET_KEY (openssl rand -ba
docker compose up -d --build # web on http://localhost:8770 ; NEVER `down -v` (wipes the Postgres volume)
```
**Generate your own `LYRA_SECRET_KEY`** (`openssl rand -base64 32`) before first run — it
encrypts your stored Qobuz/Soulseek/Last.fm credentials. `.env.example` ships an obvious
placeholder, and both web and worker **refuse to start** while the key is missing or still
the placeholder. Once set, keep it stable: changing it makes already-stored credentials
undecryptable (you'd re-enter them in Settings). Optionally set `LYRA_PASSWORD` too (see
[Security](#security)).
The web entrypoint runs `prisma migrate deploy` on every rebuild, so schema changes
reach the live DB automatically. Enter Qobuz / Soulseek / Last.fm credentials in
**Settings** (they persist across rebuilds), then follow an artist or request an album