TT Festival 2026 — Privacy Policy Analysis
Analysis of the app’s privacy statement, linked from the Google Play listing.
- URL: https://app.appmiral.com/ttfestival2026/privacy-policy
- Policy “last modified”: 10 November 2025
- Captured: 2026-06-07 (raw HTML saved to session artifacts as
privacy_policy.html) - Controller contact:
info@ttfestival.nl - Hosting/data region: AWS
eu-west-1(Ireland); Cloudflare (USA) in front.
This page records what stands out (“wat valt op”), including a cross-reference between what the policy claims and what the decompiled v2.0.1 APK actually ships.
TL;DR — what stands out
- An internal CMS edit link was left in the published policy — a clear copy-paste/editorial leak.
- It’s a generic white-label Appmiral template, hedged with “if the App is connected to…” language that never says which integrations are actually active for TT Festival.
- The named integrations don’t match the shipped build. The policy lists
OneTrust / Cookie Information (consent) and Braze, Tealium, Salesforce,
Insider, Permutive — but this build’s
EXPLICIT_MODULESenables none of them, and uses thecom.appmiral.privacy.noneprivacy module (i.e. no consent-management platform / cookie banner). - The SSO provider list is boilerplate (AWS Cognito, Azure B2C, OpenID, Sentinel) — the app actually ships only Spotify and a first-party Profile identity provider.
- Sloppy editing: an empty
<title>-style Word artifact (#_msocom_3anchor), a verbatim duplicated sentence in §9, and a stray markdown link fragment. - Informal data sharing: profile data “may be manually exported” to the Organizer’s Box.com account.
- “Not validated” profile fields are explicitly admitted.
1. The leaked internal CMS link 🚩
Section 4 (Data Storage and Retention) contains, embedded mid-sentence, a link to Appmiral’s internal “backstage” CMS:
https://app.appmiral.com/backstage/appmiralcms/localization/editiontranslationkey/2250555/edit#_msocom_3
- This is an authoring/editor URL (
/backstage/appmiralcms/.../edit) that has no business being in a public privacy statement. - The
#_msocom_3fragment is a Microsoft Word comment anchor — the text was pasted from Word with a tracked comment still attached. It reveals the policy was drafted in Word and the editor missed the cleanup. - It exposes an internal translation-key id (
2250555) and the CMS structure.
Not a data breach, but a telling editorial/operational hygiene lapse.
2. Generic, hedged white-label template
The policy repeatedly hedges instead of stating facts:
“If the App is connected to additional analytics platforms (such as CM.com CDP, Braze, Insider, Tealium, or Salesforce Marketing Cloud), data may also be processed there according to our configuration.”
A user cannot tell from this which processors actually receive their data. The same hedge is copied into both §2f and §4. This is clearly the standard Appmiral boilerplate themed per edition, not a policy tailored to TT Festival’s real setup.
3. Policy claims vs. what the APK actually ships
Cross-referenced against com.appmiral.BuildConfig in the decompiled
v2.0.1 APK (AVAILABLE_MODULES = compilable options; EXPLICIT_MODULES =
what is actually wired into this build) and package-directory presence.
| Integration named in policy | In AVAILABLE_MODULES |
In EXPLICIT_MODULES (this build) |
Code present |
|---|---|---|---|
| Crowd Connected (location) | ✅ | ✅ | ✅ (incl. native libpositioner.so) |
| Spotify | ✅ | ✅ | ✅ |
| Firebase / GA4 | (Google libs) | — | ✅ (heavily) |
| Cashless / wallet / loyalty | ✅ | ✅ | ✅ |
| Cookie Information (CMP) | ✅ | ❌ | partial libs only |
| OneTrust (CMP) | ✅ | ❌ | ❌ |
| Braze | ✅ | ❌ | ❌ |
| Tealium | ✅ | ❌ | ❌ |
| Salesforce Marketing Cloud | ✅ | ❌ | ❌ |
| Insider | ✅ | ❌ | ❌ |
| Permutive | ✅ | ❌ | ❌ |
| Facebook Connect | ✅ | ❌ | ❌ |
| CM.com CDP | n/a (not an Appmiral module) | ❌ | ❌ |
Most notable: the active privacy module is com.appmiral.privacy.none —
this build ships no consent-management platform / cookie banner, even though
the policy name-drops both OneTrust and Cookie Information. Meanwhile
Firebase/GA4 analytics is compiled in and (per policy) runs on app start in
“de-identified, IP-truncated” form. The marketing/CDP SDKs the policy warns
about (Braze, Tealium, Salesforce, Insider, Permutive) are not in this
shipped build.
Identity/SSO: the policy lists “AWS Cognito, Microsoft Azure B2C, OpenID, or
Sentinel.” The app’s actual IDENTITY_PROVIDERS are only
SpotifyIdentityProvider and ProfileIdentityProvider. (An AWS Cognito
SDK is present as a transitive dependency, but Cognito SSO is not the configured
login.) So the SSO section is template text, over-stating what TT Festival uses.
4. Specific privacy points worth flagging
- Unvalidated profile data (§2a): “These fields are not mandatory and not validated.” Honest, but unusual to advertise — it means free-text/garbage (or someone else’s details) can be entered without checks.
- Location sharing with a third party (§2c): pseudonymized location is shared
with Crowd Connected as
UUID + coordinates + optionally a push token. Sharing a push token alongside location with an external partner is worth noting — a push token is a fairly stable device identifier. - Tokens (§2b): auth tokens “may be processed but are not stored”; Spotify token used for recommendations (§2e).
- Manual export to Box.com (§6): “profile data may be manually exported to the Organizer’s secure environment (e.g., a Box.com account) for marketing or customer management.” A manual, human-in-the-loop export is an informal practice and a place where EU-only guarantees depend on the Organizer.
- Retention (§4): default 2 years after last activity; de-identified aggregates kept longer. Reasonable, but again hedged by the “additional platforms” caveat.
- Transfers (§7): EU-only except Cloudflare (USA); relies on adequacy decisions / SCCs for any non-EU transfer.
5. Editorial / quality issues
- Empty document title and a Word
#_msocom_3comment-anchor artifact (see §1) — drafted in Word, pasted without cleanup. - Duplicated sentence (§9): “You can change your consent for location or push notifications at any time in your device settings.” appears twice back-to-back.
- A dangling empty markdown link
[]( … backstage … )wraps the leaked CMS URL. - No named DPO, no dated sub-processor list, no link to per-partner policies (beyond the generic §10 third-party-links disclaimer).
6. Bottom line
The statement is a boilerplate Appmiral template that over-discloses
(lists marketing/consent SDKs and SSO providers the shipped TT Festival build
doesn’t actually use) while under-specifying which processors are really
active. The shipped v2.0.1 app is comparatively lean: Firebase/GA4 analytics,
Crowd Connected location intelligence, Spotify, and cashless/wallet — with no
active consent-management module (privacy.none). The accidental inclusion of
an internal CMS editor link with a Word comment anchor is the single most
eye-catching detail.
Observations about active vs. inactive SDKs are based on static analysis of the decompiled v2.0.1 build (
BuildConfigmodule lists + package presence) and may not capture runtime-loaded or server-side processing.
7. Follow-up: Crowd Connected contradicts the EU-only claim
A deeper analysis of the one location SDK that is active
(docs/crowd-connected.md) found that its
position/Bluetooth/step telemetry is streamed to AWS Kinesis Firehose in
us-east-1 (USA) via US-region Cognito pools, and that the location stream is
aliased to the logged-in account id. Both findings are in tension with §4/§7 of
this policy (“all personal data are stored within the European Union … with the
exception of Cloudflare” and “only in pseudonymized form”).
For the consolidated inconsistency table, the “when does it collect / can I see my data / can I visualise it” answers, and the local data visualiser, see docs/crowd-connected-faq.md.
8. The policy is English-only — no Dutch version (GDPR Art. 12)
The privacy statement is served only in English, even though TT Festival is a
Dutch event and a Dutch government body (Gemeente Assen) steers Dutch-speaking
residents to the app. This was verified by content-negotiation, not just by
eyeballing the page — see the captured proof in
evidence/appmiral.com_2026-06-26_232241/logs/language-check_privacy-policy.txt
and the raw HTML evidence/appmiral.com_2026-06-26_232241/raw/privacy-policy.html.
| Check | Result |
|---|---|
| Document language | <html lang=en> |
| Title | “TT Festival 2026 – Privacy Statement” |
Request with Accept-Language: nl-NL,nl;q=0.9 |
Identical English body returned |
Dutch terms (privacyverklaring/persoonsgegevens/gegevens/toestemming) |
0 |
English markers (personal data/privacy statement/…) |
21 |
hreflang tags |
0 |
rel="alternate" language links |
0 |
| Language switcher | none |
Why it matters. GDPR Art. 12(1) requires that information to data subjects
be provided “in a concise, transparent, intelligible and easily accessible form,
using clear and plain language.” For a predominantly Dutch-speaking consumer
audience that is actively directed to the app by a Dutch municipality, an
English-only disclosure with no Dutch option (and no language negotiation) is a
transparency/accessibility concern. The researcher also raised this directly with
the organisation — see
evidence/email-correspondence/ (thread 03,
message 05), where the same Art. 12 point is put to Stichting TT Festival.
Reproduce
$UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
# default + Dutch-preferred request; compare the <html lang> and body language
curl.exe -s -A $UA "https://app.appmiral.com/ttfestival2026/privacy-policy" | Select-String '<html'
curl.exe -s -A $UA -H "Accept-Language: nl-NL,nl;q=0.9,en;q=0.5" `
"https://app.appmiral.com/ttfestival2026/privacy-policy" | Select-String '<html','hreflang','rel="alternate"'
A Dutch-preferred request returning the same English document — with zero
hreflang/alternate links — is the reproducible proof.