Privacy by Design — 2026

Security is a chokepoint strategy

We don't rely on every feature remembering to scrub PII. We build a single shared chokepoint that every AI call must pass through — and we log everything.

Seven chokepoints you can audit

All AI and data access flows through these seven layers. School admins see logs for their own pupils; super_admins see only pseudonymised metadata and must invoke an audited break-glass procedure (with a written reason and parental consent for under-13s) to read identifying data.

AI PII chokepoint (aiSafeFetch)

Every single LLM call — without exception — passes through aiSafeFetch. CPR, NHS numbers, emails and pupil names are scrubbed or aliased to 'Pupil A' before the prompt leaves our serverless funktion. If real PII is detected the call is blocked with HTTP 422 — it never delivers pupil data to a third party.

AI prompt audit (180-day retention)

The ai_prompt_audit table logs function, model, hashed user id, count of blocked PII hits and affected pupil ids. A daily pg_cron deletes everything older than 180 days. School admins can pull audits for their own pupils; super_admins see only pseudonymised metadata — never prompt content with PII.

Default-deny PII for our own staff

Skoleelev staff (incl. the platform administrator) see only a pseudonymised user directory by default: UUID, role and school prefix — no names, no emails. To view identifying data, a break-glass the system must be invoked with a written reason (min. 20 chars), a parental-consent check for under-13s, and the parent/DPO is automatically notified (child_data_breakglass_notice). Access expires at end of session.

Zero-retention at OpenAI & Gemini

We always send store:false to OpenAI and use the hashed pseudo-user as identifier. Neither OpenAI nor Google retain prompts or responses for training under our enterprise DPA.

Sensitive access log

Every read of psychologist journals, health data, safeguarding cases and SEN accommodations passes through secure server functions that log purpose, user and scope. The school's DPO can pull the audit quarterly.

Parental consent for under-13s

child_data_consents handles 6 consent types (AI personalisation, image/audio capture, leaderboards, peer sharing, marketing, external export). useChildAgeGate blocks AI personalisation until the parent confirms via /parent/children/:id/consents.

Security-invoker views & access control

All views are built with security_invoker=true, so Row-Level Security is enforced as if the user read directly. Roles (8) and scopes are centrally configured — no view can slip past access control.

Security baseline

AES-256 at rest, TLS 1.3 in transit

EU hosting (Falkenstein, DE) + cross-region failover + S3 backup in Helsinki, FI (30 days)

MFA mandatory for admin roles

Private buckets with signed links

24-month admin_audit_log + daily pg_cron rotation

Breach notice < 24h to the school (GDPR Art. 33)

Continuous automated security and dependency scanning (Aikido Security) + external penetration tests

Hetzner’s data centres (fsn1, nbg1, hel1) are ISO 27001 certified and BSI C5 attested. Elestio is ISO 27001 certified.

Independent auditor’s statement under ISAE 3000 (type 2), with the first reporting period ending no later than 31 December 2027, renewed annually thereafter.

For the DPO

Need the documentation?

We deliver the DPIA, Data Processing Agreement and Privacy by Design declaration (Art. 25) together with the contract.