Whitepaper · Updated 2026-10-20 (v4: names sealed under a server-held key behind one logged function; the browser-only vault is withdrawn)

Student Privacy Architecture

This document describes what student information Prism keeps, where it lives, who can read it, and how we know. It is written for school principals and district counsel evaluating Prism against FERPA, state student-privacy statutes, and their own district policies. The first section is in plain English. The technical detail follows for security review.

The one-paragraph version

Prism keeps as little identifying student information as it can and knows exactly who looks at the rest. Students who arrive through your identity provider or your learning management system have no email address in Prism at all: we see an opaque identifier, nothing more. Every grade, score, mastery estimate and page view is stored against a per-class pseudonym, not a name. A student's name is kept so their teacher can run a class, and it reaches a screen through exactly one function, which only that class's teacher can call, and which writes a log entry every time it is called. If our database were published in full tomorrow, it would contain no student email for those students, no analytics row with a name on it, and an audit trail of every time a name was read.

What the database actually contains

Prism stores three categories of student-related data. They live in different places, with different protections:

1. Pseudonymous analytics (the most common case)

Every student in a class gets an opaque per-class identifier like stu_xb7q3m1lo9k4. That string is what the analytics know the student as. Quiz scores, mastery estimates, page-view counts, the P-Score, every assignment grade: they all reference the pseudonym. There is no student name in any of these tables. A different class gets a different pseudonym for the same human; you cannot cross-correlate by ID.

2. The student's name, behind one door

A student's display name is stored once, on their account, sealed: encrypted with AES-256-GCM under a key that lives in the server's environment and in no table, so a copy of the database alone contains no student name. It is never joined into analytics. The only way a teacher-facing page turns pseudonyms back into names is a single database function that refuses anyone who is not that class's teacher and records every call: which teacher, which class, how many names, when. There is no second path; any code that wants names has to go through that function, which gives an auditor one place to check and one log to read.

