Displaying an ATT prompt but reading the tracking identifier before the user responds — or transmitting a device-persistent ID to a third party before ATT resolves — defeats the purpose of the consent mechanism entirely. Under GDPR Art.7, consent must precede processing; under CCPA §1798.120, users have the right to opt out before sharing occurs. OWASP 2021 A04 (Insecure Design) applies when consent architecture is structurally bypassed. Apple's App Review detects this pattern with instrumentation: they see SDK network calls before the ATT dialog appears in their testing, and apps fail review for it.
High because transmitting tracking identifiers before ATT consent is obtained constitutes pre-consent data collection that violates Apple policy, GDPR Art.7, and CCPA §1798.120.
Gate every identifier read and third-party transmission on ATT status resolution:
import { getTrackingStatus } from 'expo-tracking-transparency';
const status = await getTrackingStatus();
if (status === 'authorized') {
const advertisingId = await getAdvertisingId();
analytics.identify(advertisingId);
} else {
// Use ephemeral session ID only
}
Audit every track() and identify() call in src/analytics/ or equivalent for whether it includes a device-persistent or user-persistent identifier. Replace persistent device IDs with ephemeral session IDs (generated fresh each app launch) for pre-consent analytics. Any DeviceInfo.getUniqueId() value passed to a third-party service must be gated the same way.
app-store-privacy-data.tracking-advertising.no-tracking-before-consenthighUIDevice.current.identifierForVendor (IDFV — not IDFA, but if shared across apps it may require ATT); any hashed email or phone number sent to an ad network before login; fingerprinting signals (screen resolution, OS version, installed font list, battery level, CPU count) collected and sent to a third-party server; DeviceInfo.getUniqueId() (from react-native-device-info) sent to an analytics service before ATT consent. For React Native, search for NativeModules.RNDeviceInfo, DeviceInfo.getUniqueId, DeviceInfo.getAdvertisingId, getAdvertisingId(), TrackingTransparency.getAdvertisingId() calls without a preceding ATT status check. For Flutter, look for AdvertisingId.id or device_info_plus unique ID usage passed to analytics before consent. Also check whether any analytics event sent on app launch includes a persistent user or device identifier."getAdvertisingId() called in src/analytics/startup.ts before ATT prompt — IDFA transmitted to analytics service on app launch regardless of consent" or "DeviceInfo.getUniqueId() passed to third-party analytics API in app initialization before any consent flow"import { getTrackingStatus } from 'expo-tracking-transparency';
const status = await getTrackingStatus();
if (status === 'authorized') {
const advertisingId = await getAdvertisingId();
analytics.identify(advertisingId);
} else {
// Use anonymous session ID only
}
track() and identify() call site for whether it includes a persistent device or user identifier