Data protection, the long version.
1. Controller
Flex Technologies Group Ltd, company number 15882806, 850 Green Lanes, London N21 2RS. Contact for data protection matters: admin@flexgroup.dev. We don't meet the threshold for a mandatory Data Protection Officer but the founder holds the role in practice and every request lands with a named person.
2. Why a DPIA
The app processes special category data (the fact of a sexual health test and what it covered) about a large number of people, on a new kind of service, so a DPIA is mandatory under UK GDPR Article 35. We did one before the first real user and we redo it when the processing changes. The full document is available to partners on request. This is the summary.
3. What we process, and on what basis
| Data | Purpose | Lawful basis (Art. 6) | Condition (Art. 9) | Retention |
|---|---|---|---|---|
| Phone number | Account and sign-in by one-time code | Contract, 6(1)(b) | n/a | Until account deletion. The app database holds only an HMAC-SHA-256 hash with a server-side pepper; the plain number lives in the sign-in table. |
| Name as printed on photo ID | Match the test result to the account holder | Contract, 6(1)(b) | n/a | Until account deletion. |
| Test date and panel | Issue and display a 90-day green tick | Consent, 6(1)(a) | Explicit consent, 9(2)(a), given at upload and withdrawn by deleting the tick or account | Until replaced by a newer result or the account is deleted. After 90 days it no longer produces a tick. |
| Result and ID photographs | Automated extraction plus human review where needed | Consent, 6(1)(a) | Explicit consent, 9(2)(a) | Deleted on decision. Automatic decisions take seconds; anything sent to a person is normally decided the same day and the photos go the moment it is. |
| Block and invite lists | User control over who can see the tick | Contract, 6(1)(b) | n/a | Until removed or deletion. Stored as peppered hashes plus last three digits. |
| Check counters | Rate limiting | Legitimate interests, 6(1)(f): preventing enumeration of the user base | n/a | Counts only, rolling hourly and daily windows. The looked-up number is never written. |
| Review decisions | Fraud prevention, appeals | Legitimate interests, 6(1)(f) | n/a | Until account deletion. Never records a positive result, only "no tick issued". |
| Image and reference fingerprints | Detect the same result uploaded to two accounts | Legitimate interests, 6(1)(f) | n/a | SHA-256 hashes of the image and the normalised reference number, nothing else. Rows expire with the tick they backed. |
We do not process children's data knowingly (18+ terms, ID check). We do not carry out automated decision-making with legal or similarly significant effect: software proposes, and a person decides anything that isn't a plain, recent, matching negative result. Declined uploads can be re-submitted and appealed to a person.
4. What we deliberately don't process
- Who checked whom. A lookup reads and never writes. There is no table, log line or analytics event that links a caller to a target. This is enforced in the single server route that performs lookups and covered by an end-to-end test.
- Positive results. A non-negative result is discarded after the decision "no tick". Nothing about what it said is stored.
- Location, contacts, device identifiers, behavioural analytics, advertising identifiers. None are collected.
5. Processors and transfers
| Processor | Role | Location | Transfer mechanism |
|---|---|---|---|
| Neon, Inc. | Postgres database, sign-in tables, private object storage | Frankfurt, Germany (AWS eu-central-1) | UK adequacy for the EU; DPA with SCCs for support access |
| Vercel, Inc. | Hosting, serverless functions | Functions pinned to Frankfurt; edge network global | DPA, UK IDTA / Addendum |
| GetOTP (otp.dev) | Delivery of the six-digit sign-in code by SMS | EU | DPA. Receives the phone number and code, nothing else |
| Google LLC (Gemini API, paid tier) | Reads the two photographs to extract name, date, panel and result | EU processing selected where available; may be US | DPA, UK Addendum. Paid-tier terms: prompts are not used to train models and are not retained beyond abuse monitoring |
No processor may use the data for its own purposes. No data is sold or shared with anyone else. We'd move object storage to a UK region the moment our provider offers one.
6. Security measures
- TLS everywhere, HSTS preloaded, strict security headers (nosniff, frame denial, referrer policy, permissions policy).
- Phone numbers hashed with a server-side pepper held only in the hosting secret store. Database and storage reachable only from server code, never from the browser.
- Uploaded photos in a private bucket with no public URLs, streamed to reviewers through an authenticated route, deleted on decision.
- Admin access limited to named phone numbers, each signing in with their own one-time code.
- Rate limits per IP on code sending and verification, three attempts per code, and per-user hourly and daily limits on lookups. Origin checks on the sign-in routes.
- Every "miss" on a lookup returns an identical body and comparable timing, whether the number is unknown, untested, expired, positive or has blocked the caller.
- Infrastructure as code in a version-controlled repository; dependency updates reviewed; secrets never in the repository.
- A security.txt for coordinated disclosure.
7. Breach handling
If personal data is compromised we assess within 24 hours, notify the ICO within 72 hours where the breach is likely to result in a risk to people, and tell affected users directly and plainly where the risk is high. Because the app never stores who checked whom, and never stores a positive result, the worst realistic case is disclosure that a number belongs to someone who has tested. We treat that as high risk anyway.
8. Rights requests
Deletion is self-service and immediate in Settings. Access, rectification, portability, restriction and objection requests go to the contact above and are answered within one calendar month. We verify requesters by sending a code to the phone number on the account, so we never need to ask for more data to answer a request about data.
9. Governance
- The four product rules (no tick, no peeking; looking leaves no trace; no result means nothing; positives are never shown) are written into the codebase, tested end to end and take precedence over any feature.
- DPIA reviewed at every change to processing and at least annually.
- Processor list, retention periods and this page updated together, with the date at the top.
- Partner data-sharing (for example, a testing service handing us a verified result) will only ever happen under a written agreement, with the user's explicit action, and we will publish the fact of it here.
10. Documents available to partners
Full DPIA, record of processing activities, processor DPAs, security questionnaire answers (for example the NHS DTAC and DSPT self-assessment once completed), and the source code under NDA. Ask: admin@flexgroup.dev.