A district wants a tutoring assistant that knows each student's reading level. A university wants an advising bot that can see transcripts. An ed-tech startup wants to fine-tune on the essays its customers upload. All three are moving education records into a language model pipeline, and in the United States that brings the Family Educational Rights and Privacy Act (FERPA, 20 U.S.C. 1232g, with regulations at 34 CFR Part 99) into the design.
FERPA is old, short and written for filing cabinets, but its rules translate into concrete engineering requirements: who may see which record, what a vendor may do with it, what must be logged, and when a record counts as de-identified. This article explains the law from first principles, maps each rule onto an LLM architecture, shows code for scoped retrieval and disclosure logging, and walks a worked example through a district deployment. It is engineering guidance, not legal advice; the institution's counsel makes the final call on any specific contract or data flow.
What FERPA protects and who holds the rights
FERPA applies to educational agencies and institutions that receive funds from programs run by the U.S. Department of Education, which covers nearly every public school district and most colleges. It protects education records: records directly related to a student and maintained by the institution or by a party acting for it. Grades, transcripts, disciplinary files, special-education plans, attendance and advising notes all qualify. A few categories are carved out, including notes kept in a teacher's sole possession, records of a campus law enforcement unit created for law enforcement purposes, and certain treatment records.
The law protects personally identifiable information from those records, and the regulatory definition is broad. It includes direct identifiers such as a name or student ID, indirect identifiers such as a date of birth or a parent's name, and any information that, alone or combined, would let a reasonable person in the school community identify the student with reasonable certainty. It also covers information requested by someone the institution reasonably believes already knows who the record is about. That last clause matters for chat interfaces, because a user can ask a narrow question that only one student answers.
Rights belong to parents until the student turns 18 or enrolls in a postsecondary institution; then they transfer to the eligible student. The rights are to inspect records (the institution must respond within 45 days), to ask for corrections, and to control disclosure. The default rule is that disclosure of personally identifiable information needs signed, dated written consent that names the records, the purpose and the recipient. Enforcement runs through the Department's Student Privacy Policy Office, and the ultimate sanction is loss of federal funding; the Supreme Court held in Gonzaga University v. Doe (2002) that FERPA gives individuals no private right to sue. In practice the pressure on a vendor comes through contracts, state law and procurement, not federal lawsuits.
The disclosure paths an LLM product can use
Consent is rarely practical for a district-wide tool, so most LLM deployments rely on one of the exceptions in 34 CFR 99.31. Pick the path deliberately, because each one carries different engineering obligations.
| Path | When it fits | What it demands of the system |
|---|---|---|
| School official exception | A vendor performs a service the school would otherwise use employees for | Legitimate educational interest per user, direct control by the school, use only for the authorised purpose, no unauthorised redisclosure |
| Directory information | Names, grade level, enrolment status and similar items the school has designated | Annual public notice, honour every parent or student opt-out, never mix directory data with protected fields |
| De-identified data | Analytics, product improvement, model evaluation | Remove all personally identifiable information and document a reasonable determination that no student is identifiable, across releases |
| Studies exception | Research for or on behalf of the institution | Written agreement, a defined study, destruction when the purpose ends |
| Written consent | Optional features a student opts into | Signed and dated consent naming records, purpose and recipient; a revocation path |
The school official exception does most of the work. Under 99.31(a)(1)(i)(B) a contractor counts as a school official only if three conditions hold: it performs an institutional service that would otherwise be done by employees, it is under the direct control of the institution with respect to the use and maintenance of the records, and it is bound by the use and redisclosure limits of 99.33(a). Separately, 99.31(a)(1)(ii) requires the institution to use reasonable methods, technical or administrative, so that each official reaches only the records in which they have a legitimate educational interest. For an LLM product, that sentence is an access control requirement on retrieval, not a policy footnote.
Reference architecture
The diagram shows the shape that keeps a deployment inside the school official exception. The district gateway owns identity and the roster, so it can answer the question the regulation asks: does this teacher have a legitimate educational interest in this student? The vendor application receives only records that pass that check, stores them in a per-district index, and calls a model API under terms that forbid retention and training. The disclosure log sits beside the gateway because it is the school's record, not the vendor's.
Two hops deserve attention. First, the model API is a further party receiving the data. Treat the model provider as a subprocessor that must be named in the agreement and bound to the same limits; if its terms allow training on inputs or long retention, the school is no longer in direct control. Second, chat transcripts about a student, kept by the vendor on the school's behalf, are very likely education records themselves. Design for the 45-day inspection right from the start: you should be able to export every conversation that concerns a given student.
What the vendor agreement must say
Procurement is where most FERPA compliance for LLM tools is actually won or lost. The Department's Privacy Technical Assistance Center published guidance in 2014 on online educational services that still frames these agreements well. For an LLM product, the agreement should say the following in plain terms.
- Purpose limitation. Records are used only to provide the contracted service to this institution.
- No training on customer records. No pre-training, fine-tuning or embedding reuse across customers. If the vendor wants per-district adaptation, it must stay inside that district's tenant and be deleted with it.
- Named subprocessors. Model providers, vector databases and logging services are listed, with their retention settings, and changes require notice.
- No redisclosure except on the institution's instruction, and no sale or targeted advertising.
- Deletion at contract end, including indexes, caches, evaluation sets and backups on a stated schedule, with written confirmation.
- Access for the institution to export records so it can answer inspection and amendment requests.
- Security and incident notice with a defined timeline, because FERPA itself has no breach notification clock but state laws and the contract usually do.
Scoped retrieval and disclosure logging in code
The reasonable-methods requirement becomes a filter that runs before retrieval, not after generation. The following sketch shows the core of a gateway: resolve the caller's legitimate interest from the roster, scope the query, drop fields the purpose does not need, and log the disclosure.
from dataclasses import dataclass
from datetime import datetime, timezone
PURPOSE_FIELDS = {
"tutoring": {"reading_level", "current_courses", "accommodations"},
"advising": {"transcript", "degree_audit", "holds"},
}
@dataclass
class Caller:
user_id: str
role: str # "teacher", "counselor", "student", "parent"
district: str
def allowed_students(caller, roster):
"""Legitimate educational interest, resolved from the district roster."""
if caller.role == "teacher":
return roster.students_in_sections_taught_by(caller.user_id)
if caller.role == "counselor":
return roster.caseload(caller.user_id)
if caller.role in ("student", "parent"):
return roster.records_holder_for(caller.user_id) # handles the age-18 transfer
return set()
def fetch_context(caller, student_id, purpose, roster, store, log):
if student_id not in allowed_students(caller, roster):
log.denied(caller, student_id, purpose)
raise PermissionError("no legitimate educational interest")
fields = PURPOSE_FIELDS[purpose]
record = store.get(caller.district, student_id, fields=fields) # per-district index
log.disclosed(
at=datetime.now(timezone.utc), caller=caller.user_id, student=student_id,
purpose=purpose, fields=sorted(fields), recipient="vendor:tutor-app",
)
return recordThree details carry the weight. The roster is the district's, so the vendor never decides who has an interest. The field list is tied to a purpose, so a tutoring prompt cannot pull disciplinary history. And the store is keyed by district first, so a retrieval bug cannot cross tenants. Note that 99.32 requires a record of disclosures for most outside parties but exempts disclosures to school officials; log them anyway, because the log is how you prove the reasonable-methods control works and how you investigate an incident.
Worked example: a district reading tutor
Take a district that deploys a reading tutor for grades 6 to 12. A ninth-grade English teacher opens the assistant and types: summarise the accommodations for the student in third period who uses text-to-speech.
The gateway resolves the teacher's sections from the roster and finds 31 students in third period. The teacher has a legitimate interest in all of them, but the assistant still should not answer by matching the description: a fuzzy match can pick the wrong student, and the disclosure log needs an exact student ID. So it asks the teacher to choose a named student from their own roster. The teacher picks one. The gateway checks that the student is in her section, fetches only the accommodations field for the tutoring purpose, writes a log entry, and passes a minimal context to the vendor app, which calls the model with retention disabled. The answer lists the accommodations and nothing from the student's evaluation report, because that field is not in the tutoring purpose.
Now change one fact: the student turns 18 in March. Rights transfer to the student, so the parent portal can no longer show the tutor transcripts by default. FERPA does let a school disclose to parents of a dependent student for tax purposes, but that is a decision the district records, not a default the vendor guesses. The records_holder_for lookup in the code above is where this lives, and it must read a date, not a grade level.
Finally, the vendor proposes using the year's transcripts to fine-tune a better tutor for all customers. Under the contract terms above the answer is no. A de-identified evaluation set is possible, but free-text essays routinely contain names, teachers, towns and family details, and a set of rare accommodations can identify a student in a small school. The regulation also counts information as identifying when the recipient is likely to know who it describes, so a model that answers narrow questions about its training data can re-identify a student even when no name was kept. The district would need to document why no student is reasonably identifiable, which for raw student writing is usually not achievable without heavy manual review.
Failure modes
- Retrieval scoped after generation. The model sees the whole school, and an output filter tries to hide what it should never have read. Prompt injection or a clever question defeats it.
- Shared embedding index. One vector store across districts with a metadata filter. One missing filter clause leaks across customers.
- Provider defaults. The model API retains inputs for abuse monitoring or allows training by default, and nobody checked the account setting.
- Directory opt-outs ignored. A student whose family opted out of directory information appears by name in a generated class newsletter or public honour-roll post.
- Transcripts outside the record system. Chat logs live in an observability tool, cannot be exported per student, and are kept forever.
- Age-18 transfer missed. Parent access is driven by grade level rather than date of birth or postsecondary enrolment.
Trade-offs and the laws around FERPA
Tighter purpose scoping makes answers narrower; teachers will ask why the assistant cannot see attendance when they are discussing reading progress. The fix is to define purposes with teachers rather than widen the field list silently. Per-district indexes cost more than a shared one, but they turn a cross-tenant leak from a filter bug into an impossibility. Zero-retention model endpoints may limit which providers and features you can use. And de-identification for model improvement is expensive to do honestly; many vendors will find it cheaper to use synthetic data or ask for opt-in consent.
FERPA is also only the floor. COPPA governs online services collecting data from children under 13. The Protection of Pupil Rights Amendment covers surveys on sensitive topics. Special-education records carry IDEA confidentiality rules. Many states add student privacy statutes for operators, such as California's SOPIPA, which limits K-12 operators' use of student data for advertising and profiling. A design that meets the strictest of these in your market is usually simpler than one tuned per state.
Related reading
For the mechanics behind these controls, read how LLMs leak personal data, tenant isolation for LLM systems, third-party LLM risk and audit logging for LLM applications. For a comparison with a consumer privacy regime, see CCPA and LLM applications.
What to do next
- Inventory every field the assistant can reach and tag each with a purpose; remove fields no purpose needs.
- Move legitimate-interest checks to the gateway, driven by the district roster, before any retrieval.
- Split vector stores by district and prove isolation with a test that queries across tenants.
- Confirm the model provider's retention and training settings in writing and name it as a subprocessor.
- Add contract terms for no training, deletion at end, export for inspection requests and incident notice.
- Log every disclosure with caller, student, purpose and fields, and make transcripts exportable per student.
- Implement the age-18 and postsecondary rights transfer from dates, and honour directory opt-outs everywhere.
- Handle targeted requests by forcing an explicit student choice from the caller's own roster.