Children's privacy (COPPA)
Status: ⚠️ Compliance — engineering substrate BUILT; legal VPC-method-sufficiency review DEFERRED (product ships for solo self-testing; hard legal gate before public launch)
Scope
COPPA requires verifiable parental consent before collecting personal information from children under 13. Rewhaven must age-gate account creation, obtain and record explicit parental consent, minimize data collected for minors, and provide a deletion path. This is the highest-priority compliance item given the product's audience. No behavioral advertising targeting minors under any circumstances.
Shipped mechanism (COPPA Layer 1 + 2)
Both the parent-creates-child-member path and the child self-signup + consent gate have shipped. The engineering substrate covers:
Schema + RLS
MemberStatus.pendingConsent— a child who has linked their own login but whose household has not yet completed VPC sits inhousehold_memberswithstatus='pendingConsent',kind='child',consent_state='none'. RLS is frozen for unconsented children: they cannot read or write household data until a parent approves.- SECURITY DEFINER child-link RPC — the child-signup flow calls a server-side RPC to link the child's auth user into the household member row without exposing parent data to the unauthenticated child session.
- Parent code-issuance UI (L1-T12): a parent generates a short-lived link/code that the child uses to join the household.
- Household approval surface (VPC →
captureConsent): a parent reviews and explicitly approves the pending child membership. decline_childRPC: parent rejects, hard-deletes the child member row and its auth user.- Child-signup + waiting app screens: the child sees an in-app waiting state until the parent approves or declines.
Expiry + orphan cleanup
expire-pending-childrenEdge Function (infra/supabase/functions/expire-pending-children/index.ts, commit a0c35f8) — scheduled reaper. DeletespendingConsentchild members whose VPC window has expired (7 days, per COPPA delete-if-no-consent requirement). Also sweeps orphaned child auth users whose member row was already removed (step-2 failure rollback gap). Invoked by scheduler only; guarded by shared secret (x-cron-secret). Deployed withverify_jwt OFF.- Expiry index:
infra/supabase/migrations/20260713000100_pending_child_expiry_index.sql
Migrations
| File | What it does |
|---|---|
20260712000100_member_status_pending_consent.sql | Widens household_members_status_check to admit 'pendingConsent' |
20260712000200_link_child_rpc.sql | SECURITY DEFINER RPC that links a child auth user to an existing shadow member row |
20260712000300_child_consent_rls_freeze.sql | RLS policies that block unconsented children from reading/writing household data |
20260712000400_decline_child_rpc.sql | Parent-side decline RPC — hard-deletes the pending child member and auth user |
20260712000500_child_link_hardening.sql | Additional authz hardening for the link flow |
20260713000100_pending_child_expiry_index.sql | Index on (status, created_at) for the scheduled expiry sweep |
Residual open item
The legal VPC-method-sufficiency review is still deferred. The current mechanism (parent code-issuance + in-app approval) is the product-engineering implementation. Whether it satisfies the COPPA "verifiable" bar (as distinct from the FTC's enumerated methods such as credit-card micro-charge or signed consent form) requires legal sign-off before public go-live. Product ships for solo self-testing under this deferred gate.
Relationship
Personas — child members are the highest-risk group; consent must be parent-granted.