Security
We handle student PII. This page lists the concrete controls that protect it. Where we have an exception, we say so. Where work is in progress, we say so. No marketing.
Authentication
Two-factor authentication for staff
RequiredEvery ADMIN, TEACHER, and COUNSELOR account must enroll a TOTP authenticator (Google Authenticator, 1Password, Authy, Bitwarden, etc.) before accessing any student data. Enforced in middleware — no bypass.
Password storage
bcrypt cost 12Passwords are hashed with bcrypt at a work factor of 12. We never see, log, or store plaintext passwords.
Password complexity
12 chars min, banned-list checkNew passwords must be 12+ characters with at least one of each: lowercase, uppercase, digit. Common passwords are rejected.
Login rate limit
5 attempts / 15 minPer IP and per account. Bots are blocked by Cloudflare Turnstile before the rate-limit table is even touched.
Session cookies
HttpOnly, Secure, SameSite=Lax, 12h maxCookies cannot be read by JavaScript, are only transmitted over HTTPS, and expire after 12 hours of absolute time.
Single sign-on (SSO)
RoadmapGoogle Workspace SSO is on the roadmap. Schools that need SAML/SSO today should ask — happy to scope it.
Authorization
Role-based access control
Enforced in middleware + page + actionSix roles: STUDENT, TEACHER, PARENT, COUNSELOR, ADMIN, PENDING. Path-prefix gates in middleware are the first line; every server action also checks role + resource ownership. Defense in depth.
Counselor caseload isolation
EnforcedCounselors only see students assigned to them. Trying to view another counselor's student via URL hacking redirects, and the denied attempt is logged with the attacker's user ID, IP, and timestamp.
Parent-child access
EnforcedParents see only the students they're explicitly linked to. The link is a separate database record, not derived from name or email.
Teacher gradebook scoping
EnforcedTeachers can only grade students in sections they teach. Section ownership is checked on every grade write.
Messaging
Role-pair allowlistStudents cannot DM students. Parents cannot DM parents. Each role pair (student ↔ teacher, parent ↔ teacher, etc.) is explicitly authorized based on an actual educational relationship.
Audit trail
Cross-user reads logged
OnEvery time a counselor views a student, a parent views a child's grades, an admin views any staff member, or AI processes a student's data — we record the actor, target, action, IP address, and timestamp.
Grade changes logged
OnEvery grade create/update writes a row to GradeChangeLog: who, when, old value, new value. Visible to admins.
Audit log is tamper-evident
Enforced at database levelThe application's database role cannot UPDATE or DELETE rows in AccessLog, AIUsageLog, or GradeChangeLog. This is enforced by Postgres permissions, not application code — so even a fully compromised app account cannot edit the audit trail.
Denied access attempts logged
OnIf a counselor tries to view a student outside their caseload, we log that as `view_*:denied` with the studentId — so you can see snooping attempts.
Encryption
In transit (browser → app)
TLS 1.3 enforcedHTTPS only, HSTS with max-age 1 year, includeSubDomains. HTTP is permanently redirected at the edge.
Cloudflare → origin
TLS (Full strict)Encrypted with a Cloudflare-issued origin certificate, mutually authenticated. We are not on Flexible SSL.
At rest
Volume encryption (OVH); field-level for sensitive notesThe database lives on an encrypted volume. We additionally encrypt the most sensitive fields (IEP/504 details, intervention notes, discipline narratives, nurse-visit notes) with AES-256-GCM, keyed independently of the database.
AI / third-party data flow
AI provider
Anthropic ClaudeAI features (grading assist, lesson-plan generation, attendance pattern analysis, counselor query, etc.) call Anthropic's Claude. We are pursuing an enterprise / zero-retention contract before any pilot with real student data.
AI usage log
OnEvery AI call is logged with: who triggered it, what feature, which student IDs were referenced, and SHA-256 hashes of the prompt + response. Parents can ask 'what has the AI seen about my child' — we can answer in under a minute.
Prompt injection hardening
OnUser-controlled content is wrapped in delimiters and passed as data, not instructions. The model is system-prompted to ignore embedded instructions in user content.
AI output guard
OnAI-suggested grades cannot exceed the assignment's maximum, regardless of what the model returns. Suspicious outputs are flagged for human review.
Data minimization
OnAI calls include first name and grade level only — not full names, not student IDs, not addresses. We never send AI a row of PII it doesn't need.
Network / infrastructure
Web application firewall
Cloudflare WAFOWASP Core Rule Set enabled. SQL injection probes, XSS attempts, and known-bad scanners are blocked at the edge before reaching the application.
DDoS protection
CloudflareVolumetric attacks are mitigated at Cloudflare's edge.
Bot management
Cloudflare Turnstile on loginCredential stuffing bots are blocked before they reach the application. No CAPTCHAs for legitimate users in most cases.
Security headers
OnStrict Content-Security-Policy, HSTS, X-Frame-Options DENY, X-Content-Type-Options nosniff, Referrer-Policy strict-origin-when-cross-origin, Permissions-Policy locking down camera/microphone/geolocation/payment.
HTTPS-only cookies
OnSession cookies have the Secure and HttpOnly flags. SameSite=Lax.
Data lifecycle
Soft delete
On for User, Student, intervention, discipline, nurseDeleting a user does not erase their audit trail. The user is marked deleted and excluded from listings, but historical records remain queryable by admins.
Backups
Nightly, encrypted, off-sitepg_dump → gzip → age-encrypted (recipient key held offline) → off-site bucket. Restore drill performed quarterly.
Data export
On requestA school can request a full export of their data at any time, in standard formats. SOPIPA / AB 1584 compliance.
Deletion on request
Per FERPA workflowParents (or eligible students 18+) can request correction or deletion of records. We support this through an admin-mediated workflow that preserves the audit trail of the deletion itself.
Operational rigor
Vulnerability disclosure
ActiveWe accept security reports at [email protected]. Acknowledgement within 72 hours. security.txt.
Dependency monitoring
npm audit + DependabotWeekly scan; criticals patched within 14 days, highs within 30.
Penetration testing
Planned before whole-school pilotIndependent third-party pentest scheduled before any deployment with real student data. Summary report available to subscribing schools.
Incident response
72-hour parent notification SLADocumented runbook. California Civil Code §1798.29 requires notification within 30 days; we commit to 72 hours where the law allows.
Student Privacy Pledge
SignedPublic commitment to never sell student data, never use it for advertising, and limit data collection to educational purposes.
Insurance
Cyber liability$1M policy. Certificate available on request.
What we don't have yet — by name
SOC 2 Type II
On roadmapTargeting completion within 12 months of first paid customer. Schools requiring SOC 2 today should contact us — we can compensate with extra contractual commitments in the interim.
ISO 27001
Not yetNot on the immediate roadmap. Available after SOC 2.
Full WCAG 2.1 AA accessibility certification (VPAT)
In progressPattern library is being rebuilt for WCAG 2.1 AA compliance. VPAT will be published when the audit completes.