Skip to main content

FERPA Data Flow & PII Inventory

Last updated: March 25, 2026

1. System Architecture Overview

The following diagram illustrates Ludwitt's system architecture and the boundaries between data processors. All communication occurs over TLS 1.3 encrypted connections. Anthropic (AI provider) receives no PII, and Stripe (payments) receives no student data.

                                    ┌─────────────────────────────────────┐
                                    │         DATA PROCESSORS             │
                                    │      (Sub-Processor Boundary)       │
                                    └─────────────────────────────────────┘

  ┌──────────┐    TLS 1.3     ┌──────────┐    TLS 1.3    ┌───────────────┐
  │ Student  │ ──────────────►│  Vercel   │─────────────►│  Google Cloud  │
  │ Browser  │◄──────────────│  Edge CDN │◄─────────────│  (Firebase)    │
  └──────────┘               └────┬─────┘              │                │
                                   │                    │  ┌───────────┐ │
                                   │                    │  │ Firestore │ │
                              ┌────▼──────┐            │  │ us-central│ │
                              │ Next.js   │            │  │           │ │
                              │ API Routes│───────────►│  │ Auth      │ │
                              │ (Serverless│◄──────────│  │           │ │
                              │ Functions)│            │  │ Storage   │ │
                              └──┬────┬───┘            │  └───────────┘ │
                                 │    │                └───────────────┘
                    ┌────────────┘    └──────────────┐
                    │                                │
              ┌─────▼──────┐                  ┌──────▼──────┐
              │  Anthropic  │                  │   Stripe    │
              │  Claude API │                  │  Payments   │
              │             │                  │             │
              │  NO PII     │                  │  NO student │
              │  RECEIVED   │                  │  data       │
              └─────────────┘                  └─────────────┘

2. Data Flow: Student Authentication (SSO/SAML)

When a student authenticates via their university's Single Sign-On (SSO) system, the following data flow occurs. The university password never leaves the identity provider.

┌──────────┐     ┌──────────────┐     ┌─────────────────┐     ┌──────────────┐
│ Student  │     │ University   │     │   Ludwitt API    │     │   Firebase   │
│ Browser  │     │ IdP (SAML)   │     │   (Vercel)       │     │   Auth       │
└────┬─────┘     └──────┬───────┘     └────────┬─────────┘     └──────┬───────┘
     │                  │                       │                      │
     │  1. Click SSO    │                       │                      │
     │  login           │                       │                      │
     │─────────────────────────────────────────►│                      │
     │                  │                       │                      │
     │  2. Redirect to  │                       │                      │
     │  university IdP  │                       │                      │
     │◄────────────────────────────────────────│                      │
     │                  │                       │                      │
     │  3. Authenticate │                       │                      │
     │  with university │                       │                      │
     │  credentials     │                       │                      │
     │─────────────────►│                       │                      │
     │                  │                       │                      │
     │  4. SAML         │  5. Validate SAML     │                      │
     │  assertion       │  assertion            │                      │
     │◄─────────────────│──────────────────────►│                      │
     │                  │                       │                      │
     │                  │                       │  6. Create/lookup     │
     │                  │                       │  Firebase user        │
     │                  │                       │─────────────────────►│
     │                  │                       │                      │
     │                  │                       │  7. Session token     │
     │  8. Authenticated│                       │◄─────────────────────│
     │  session         │                       │                      │
     │◄────────────────────────────────────────│                      │
CategoryDetails
PII TransmittedEmail, display name (from SAML assertion)
PII StoredEmail, display name, org membership (in Firebase Auth + Firestore)
PII NOT StoredUniversity password (never leaves the identity provider)

3. Data Flow: AI-Powered Problem Grading

When a student submits an answer for AI grading, all PII is stripped at the API route layer before any data reaches the AI provider. The following sequence demonstrates this process step by step.

┌──────────┐          ┌─────────────────┐          ┌──────────────┐
│ Student  │          │   Ludwitt API    │          │  Anthropic   │
│ Browser  │          │   (Vercel)       │          │  Claude API  │
└────┬─────┘          └────────┬─────────┘          └──────┬───────┘
     │                         │                           │
     │  1. Submit answer       │                           │
     │  {answer: "x=5",        │                           │
     │   problemId: "abc123"}  │                           │
     │────────────────────────►│                           │
     │                         │                           │
     │                         │  2. Authenticate user     │
     │                         │  (Firebase token → userId)│
     │                         │                           │
     │                         │  3. Load problem text     │
     │                         │  from Firestore           │
     │                         │                           │
     │                         │  4. Build prompt:         │
     │                         │  ┌─────────────────────┐  │
     │                         │  │ "Check if this      │  │
     │                         │  │ answer is correct:  │  │
     │                         │  │ Problem: 3x+5=20   │  │
     │                         │  │ Answer: x=5"        │  │
     │                         │  │                     │  │
     │                         │  │ NO NAME             │  │
     │                         │  │ NO EMAIL            │  │
     │                         │  │ NO USER ID          │  │
     │                         │  └─────────────────────┘  │
     │                         │                           │
     │                         │  5. API call (content     │
     │                         │  only, no PII)            │
     │                         │──────────────────────────►│
     │                         │                           │
     │                         │  6. Response: correct,    │
     │                         │  explanation              │
     │                         │◄──────────────────────────│
     │                         │                           │
     │                         │  7. Log credit usage      │
     │                         │  (userId + token count,   │
     │                         │   NOT prompt content)     │
     │                         │                           │
     │                         │  8. Update progress       │
     │                         │  (accuracy, XP, streak)   │
     │                         │                           │
     │  9. Return feedback     │                           │
     │◄────────────────────────│                           │
