← NovaLMS

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

Required

Every 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 12

Passwords 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 check

New passwords must be 12+ characters with at least one of each: lowercase, uppercase, digit. Common passwords are rejected.

Login rate limit

5 attempts / 15 min

Per 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 max

Cookies cannot be read by JavaScript, are only transmitted over HTTPS, and expire after 12 hours of absolute time.

Single sign-on (SSO)

Roadmap

Google 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 + action

Six 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

Enforced

Counselors 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

Enforced

Parents 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

Enforced

Teachers can only grade students in sections they teach. Section ownership is checked on every grade write.

Messaging

Role-pair allowlist

Students 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

On

Every 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

On

Every 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 level

The 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

On

If 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 enforced

HTTPS 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 notes

The 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 Claude

AI 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

On

Every 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

On

User-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

On

AI-suggested grades cannot exceed the assignment's maximum, regardless of what the model returns. Suspicious outputs are flagged for human review.

Data minimization

On

AI 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 WAF

OWASP Core Rule Set enabled. SQL injection probes, XSS attempts, and known-bad scanners are blocked at the edge before reaching the application.

DDoS protection

Cloudflare

Volumetric attacks are mitigated at Cloudflare's edge.

Bot management

Cloudflare Turnstile on login

Credential stuffing bots are blocked before they reach the application. No CAPTCHAs for legitimate users in most cases.

Security headers

On

Strict 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

On

Session cookies have the Secure and HttpOnly flags. SameSite=Lax.

Data lifecycle

Soft delete

On for User, Student, intervention, discipline, nurse

Deleting 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-site

pg_dump → gzip → age-encrypted (recipient key held offline) → off-site bucket. Restore drill performed quarterly.

Data export

On request

A school can request a full export of their data at any time, in standard formats. SOPIPA / AB 1584 compliance.

Deletion on request

Per FERPA workflow

Parents (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

Active

We accept security reports at [email protected]. Acknowledgement within 72 hours. security.txt.

Dependency monitoring

npm audit + Dependabot

Weekly scan; criticals patched within 14 days, highs within 30.

Penetration testing

Planned before whole-school pilot

Independent third-party pentest scheduled before any deployment with real student data. Summary report available to subscribing schools.

Incident response

72-hour parent notification SLA

Documented runbook. California Civil Code §1798.29 requires notification within 30 days; we commit to 72 hours where the law allows.

Student Privacy Pledge

Signed

Public 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 roadmap

Targeting 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 yet

Not on the immediate roadmap. Available after SOC 2.

Full WCAG 2.1 AA accessibility certification (VPAT)

In progress

Pattern library is being rebuilt for WCAG 2.1 AA compliance. VPAT will be published when the audit completes.