Skip to the content.

09 · Active config — km range + remote kill-switch (live, 2026-06-28)

The investigation’s headline question, answered across the whole installed cohort instead of one app: for every Appmiral app that carries the Crowd Connected location SDK, what geofence km range is armed, and is the remote kill-switch ON or OFF right now? This reads each app’s own server-pushed config out of its private on-device storage (root) — we never contact Crowd Connected. It extends the single-app 04-live-capture-2026-06-26.md to the live fleet.

Evidence header

=== EVIDENCE CAPTURE HEADER (APK harvest) ===
Captured by:     adb over USB, on-device pull
Host wall-clock: 2026-06-28T15:43:11+02:00
Device time:     Sun Jun 28 15:43:12 CEST 2026
Device model:    Pixel 10a (Android 16)
Device build:    google/stallion/stallion:16/CP1A.260505.005/15081906:user/release-keys
ADB serial:      5B161JEA308016

Source data (this folder): data/cc_live_config_2026-06-28.csv / .json. Raw Room DBs + CrowdConnected.xml prefs are private (they contain device/account identifiers); only the redacted decoded config is published. Reader: ../../tools/apk-harvest/read-cc-config.py.

Result — the 6 apps with a populated Crowd Connected config

Of the 140 installed apps, 6 had a live, cached Crowd Connected config at capture time (an app only has one after it has been launched and the SDK has polled its backend). Identifiers redacted; all values are server-pushed.

App Kill-switch Active km range (radius2) Inner ring (radius1) Geofence centre Poll / high / med (s) Schema
com.appmiral.ttfestival 🔴 ON 60 km 820 m 52.99, 6.56 (Assen) 120 / 30 / 1800 new Settings.active=1, SDK 2.1.0, BACKGROUND
com.appmiral.mdlbeast 🟢 OFF 60 km (armed) 282 m 21.49, 39.19 (Jeddah, SA) 120 / 30 / 1800 new Settings.active=0, SDK 2.1.0, BACKGROUND
com.appmiral.rockforpeople 🟢 OFF 40 km (armed) 1354 m 50.25, 15.84 (Hradec Králové, CZ) 120 / 30 / 1800 new Settings.active=0
com.appmiral.teamnl 🟢 OFF 50 km (armed) 183 m 45.45, 9.16 (Milan, IT) 120 / 30 / 300 new Settings.active=0, SDK 2.1.0, BACKGROUND
com.appmiral.museumnachtamsterdam 🟢 OFF 80 km (armed) 10155 m 52.36, 4.89 (Amsterdam) 120 / 30 / 1800 legacy activeAPIResponse=120,false,…
com.appmiral.dutchgp 🟢 OFF — (no zone cached this run) — — 120 / — / — legacy activeAPIResponse=120,false,…

What this shows

  1. Only TT Festival was live. Settings.active=1 with a 60 km collection ring centred on Assen and the SDK in background mode — armed far beyond the festival grounds. This corroborates 04-live-capture and the transmission-to-firehose.us-east-1 evidence there.
  2. The kill-switch is a remote decision. Every other app shipped an armed geofence (40–80 km) yet was toggled OFF by Crowd Connected’s backend at capture time. Same SDK, same local geoEnabled=1/sendPositionData=1 flags — the only thing that differs is the server-pushed switch. The operator can flip any of these ON remotely, exactly as TT Festival is.
  3. The geofences are city/region-scale, not venue-scale. 40–80 km rings cover whole metropolitan areas (an 80 km ring on Amsterdam reaches the German border side of the Randstad; 60 km on Assen covers most of the north-east Netherlands).

Where the switch lives (two schemas)

The “on/off” is not the local geoEnabled/sendPositionData flags. It is the server-pushed activation, stored in one of two places depending on SDK age:

The km range (GeoZone.radius2, in metres ÷ 1000 = km) and centre live in the Room DB for both schemas; radius1 is the inner high-frequency ring.

Why this is broader than “12 apps”

The static scan (see 08-integration-matrix) shows the Crowd Connected capability — AWS Cognito + Kinesis Firehose + Google Fused Location — is bundled in ~139/140 apps, even though the literal com.crowdconnected package survives obfuscation in only 9. A given app only produces a live km/kill-switch reading after it has been launched and has polled config; the 6 above are simply the ones that had been opened. Any of the other CC-capable apps would populate the same config once launched. So the live table is a floor, not a ceiling, on how many apps can be remotely armed.

Determinism / caveats (for replication)

Re-verify one app (root, ~1 min)

$pkg = "com.appmiral.ttfestival"
adb shell su -c "cp /data/data/$pkg/databases/CrowdConnected-RoomDatabase /sdcard/cc.db"
adb pull /sdcard/cc.db
python -c "import sqlite3;c=sqlite3.connect('cc.db');print('Settings',[r for r in c.execute('select active,geoEnabled,sendPositionData from Settings')]);print('GeoZone',[r for r in c.execute('select lat,lng,radius1,radius2 from GeoZone')])"
# legacy apps (no `active` column) — read the heartbeat instead:
adb shell su -c "cat /data/data/com.appmiral.museumnachtamsterdam/shared_prefs/CrowdConnected.xml" | Select-String activeAPIResponse

Full automated reader + reproduction: 10-apk-harvest-reproduction.md.