Closed testingFamily safety · Google PlayCase study

Tatabbu

A location app a stranger cannot read — proved with probes and mutations, not with a promise.

14 minPlay reviewHow this was measured

Submission timestamp 10:22, release timestamp 10:36, both recorded in the Play Console release history.

176countries in closed testingHow this was measured

Country list selected in the Play Console release; 176 countries plus the rest-of-world option.

25SQL privilege probes
34policy mutations killed

Why this one is hard

A family-safety app holds the single most dangerous field in consumer software: a child’s live location. Every other feature is ordinary; that one field turns a bug into a physical risk.

The usual failure is not a dramatic breach. It is an ordinary query that forgot a filter, in a codebase where the security decision lives in the application layer and is repeated in forty places.

Demo data1Live tracking: the phone has been still for 3 minutes; locate, loud sound and alert.3All three devices on one map, each with its last-seen time, beside the safe zones.View all screens →

The constraint I set

Authorization does not live in the app. It lives in the database, as row-level security (RLS) policies, so a forgotten filter in client code cannot widen access — the database simply returns nothing.

Data residency was chosen deliberately: Supabase in the EU (Frankfurt), under a regime with a real answer to who can compel disclosure.

Decisions

Every table denies by default. Access is granted by explicit policy, per row, per role. There is no 'authenticated users can read' shortcut anywhere.

The client is treated as hostile. Nothing the app sends is trusted to identify who is asking; identity is taken from the verified session on the server side.

Store declarations were written before the features. Foreground-service type and background-location justification were designed into the build, which is why review was not a negotiation.

How it was verified

Inspection is not evidence. I wrote 25 SQL-level privilege probes that attempt, as each role, exactly the reads and writes that must fail — and assert that they do.

Then I attacked my own policies: 34 mutations deliberately weakened the security rules one at a time, and the probe suite had to catch every one. A policy layer that survives mutation is a policy layer that is actually load-bearing.

This method found real gaps that reading the policies had not. Two are worth naming, because both are invisible to inspection: a function still reachable through Postgres’ default PUBLIC grant after being revoked from the app role — the function from the top of this page; and a guard comparing a JSON extraction with <>, which yields NULL rather than false when the key is absent — a check that silently passes everything.

Outcome

Cleared Google Play review in 14 minutes, including the two declaration classes that most often stall a release.

Opened to closed testing in 176 countries with a complete data-safety disclosure and a Parenting category listing.

What I would change — and what it still costs

The probe suite grew after the policies, not with them. Written first, it would have caught both defects before they ever reached a migration.

Residency in Frankfurt is right for privacy and wrong for latency from the Gulf. That is a trade I made on purpose and would make again — but it is a trade, not a free win.

Screens10

Demo dataCaptured on the Android release build 1.0.14 in an emulator, with test accounts and a synthetic drive — no real family’s location appears.

What you can check yourself

Each row is a source you can open or a method you can repeat.

  • LinkIn closed testing on Google Play and TestFlight — not public yet.
  • Measured14 min Google Play review timeSubmission timestamp 10:22, release timestamp 10:36, both recorded in the Play Console release history.
  • Measured176 countries in closed testingCountry list selected in the Play Console release; 176 countries plus the rest-of-world option.
  • Screens10 screensCaptured on the Android release build 1.0.14 in an emulator, with test accounts and a synthetic drive — no real family’s location appears.

Talk about this project

For judges, mentors and security teams — WhatsApp and email reach me directly, and I reply myself. Open to mentorship and cybersecurity programmes.