Security¶
Security is enforced on the server, for every request. The UI hides what a user shouldn't see, but the backend is the authority. This page summarizes the posture and the hardening completed in the 2026 review.
The model in plain terms¶
- Authentication. Login issues a signed token. Every request re-checks the token and the live account — a blocked or demoted user loses access on their next click, not seven days later.
- Authorization. Three roles (student / teacher / admin) gate every action. Teachers are scoped to their own classes and students everywhere. Admins are unrestricted. Students see only their own data and only assigned work.
- Data isolation. Object access is checked by owner, not just by "are you logged in" — a student cannot read another student's essay, attempt, audio, or notifications by guessing an ID.
- Media. Files in storage are served only through signed URLs with an expiry, verified with a constant-time check.
- Defense in depth. A strict Content-Security-Policy and hardening headers protect the browser even if bad content slips through.
What was hardened in the 2026 review¶
A full multi-agent security audit (find → independently verify → fix) drove these production changes:
- Teacher-scoping added to every management route that was missing it (user directory, classes, sessions, schedule generation, attendance, assignment lists and rosters, teacher notifications).
- The two assignment write-paths (delete, create) now enforce class/assignment ownership — a teacher can't destroy or target outside their scope.
- A student's homework-only access is enforced on the server for all four skills, down to the individual passage/section.
- The signing secret fails closed in production — the app refuses to run on a public default, closing an admin-token-forgery risk.
- Login tokens are re-validated against the live account every request, so deactivation and role changes take effect immediately.
- The shared read-aloud access code uses a constant-time comparison.
- All rich-content rendering (materials, prompts, essays, corrections) is sanitized — closing a stored cross-site-scripting surface where OCR/AI-derived HTML reached students.
- A strict Content-Security-Policy (plus clickjacking, MIME-sniffing, and HTTPS-enforcement headers) blocks inline-script execution as a second line of defense.
- AI spend is checked before the paid call and fails closed, so no single user can drain the center's monthly budget.
- The AI Tutor toggle is enforced server-side, not just hidden in the UI.
What's covered by tests¶
A role/permission end-to-end suite runs against production and covers the access matrix — including negative cases (wrong role → forbidden, cross-user → forbidden), the homework-only gate, submission idempotency, provisional-band handling, and the deactivated-account lockout. It is green.
Known residual items¶
These are documented, lower-severity, and tracked (see Status & gaps):
- Login tokens live in browser storage rather than an HTTP-only cookie. The per-request account check and the strict CSP close the practical takeover path; moving to a cookie is a planned hardening.
- The undeployed legacy microservices carry a weaker security model. They are not live, but should be archived so they can't be accidentally deployed. Two of their unauthenticated internal endpoints were guarded as a precaution.
Privacy notes for operators¶
- Student and parent contact details are visible only to admins and the student's own teacher.
- Audio recordings are private (signed-URL access only) and expire.
- There is no online payment data — no card numbers are ever handled.