Repository navigation
Phase 1: security and ops hardening (P-01–P-10) - #25
Merged
Merged
Conversation
Align DEPLOY.md and .env.example on EMAIL_*. Keep deprecated SMTP_* aliases so existing Railway env still works, warn once, and cover precedence in tests.
Railway startCommand was overriding the Dockerfile and skipping data.ingest, so production RAG stayed empty. One script now runs migrate → ingest → uvicorn for Docker and Railway; ingest failure aborts the deploy.
Replace NEXT_PUBLIC_PREVIEW_AUTH with PREVIEW_AUTH. Production plus the flag throws at boot. Localhost/127.0.0.1 still work in development via shared isPreviewAuthAllowed helper.
Missing Origin/Referer no longer bypasses CSRF in production. Origins are compared as scheme+netloc only, so suffix/prefix lookalikes cannot pass. Development still allows TestClient requests with no Origin.
POST /auth/refresh used to load every live refresh row and hash-compare in Python. Lookup is now equality on the stored SHA-256, with a unique partial index so NULLs (logged-out rows) stay allowed.
GET /health now includes llm=connected|unconfigured|unavailable via a 5s GET to LLM_BASE_URL. Provider 401 counts as reachable. LLM outage does not 503 the process, so Railway/Docker probes stay up.
Unset REQUIRE_EMAIL_VERIFICATION now means true in production and false in development. Explicit false/0/off still disables it. Missing SMTP in prod logs an error at boot but does not crash.
Replace path-filtered Backend CI / Frontend CI and the broken workflow_run deploy-gate with .github/workflows/ci.yml. Gate needs both jobs and is the status check to require on main.
Stop rewriting transport failures as FastAPI-style {detail}. Upstream
4xx/5xx still pass through. set-cookie stays off the hop-by-hop list.
Record the unmerged hardening branch as current state. Strike deploy-gate.yml, SMTP_* as required, and NEXT_PUBLIC_PREVIEW_AUTH.
Spell out what Phase 1 closed versus what still blocks taking money or calling the tutor a finished product.
KafKafrnZ
added a commit
that referenced
this pull request
Aug 25, 2026
Backend (mypy): - config.py: JWT_SECRET/DATABASE_URL os.getenv() results weren't narrowed to str for the class-level type annotation. - database.py: switch declarative_base() to SQLAlchemy 2.0's typed DeclarativeBase — the old style made every model class an "invalid base class" under mypy. - main.py: import FastApiIntegration/SqlalchemyIntegration directly instead of dotted attribute access on sentry_sdk.integrations.*. This wasn't just a type error — sentry_sdk doesn't auto-import integration submodules, so sentry_sdk.init() would have raised AttributeError at runtime the moment SENTRY_DSN was ever set. - analytics.py: explicitly annotate weak_areas_serialized as str | dict[str, float] so both branches type-check (matches StatsResponse's existing schema). Frontend (eslint): replace `as any` with a narrow structural cast in api-proxy.test.ts. Verified locally: mypy backend/app/ --ignore-missing-imports clean, npm run lint / tsc --noEmit / npm test (46/46) / npm run build all pass, and app.main imports + FastAPI app builds with SENTRY_DSN set. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PvQrDCnKHKLdwaaT2Qi2wT
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.
Summary
Phase 1 hardening for Ascend AI. Makes the stack safe to create accounts and run CI. It is not yet a paid product.
Remaining work to ship and charge: PRODUCTION_READINESS.md.
What landed
EMAIL_*canonical;SMTP_*deprecated fallbackbackend/scripts/start.sh: migrate → ingest → uvicornPREVIEW_AUTH; production + flag throws/healthreports LLM reachability without spending tokensBACKEND_UNREACHABLE;set-cookiestill forwardedAfter merge
main: require GitHub check Gate (workflow CI).DEPLOY.md.mainand Gate is green.Test plan
Gategreen on this PR