Data residency
Helix is a UK-built vendor selling to UK-regulated banks and fintechs. The business plan (§1, §3) commits to keeping behavioural data on-device and keeping all server-side processing inside the UK / EEA. This document is the formal answer banks ask for during vendor due-diligence (CAIQ §DSI, SIG §H).
What we process server-side
The control plane stores only the following:
| Data | Source | Retention |
|---|---|---|
| Aggregated risk events (score + signal weights, no raw biometric) | Bank's mobile app via SDK → REST | 13 months rolling |
| Audit log entries (hash-chained, append-only) | Control plane actions | 7 years |
| API key hashes (SHA-256) | Issued in-app | Until revoked |
| Webhook delivery records (status code, payload SHA-256) | Outbound delivery | 13 months |
| CSP violation reports | Browser → /api/public/csp-report | 90 days |
| Profiles, tenants, user roles | Sign-up flow | Lifetime of account |
What we never store server-side: keystroke timings, accelerometer samples, swipe coordinates, touch pressure, gyroscope traces, screen content, contact list, location, or any raw biometric signal. These stay on the device in the iOS/Android SDK's encrypted enclave (Android Keystore / iOS Secure Enclave) and are discarded after each scoring window.
Where the data lives
| Layer | Provider | Region | UK-adequacy |
|---|---|---|---|
| Postgres + auth + storage | Supabase (managed by Lovable Cloud) | EU (Ireland — eu-west-1) | Yes (UK-EU adequacy decision, June 2021) |
| Static assets / SSR | Cloudflare Workers — EU + UK PoPs | EEA + UK | Yes |
| Email (transactional) | Resend (EU region) | EEA | Yes |
No data flows to US-hosted infrastructure. Lovable's edge proxy is a pass-through; we do not enable any US-only Workers binding.
Raw behavioural telemetry never leaves the device. The ingestion endpoint
(POST /api/public/v1/events) enforces a strict allow-list: signals may
only contain keystroke_cadence, touch_pressure, device_motion and
swipe_dynamics, each a single derived score between 0 and 1. Any other
key, raw sample array, nested object or string is rejected with HTTP 400
and is never stored.
Verifying region
- Lovable Cloud → Connectors → Lovable Cloud → Database settings —
confirm region reads
eu-west-1. dig +short project--<id>.lovable.app— Cloudflare resolves to anycast; PoP selection is determined by client geo.- Run from a UK office:
curl -sI https://helixsecure.co.uk/ | grep -i 'cf-ray' # cf-ray suffix encodes the colo (e.g. LHR for London).
Cross-border transfers
There are none in production. If a future feature requires a US-hosted sub-processor (e.g. an LLM provider), it must:
- Be added to a sub-processor list published at
/legal/subprocessors. - Operate under SCCs + a UK Addendum (or successor mechanism).
- Be flagged in this document with the data categories transferred.
GDPR / UK-GDPR posture
- Lawful basis: legitimate interest (fraud prevention) for risk events; contract for control-plane account data.
- Data subject rights: handled by the bank as data controller; Helix is processor.
- DPIA: Helix provides a template DPIA Annex to every customer in the onboarding pack.
- ICO registration: Helix Security Limited is registered with the
UK ICO (registration number to be added on incorporation — see
docs/deployment-checklist.md).
Changing the region
Migrating Postgres to a different region is destructive and requires:
- Customer notification ≥ 30 days in advance.
- Updated DPA addendum.
- Update to this document and the public sub-processor list.
Review of stored risk_events.signals (24 Sep 2026)
All 614 rows (13 tenants, 16 May – 6 Jun 2026) were inspected. Every row is seeded demo data; no customer SDK has written production events.
- No raw telemetry found: no arrays, sample streams, coordinates, keystroke timings, accelerometer/gyro traces or strings of samples.
- Non-allow-listed keys found:
device_id(pseudonymous device identifier) andip_countryin all 614 rows, and the four signal scores stored on a 0–100 scale instead of 0–1. - Needed? No. Helix scoring uses only the four derived scores; a persistent device identifier is not required and increases re-identification risk.
- Action taken:
device_idandip_countrywere deleted from every row and the scores rescaled to 0–1. No copy was kept (seed data, no retention need). Post-clean check: 0 rows contain any key outside the allow-list. - Retention going forward: risk events 13 months rolling; the ingestion contract makes it impossible to store non-allow-listed keys.
Ingestion contract (enforced)
Accepted top-level fields only: score (int 0–100), session_id
(opaque, ≤128 chars of A-Za-z0-9_-:.), signals, model_version,
sdk_version (opaque ids ≤64 chars), occurred_at (ISO-8601). Any other
key → HTTP 400. Tests: src/routes/api/public/v1/__tests__/events-privacy-contract.test.ts.