CategoryDetails
PII Transmitted to AnthropicNONE
Data Transmitted to AnthropicProblem text + student answer (educational content only)
Data StoredProgress metrics (accuracy, XP) linked to userId in Firestore

4. Data Flow: Institutional Analytics Access

When an institutional administrator accesses student data, FERPA audit logging captures the access event. All data access is scoped to the administrator's organization.

┌──────────────┐     ┌─────────────────┐     ┌──────────────┐     ┌──────────┐
│ Institution  │     │   Ludwitt API    │     │  Firestore   │     │  Audit   │
│ Admin        │     │   (Vercel)       │     │              │     │  Log     │
└──────┬───────┘     └────────┬─────────┘     └──────┬───────┘     └────┬─────┘
       │                      │                      │                   │
       │  1. Request student  │                      │                   │
       │  analytics           │                      │                   │
       │─────────────────────►│                      │                   │
       │                      │                      │                   │
       │                      │  2. Authenticate     │                   │
       │                      │  (verify org-admin   │                   │
       │                      │   or instructor role)│                   │
       │                      │                      │                   │
       │                      │  3. Verify org       │                   │
       │                      │  membership          │                   │
       │                      │─────────────────────►│                   │
       │                      │                      │                   │
       │                      │  4. FERPA AUDIT LOG  │                   │
       │                      │  Record: who accessed│                   │
       │                      │  what student data,  │                   │
       │                      │  when, from where    │                   │
       │                      │──────────────────────────────────────────►
       │                      │                      │                   │
       │                      │  5. Query student    │                   │
       │                      │  progress (scoped    │                   │
       │                      │  to org only)        │                   │
       │                      │─────────────────────►│                   │
       │                      │                      │                   │
       │  6. Return analytics │                      │                   │
       │  (aggregate + per-   │                      │                   │
       │  student metrics)    │                      │                   │
       │◄─────────────────────│                      │                   │

FERPA Audit Log Entry Contains:

  • accessedBy: admin userId
  • accessedByRole: "org-admin" or "instructor"
  • resourceType: "student_grades" or "basics_progress"
  • action: "read"
  • targetUserId: student whose data was accessed
  • ipAddress: admin's IP address
  • timestamp: ISO 8601 format
  • organizationId: scoping context

5. Complete PII Inventory

The following table provides a comprehensive inventory of every PII field stored by Ludwitt, its storage location, encryption status, access controls, and whether it is sent to the AI provider.

PII FieldStorage LocationEncryptedAccess ControlSent to AI
EmailFirebase Auth + Firestore usersTLS in transit, AES-256 at restOwner + org-adminNever
Display nameFirestore usersAES-256 at restOwner + org-adminNever
Date of birthFirestore usersAES-256-GCM (application-level)Owner onlyNever
Phone numberFirebase Auth (MFA only)AES-256 at restOwner onlyNever
Profile photoFirebase StorageAES-256 at restOwner-controlled visibilityNever
Learning progressFirestore subcollectionsAES-256 at restOwner + org-admin/instructorNever
Problem answersIn-memory during gradingTLS in transitTransient, not persistedContent only (no PII)
Payment infoStripe (not in Ludwitt)PCI-DSS compliantStripe controlsNever

6. Where Student PII Does NOT Live

The following systems explicitly do not contain student PII. This is verified through architectural controls, not just policy.

SystemPII PresentReason
Anthropic Claude APINoOnly educational content sent, no identifiers
Vercel function logsMinimalRequest metadata only, no request bodies
Sentry error reportsNoPII scrubbed before submission
Daily.coNoVideo streams only, no persistent storage
GitHub/CINoSource code only, no user data

7. Sub-Processor Registry

All sub-processors are disclosed in the Data Processing Agreement. Changes to sub-processors are communicated to institutional customers 30 days in advance.

Sub-ProcessorServiceData ReceivedLocationSOC 2DPA
Google Cloud / FirebaseDatabase, Auth, StorageAll platform dataus-central1 (USA)Type IIYes
VercelHosting, CDN, ServerlessRequest routing, function executionUSAType IIYes
AnthropicAI grading and feedbackEducational content only (no PII)USAType IIYes
StripePayment processingPayment information onlyUSAType I & IIYes
Daily.coVideo study roomsAudio/video streams (ephemeral)USAType IIYes
SentryError monitoringError metadata (no PII)USAType IIYes

8. Cross-Border Data Transfers

Ludwitt does not operate data centers outside the United States. All data processing occurs within US-based infrastructure provided by Google Cloud and Vercel.

ScenarioData FlowSafeguard
US studentsData stays in US (us-central1)No cross-border transfer
EU students (GDPR)Data stored in USStandard Contractual Clauses in DPA
International studentsData stored in USDPA + Privacy Policy disclosure

9. Data Access Matrix

The following matrix defines what data each role can access. All access beyond a student's own data is FERPA audit logged.

RoleStudent's Own DataOther Students' DataOrg AnalyticsPlatform Admin
StudentFull read/writeNoneNoneNone
InstructorRead (own org only)Read (own org only)Read (own org)None
Org AdminRead (own org only)Read (own org only)Full (own org)None
Platform AdminRead (all)Read (all)Read (all)Full

FERPA Audit Logging: All access beyond "Student's own data" is recorded in an immutable, append-only audit log. Audit logs are retained for 3 years and include the accessor's identity, role, IP address, timestamp, and the specific data accessed.

For FERPA compliance inquiries, contact dpo@ludwitt.com.