Apple's guideline 2.5.2 prohibits apps from downloading executable code after approval. Using OTA updates (Expo Updates, CodePush) combined with remote feature flags to silently enable entirely new functionality — gambling, payments, adult content, cryptocurrency — after passing review is treated as deception and results in account termination, not just app rejection. The line Apple draws is between bug fixes and UI changes (permitted) and new features that would require re-review (prohibited). The combination of OTA + remote config is the mechanism most commonly exploited to bypass review — reviewers know what to look for.
Info because most OTA implementations are legitimate; the risk is narrow but the consequence (account termination) is severe enough to warrant inspection.
Configure Expo Updates to apply only on error recovery, and ensure no remote flag can enable a feature category that wasn't present and reviewed at submission time.
// app.json
"updates": {
"enabled": true,
"fallbackToCacheTimeout": 0,
"checkAutomatically": "ON_ERROR_RECOVERY"
}
Audit every LaunchDarkly/Statsig/GrowthBook flag in the codebase. For any flag that controls a payment flow, adult content, gambling mechanic, or cryptocurrency feature — verify that feature was present and reviewable at the last App Store submission. Disable the flag permanently or submit a new app version before enabling it.
app-store-review-blockers.technical-requirements.no-hot-code-push-abuseinfoapp.json for updates.url and updates.enabled. Look for expo-updates runtime API usage: Updates.checkForUpdateAsync(), Updates.fetchUpdateAsync(), Updates.reloadAsync(), CodePush.sync(). Look for conditional logic that loads different feature sets based on remote config values fetched alongside or through the update mechanism. Pay special attention to expo-updates combined with remote feature flags that could enable major new features post-approval. Check if the OTA mechanism is used to ship JavaScript-only UI and logic changes (permitted) vs. changes to core functionality that would require re-review (not permitted).REQUEST_INSTALL_PACKAGES Android permission combined with self-update logic.expo-updates, no react-native-code-push, no custom OTA logic) is present in the codebase."expo-updates combined with remote feature flags could enable new payment flows post-approval without re-review" or "CodePush.sync() configured to apply mandatory updates immediately — could push major feature changes""updates": { "fallbackToCacheTimeout": 0, "checkAutomatically": "ON_ERROR_RECOVERY" }