Privacy & Safety Controls
SisterShield handles sensitive subject matter (technology-facilitated violence against women and girls) and serves a potentially vulnerable audience. Privacy and safety are core design priorities, not afterthoughts.
Data Lifecycle
What Data Is Collected
| Data Type | Purpose | Storage Location |
|---|---|---|
| User profile (name, email, hashed password, role, locale) | Authentication and personalization | PostgreSQL User table |
| Course progress (visited passages, time spent, quiz scores) | Learning tracking and completion | PostgreSQL Progress table |
| Submissions (uploaded Twine files, metadata) | Student work submission and review | PostgreSQL Submission table + local filesystem |
| Course content (Twee source, built HTML, images) | Educational content delivery | PostgreSQL Course table + local filesystem |
| Pilot requests (email, organization, name) | Program interest tracking | PostgreSQL PilotRequest table |
| Teacher access logs (action, resource, timestamp) | Audit trail | PostgreSQL TeacherAccessLog table |
| Analytics events (quick_exit_used, resources_opened) | Safety feature usage tracking | Client-side only (via trackEvent()) |
Where Data Is Stored
- Database: PostgreSQL, accessed exclusively through Prisma ORM. No raw SQL queries.
- Files: Local filesystem under a storage directory. The storage abstraction in
src/lib/storage/is designed for future migration to S3 or MinIO. - Client-side:
sessionStorageis used for temporary UI state. It is cleared on Quick Exit.
Data Retention
- User data persists until the account is deleted (TODO: implement account deletion API).
- Progress data is retained indefinitely for learning analytics.
- Session tokens (JWT) expire after 30 days.
- No data is shared with third parties beyond the LLM API calls described in the AI section.
Authentication
JWT Strategy
SisterShield uses NextAuth 4.24.11 with a JWT session strategy (not database sessions for request authentication).
- Provider: Credentials (email + password).
- Password hashing: bcrypt with cost factor 10 (
bcryptjs). - JWT payload:
id,role(STUDENT/TEACHER/ADMIN),preferredLocale. - Token lifespan: 30 days.
- Cookie:
next-auth.session-token, HttpOnly, SameSite=Lax. AutomaticallySecureon HTTPS.
Role-Based Access
API routes check session.user.role before executing sensitive operations:
- Public: Registration, login, landing page, hero evidence (read), pilot requests.
- Authenticated: Course browsing, course play, progress tracking, submission creation.
- Teacher+: Course creation, editing, publishing, AI generation, translation, submission review.
- Admin: All teacher capabilities, evidence management, user management (TODO).
Privacy Controls
Quick Exit
The QuickExit component (src/components/safety/quick-exit.tsx) provides an emergency escape mechanism.
Behavior:
- Triggered by clicking the exit button or pressing Escape (when no dialog is open).
- Calls
trackEvent('quick_exit_used')for analytics. - Clears
sessionStorageto remove any sensitive UI state. - Calls
window.location.replace('https://weather.com'), which navigates away and replaces the current history entry so the back button does not return to SisterShield.
Limitations:
- JWT cookie is not cleared (this is intentional — clearing it would require a server round-trip, which delays the exit). The cookie is HttpOnly, so it is not accessible to JavaScript.
- Browser tabs or windows showing SisterShield content are not closed (the Quick Exit operates within its own tab).
Security Headers
Configured in next.config.js, applied to all routes:
| Header | Value | Purpose |
|---|---|---|
X-Frame-Options | SAMEORIGIN | Prevents clickjacking by blocking cross-origin iframe embedding |
X-Content-Type-Options | nosniff | Prevents MIME-type sniffing |
Referrer-Policy | strict-origin-when-cross-origin | Limits referrer information leaked to external sites |
HTTPS
In production, the application should be served over HTTPS. NextAuth automatically sets the Secure cookie flag when the NEXTAUTH_URL uses https://.
AI Safety
Image Generation Constraints
The image generation system (src/lib/llm/generate-image-prompts.ts) enforces strict safety rules in the LLM prompt:
- No minors: All characters must be depicted as young adults (18-22 years old), even if the story describes younger characters. The prompt explicitly states: “NEVER depict minors, children, or teenagers.”
- No violence: Images must not contain violence, weapons, nudity, drugs, horror, or inappropriate content.
- No threatening content: When illustrating cyberbullying or online threats, the prompt requires showing the character’s emotional response or safe action, never the threatening content itself.
- Modest clothing: Characters wear casual, modest clothing appropriate for a college campus.
- No text in images: Prompts specify that images must not contain text, words, letters, or UI elements.
Content Generation Safety
The story generation prompt (src/lib/llm/generate-story.ts) includes:
- Structured output format (Twee 3) that constrains the LLM’s output.
- Mandatory safety passages: every story ends with real crisis resources (Korean hotlines, international organizations).
- No victim-blaming: dangerous choices lead to educational Risk Analysis passages, not punishment.
- Recovery paths: every wrong choice includes a “Let me think about this again” retry link.
Data Sent to LLM Providers
- Course content (Twee source) is sent to the configured LLM provider for generation, translation, and error fixing.
- No user PII (names, emails, passwords) is sent to LLM providers.
- Image prompts are sent to OpenAI for DALL-E 3 generation.
Data Minimization
- Minimal PII: Only email, name, and hashed password are stored. No phone numbers, addresses, or demographic data.
- No unnecessary tracking: Progress tracking captures passage visits and time for educational purposes only.
- Audit logging: Teacher access logs record only the action type, resource ID, and timestamp — not the content viewed.
GDPR/Privacy Considerations
| Requirement | Current Status |
|---|---|
| Right to access personal data | TODO: Implement data export endpoint |
| Right to deletion | TODO: Implement account deletion with cascade |
| Data processing consent | TODO: Add consent flow during registration |
| Privacy policy | TODO: Draft and publish privacy policy page |
| Cookie consent banner | TODO: Implement for non-essential cookies (currently only session cookie) |
| Data breach notification | TODO: Define incident response procedure |
Digital Ethics Audit: TF-VAWG-Specific Risk Assessment
SisterShield operates in a high-stakes domain where standard privacy practices are insufficient. This section documents a TF-VAWG-specific risk assessment that goes beyond conventional data protection to address the unique threats faced by users who may be experiencing technology-facilitated violence.
Risk Matrix
| # | Risk | Severity | Likelihood | Mitigation Feature | Status |
|---|---|---|---|---|---|
| 1 | Data leak reveals victim is learning about abuse | Critical | Medium | Minimal PII, no demographic data, neutral app title | Implemented |
| 2 | Re-traumatization through content | High | Medium | Trauma-informed design, calm color system, supportive language, content warnings | Implemented |
| 3 | Abuser discovers victim is using the platform | Critical | High | Quick Exit (Escape key), browser history replacement, neutral redirect destination | Implemented |
| 4 | Victim-blaming in AI-generated content | High | Low | Dangerous Choice Architecture with mandatory recovery paths, no punishment framing | Implemented |
| 5 | Harmful or inappropriate AI-generated content | High | Low | Structured output format, image safety constraints, teacher review before publication | Implemented |
| 6 | Progress data exposes sensitive topic engagement | Medium | Medium | Progress tracks passage visits only (no choice content), no exportable reports for students | Implemented |
| 7 | Browser history reveals platform usage | High | High | Quick Exit replaces history entry; neutral destination (weather.com) | Implemented |
| 8 | Push notifications reveal sensitive content | High | Low | No push notifications implemented; no email notifications about course content | By design |
| 9 | Shared device exposes session | Medium | Medium | sessionStorage cleared on Quick Exit; JWT cookie is HttpOnly (not accessible to scripts) | Implemented |
| 10 | LLM provider retains generated content | Medium | Medium | No user PII sent to LLM; only course content (Twee source) and translation requests | Implemented |
Quick Exit as Digital Safety Feature
The Quick Exit feature is not merely a convenience — it is a digital safety feature designed for users in potentially dangerous situations. The design reflects six specific considerations:
- Sub-second exit: The
window.location.replace()call executes immediately. No confirmation dialog, no animation, no delay. When a user needs to leave, milliseconds matter. - History replacement: Using
replace()instead ofassign()ensures the back button does not return to SisterShield. An abuser checking the victim’s browser cannot use the back button to discover what they were viewing. - Neutral destination: The redirect target (weather.com) is a plausible, innocuous website. It does not suggest the user was doing anything sensitive.
- State clearing:
sessionStorageis cleared before navigation to remove any cached UI state (open dialogs, form inputs, navigation history within the app). - Keyboard trigger: The Escape key binding ensures users can exit without moving the mouse to a specific button — useful if someone enters the room unexpectedly.
- Dialog guard: The Quick Exit does not trigger when a dialog, menu, or listbox overlay is open (checked via
[data-state="open"]). This prevents accidental exits during normal interaction while ensuring intentional exits always work.
Trauma-Informed Content Safety
AI-generated educational content passes through five safety layers before reaching students:
- Prompt-level constraints: The story generation prompt prohibits graphic violence, victim-blaming language, and content that depicts the threatening behavior itself (only emotional responses and safe actions).
- Structured output format: Twee 3 format constrains the LLM to produce navigable, link-based content rather than free-form text that could contain harmful passages.
- Programmatic validation: The Twee parser checks for structural integrity (no dead links, no orphan passages, no duplicate passage names) before content is stored.
- Teacher review gate: All AI-generated stories are saved as drafts. A teacher must explicitly review and publish before any student can access the content.
- Mandatory safety passages: Every generated story must include crisis resources (Korean Women’s Emergency Hotline 1366, international organizations) and recovery paths from dangerous choices.
Data Minimization as Protection
For TF-VAWG platform users, data minimization is not just a privacy best practice — it is a safety measure:
- No demographic data collected: The platform stores only email, name, hashed password, role, and locale preference. No age, gender, location, or relationship status is requested. An abuser who gains access to the database learns nothing about the victim beyond their email.
- No social features: There are no friend lists, group chats, forums, or shared progress features. A user’s presence on the platform is invisible to other users. This prevents abusers from discovering victims through the platform itself.
- No choice content tracking: Progress data records which passages were visited and time spent, but does not record which choices the user made within a story. This means even with database access, no one can determine whether a user identified with a victim scenario or which coping strategies they practiced.
Safety Component Reference
QuickExit (src/components/safety/quick-exit.tsx)
- Trigger: Button click or Escape key.
- Guard: Does not trigger if a dialog, menu, or listbox overlay is open (checks
[data-state="open"]). - Styling: Uses
safety-exitandsafety-exit-borderdesign tokens (red). - Accessibility:
aria-label,titletooltip, minimum touch target (44x44px).
GetHelp (src/components/safety/get-help.tsx)
- Trigger: Button click opens a Dialog.
- Content: Region-selectable resources (Korea / International).
- Korea resources: Women’s Emergency Hotline (1366), Digital Sexual Violence Counseling (02-735-8994), Police (112).
- International resources: Cyber Civil Rights Initiative, UN Women, Internet Watch Foundation.
- Accessibility: Emergency warning banner, phone links (
tel:), external links withnoopener noreferrer. - Analytics: Tracks
resources_openedevent when dialog opens.