Repository navigation
fix(config): refuse to start with the development auth secret, and add CI - #7
Open
VampiricCyborg wants to merge 3 commits into
Open
VampiricCyborg wants to merge 3 commits into
VampiricCyborg wants to merge 3 commits into
Conversation
auth_secret is the only input to the session cookie's HMAC, and it fell back to "dev-only-change-me" -- a constant committed to a public repository. Any deployment that never set AUTH_SECRET was signing sessions with a key anyone could read, so anyone could mint a cookie for any user id. Nothing forced the override, and AUTH_SECRET was absent from .env.example, so there was not even a prompt to set it. A model validator on Settings now rejects an empty or still-default secret whenever debug is off. It runs at Settings() construction, which app.main performs at import, so a misconfigured process dies before create_app() wires a single route rather than serving forgeable sessions. Debug builds stay exempt so local development needs no setup. Also documents AUTH_SECRET in .env.example alongside the three other AUTH_* variables, which were equally undocumented. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
useTypewriter reset its character count inside the effect that starts the interval, so a changed line rendered once at the previous line's length before the effect snapped it back to zero. Moving the reset into render -- the adjusting-state-on-a-changed-input pattern -- removes that frame, and seeding the initial count from `active` removes the same flicker on mount. This was also the one error failing `npm run lint`, which the next commit turns into a required check. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The repository had no automated checks at all. Two jobs, neither needing a live service: pytest for the backend, and typecheck, lint and build for the frontend. The backend job sets AUTH_SECRET because `from app.main import app` builds Settings at import time and a non-debug Settings now refuses the development default -- so this workflow's first run also exercises the guard added two commits ago. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two unrelated fixes that pair usefully: CI's very first run is against the commit that makes CI need
AUTH_SECRET, so the first PR this workflow gates is also the one that validates it end to end.1. The auth secret guard
auth_secretis the only input to the session cookie's HMAC, and it fell back to"dev-only-change-me"— a constant committed to this public repository. Any deployment that never setAUTH_SECRETwas signing sessions with a key anyone could read, which is enough to mint a cookie for any user id and read that user's documents.AUTH_SECRETwas also missing from.env.example, so nothing ever prompted anyone to set it.A
@model_validator(mode="after")onSettingsnow rejects an empty or still-default secret wheneverdebugis off. It fires atSettings()construction — whichapp/main.pyperforms at import — so a misconfigured process dies beforecreate_app()wires a single route. Debug builds stay exempt, so local development needs no setup.Verified both paths:
Five new cases in
tests/test_security.pycover the default, empty and whitespace secrets, a real secret, and debug builds staying exempt.Important
Railway production does not currently have
AUTH_SECRETset (confirmed against the Railway API, notrailway.json), and it deploys frommain. Set the variable in Railway before merging this PR. Merging first means the guard does exactly what it is built to do and takes the backend down on deploy.Whatever value is set invalidates every session cookie currently outstanding, so everyone signed in is logged out once. That is the intended outcome given the old key was public — but it is worth a heads-up rather than a surprise.
2. CI
Two jobs, neither needing a live service:
pytest -qfor the backend, andtsc --noEmit/npm run lint/npm run buildfor the frontend. The backend suite mocks the database and the embedding service, and the tests useASGITransport, so the app's lifespan never loads the ONNX model.The backend job sets a throwaway
AUTH_SECRETbecause of the guard above.npm run lintwas already failing onreact-hooks/set-state-in-effectinuseDemoLoop.ts, so CI would have been red on its first run.useTypewriternow rewinds during render instead of in an effect, which also removes a frame where a changed line rendered at the previous line's length.Checks run locally
pytest -q— 84 passed (was 79)npx tsc --noEmit— cleannpx eslint .— 0 errors (1 warning inservices/mock.ts, which is being deleted separately)npm run build— 15 routes🤖 Generated with Claude Code