DOWNLOAD_SIGNING_SECRET made mandatory at startup - silent fallback removed

counselos removes the `"dev-secret"` fallback from `downloadTokens.ts` and adds a boot-time check that prints a helpful error and exits if `DOWNLOAD_SIGNING_SECRET` is missing or shorter than 32 characters. Any deployment without the variable set won't start.

securityinfrastructure

The problem being closed: getSecret() in downloadTokens.ts used a three-step fallback chain - DOWNLOAD_SIGNING_SECRET ?? SUPABASE_SECRET_KEY ?? "dev-secret". Both the literal and the coupling to SUPABASE_SECRET_KEY were visible in public source. Any operator who deployed without setting the variable would silently sign download URLs with a guessable or service-coupled key.

The fix cuts the fallback entirely. getSecret() now throws if the variable is absent or under 32 characters. At the module level in backend/src/index.ts, assertRequiredEnv() runs before Express is configured: it collects validation failures into an array, prints them with a suggested fix (openssl rand -hex 32), and calls process.exit(1). The server never reaches app.listen() without a valid secret.

backend/.env.example is updated with documentation for both DOWNLOAD_SIGNING_SECRET and MIKE_DEBUG_STREAMS. The comment on the latter warns that filenames, storage paths, and document text land on disk and stdout when the flag is on - leave it unset in production.

This is a breaking change. Upgrade sequence: generate the secret first, add it to backend/.env, then deploy. Any rollout that deploys the code before setting the variable will fail to start. That's intentional - the explicit error is better than the previous silent misconfiguration.

So what Worth importing if your fork issues signed download URLs from `downloadTokens.ts` and you haven't already removed the fallback chain. The change is 40 lines across three files. Verify your `getSecret()` still has the same shape, and stage the rollout: secret first, deploy second.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

1 commit from counselos/mike-inhouse, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
98d20f52 fix: require DOWNLOAD_SIGNING_SECRET at startup (no fallback) counselos 2026-05-04 ↗ GitHub

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-73.md from inside the repo you want the changes in.

⬇ Download capture-thread-73.md