Security: plumb SESSION_SECRET into compose and .env.example (#42) #67

Merged
claude-bot merged 1 commit from fix/42-session-secret into main 2026-07-16 05:23:01 +00:00
Contributor

Fixes #42. SESSION_SECRET defaulted to change-me-in-production and was absent from docker-compose.yml and .env.example, so every compose deployment silently signed session cookies with the hardcoded default.

Changes

  • docker-compose.yml: add SESSION_SECRET=${SESSION_SECRET:?Set a random SESSION_SECRET} to the app service — docker compose up now hard-fails if it's unset (hard-fail beats silent insecurity). Matches the file's existing ${VAR:-default} env style (no env_file: in use).
  • .env.example: add SESSION_SECRET= with generation guidance (openssl rand -hex 32).
  • backend/app/main.py: log CRITICAL at startup if the insecure default is in use while auth is enabled — warns loudly without breaking DISABLE_AUTH=true dev/test flows or bare-uvicorn runs (compose-level :? already blocks the deployment path).

Verification

  • docker compose config hard-fails with the required message when SESSION_SECRET is unset; resolves correctly when set.
  • Backend ruff check / ruff format --check / mypy app/ clean after rebasing onto the now-green main.

Follow-up (ops, not in this PR)

The dev server's live SESSION_SECRET still needs rotating to a real random value.

🤖 Generated with Claude Code

Fixes #42. `SESSION_SECRET` defaulted to `change-me-in-production` and was absent from `docker-compose.yml` and `.env.example`, so every compose deployment silently signed session cookies with the hardcoded default. ## Changes - **docker-compose.yml**: add `SESSION_SECRET=${SESSION_SECRET:?Set a random SESSION_SECRET}` to the app service — `docker compose up` now hard-fails if it's unset (hard-fail beats silent insecurity). Matches the file's existing `${VAR:-default}` env style (no `env_file:` in use). - **.env.example**: add `SESSION_SECRET=` with generation guidance (`openssl rand -hex 32`). - **backend/app/main.py**: log CRITICAL at startup if the insecure default is in use while auth is enabled — warns loudly without breaking `DISABLE_AUTH=true` dev/test flows or bare-`uvicorn` runs (compose-level `:?` already blocks the deployment path). ## Verification - `docker compose config` hard-fails with the required message when `SESSION_SECRET` is unset; resolves correctly when set. - Backend `ruff check` / `ruff format --check` / `mypy app/` clean after rebasing onto the now-green main. ## Follow-up (ops, not in this PR) The dev server's live `SESSION_SECRET` still needs rotating to a real random value. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Fix #42: require SESSION_SECRET, stop silently signing with default
All checks were successful
CI / Alembic migration check (pull_request) Successful in 1m17s
CI / Python lint & type-check (pull_request) Successful in 1m46s
CI / Frontend lint, test & build (pull_request) Successful in 1m57s
CI / Python tests (pull_request) Successful in 2m32s
CI / Dependency audit (pull_request) Successful in 1m37s
CI / Docker build, health smoke & E2E (pull_request) Successful in 20m38s
fd445ce60f
docker-compose.yml silently ran with the hardcoded SESSION_SECRET
default from backend/app/config.py because the variable was never
passed through the app service's environment block. Every compose
deployment therefore signed session cookies with a publicly known
key.

- docker-compose.yml: pass SESSION_SECRET through with the `:?`
  interpolation form so `docker compose up`/`config` hard-fails with
  a clear message if it's unset, instead of falling back to the
  insecure default.
- .env.example: document SESSION_SECRET with a generation command
  (openssl rand -hex 32).
- backend/app/main.py: log a CRITICAL warning at startup if the
  default secret is still in use while auth is enabled (DISABLE_AUTH
  is false), so misconfiguration is loud even outside compose.
  DISABLE_AUTH=true dev/test flows are unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude-bot deleted branch fix/42-session-secret 2026-07-16 05:23:02 +00:00
Sign in to join this conversation.
No description provided.