3. Auth-system identity (the student's own account)

How the student signs in depends on your district:

  • SSO-federated and LMS-launched districts: the student signs in through your identity provider, or opens Prism from inside Canvas or another LMS. Prism receives an authentication token and immediately gives the account an opaque synthetic address. The application-level profiles.email column is NULL. We have no readable email for the student anywhere in our database; your directory and your LMS keep it.
  • Non-SSO districts: the student signs in with email and password. The email is hashed in the browser before it reaches us, and the readable form is encrypted under a key held outside the database, used only to deliver notifications.

What this means under specific scenarios

If Prism receives a subpoena for student data

We can produce pseudonymous analytics and, for a named class, the roster its teacher sees, because we hold those names on the district's behalf. For SSO-federated and LMS-launched students we cannot produce an email address; we do not have one. We can also produce the access log showing every time a name was read, by whom.

If Prism's database is breached

The attacker gets pseudonymous analytics that name nobody, and account rows that carry a display name but, for federated and LMS students, no email, no birth date, no student number and no address, because we never collected them. The database is encrypted at rest by our hosting provider; backups are encrypted separately under our own key.

If a Prism employee goes rogue

An employee with database access can read what the database holds. What limits the harm is how little that is, and the fact that reads through the application are logged. We do not claim the math makes this impossible; we claim the data minimization makes it small, and the log makes it visible.

If a teacher forgets their password

They reset it. Nothing about their class is lost. We considered an architecture where names were encrypted under the teacher's password so that Prism could never read them, and withdrew it: it meant a forgotten password lost every roster, and it made the features districts actually ask for (LMS rostering, grade passback, exports, co-teachers) impossible to build. A promise that breaks the product is not a privacy feature.

If your district leaves Prism

We delete the accounts and the per-class pseudonym rows. The analytics that remain for research, if your district opted in, reference pseudonyms that no longer map to anyone.

Technical architecture

For security teams that want to verify our claims, this is the exact mechanism.

Identity layer

SSO federation (preferred). If the district uses Google Workspace for Education, Microsoft Entra, or any OIDC-compliant identity provider, students sign in through it. Supabase Auth receives an authentication token from the provider, and a trigger immediately replaces the provider's email address with an opaque synthetic value (stu_<hash>@no-pii.prism.invalid, using the unroutable .invalid domain). The application-level profiles.email column is set to NULL.

LMS launch (LTI 1.3). A student who opens Prism from Canvas or another LTI platform is identified by the platform's opaque subject identifier. Prism derives the account address from a hash of it and never stores the email the platform offers. The same applies when a teacher pulls the class list from the LMS: the roster arrives with names, which are kept, and emails, which are discarded.

Hashed identity (for districts without an IdP). When students sign in with email and password, the browser hashes the email (SHA-256 with a public per-deployment salt) and uses hash_<hex>@no-pii.prism.invalid as the address Supabase Auth sees. The real email is encrypted with RSA-OAEP-3072 under a Prism-held public key; the private key lives in the server's secrets manager, not the database. Notification delivery decrypts in-process, hands the recipient and body to the email vendor in a single call, and returns without logging the address.

Honest trust model for the non-SSO branch: a database compromise alone yields ciphertext for those emails. A simultaneous compromise of the database and the server secret yields the readable email. This is weaker than the SSO and LMS paths' structural "we don't have the data" guarantee. We recommend SSO or LMS launch where available.

Teachers are treated as standard auth-system users: teacher emails are stored in cleartext, same as any SaaS. Teachers are consenting adults; FERPA addresses the protected class, students.

The name chokepoint

One database function, public.teacher_student_display_map(_class_id), materializes names for a class. It is gated by public.is_class_teacher() and returns nothing to anyone else. On every call it inserts a row into public.student_name_access_log with the caller, the class, the number of names returned and the time. That table has no read policy: it is append-only through the application and readable only by operations tooling for audits and for your district on request. Every teacher-facing surface (roster, gradebook, reports, exports) calls this function; nothing else joins analytics to a profile.

Database surfaces

  • student_pseudonyms: per-(class, student) opaque ID. Every analytics table joins to this, never to a profile.
  • profiles: the account row. For students the display name is held only as ciphertext (full_name_sealed, AES-256-GCM under a server-held key, unsealed in process by the chokepoint and by the few student-facing pages that show a classmate's name); email only for password accounts and teachers; no birth date beyond what the consent-age check needs; no student number, no address.
  • student_name_access_log: the audit trail of name reads described above.

Encryption at rest and in transit

Student names are sealed in the application under a key the database never holds, on top of the hosting provider's encryption of the database and its storage at rest (AES-256). Nightly backups held by Prism are encrypted under a separate Prism key before they leave the database host. All traffic is TLS. Districts that require that Prism itself be unable to read names can be served with a district-held key through a key-management service; that is offered as an enterprise arrangement because it changes recovery and support obligations on both sides.

Messaging

Messages between teachers, students and parents are stored like the rest of the database: encrypted at rest, readable only by the thread's participants under row-level security. An earlier end-to-end design keyed to the teacher's password was withdrawn together with the name vault, for the same reason.

FERPA mapping

FERPA's 34 CFR § 99.3 enumerates personally identifiable information. The table below maps each category to where it lives in Prism.

  • Student's name: on the student's own account row, and reachable for teachers only through the logged chokepoint. Never present in analytics tables.
  • Student's email address: for SSO-federated and LMS-launched students, never stored; the account carries an opaque synthetic value. For non-federated students, hashed at sign-up, with the readable form encrypted under a server-held key for notifications only.
  • Parent or family member name: a parent who links to a student has an account of their own, treated as a teacher's is: name and email on their row.
  • Personal identifier (SSN, student number): Prism does not collect these.
  • Indirect identifiers (date of birth, place of birth, mother's maiden name): a birth date is asked only where consent rules require an age; nothing else is collected.
  • Other information that, alone or in combination, is linked or linkable: quiz scores, mastery estimates, etc. are stored against pseudonyms; linking them to a student requires the chokepoint, and leaves a log entry.

What this architecture does not protect against

We'd rather be specific about the limits than over-claim:

  • A compromised teacher device. If a teacher's laptop is stolen while signed in, the attacker has the access the teacher had, and the log will show the reads.
  • Database access. Prism staff with database access can read what is stored, which for students excludes the name (sealed) and the email (not stored). Staff with access to both the database and the server environment could unseal names; that access is restricted and reads through the application are recorded.
  • The student's own account. A student's own name is visible to the student and to classmates where the product shows it (discussions, a class leaderboard a teacher turns on). Students may choose to appear to classmates under a pseudonymous creature name instead.
  • Misuse by the teacher. A teacher who shares their students' names with an unauthorized third party has the data they need to do so. That is a school-policy issue, not an architectural one.
  • Your identity provider and your LMS. They still hold the student's email; that is how they authenticate. Prism does not see it, but it exists in their logs. This is the same trust boundary every SSO-using service has.
  • The email vendor. For non-SSO students, the notification path has to put the recipient on the wire to a vendor so the email can be delivered. Our server does not persist the recipient itself.

Questions and contact

Procurement officers and district counsel can reach us at art@onprism.org. For pricing inquiries see our pricing page; for the related legal documents see our Terms, Privacy Policy, and AI disclosure.

Demo sandbox · sample data, deleted after 7 days