Location permission distinguishes between always/when-in-use/never
Why it matters
Requesting always-on background location when only foreground location is needed is one of the most common grounds for App Store rejection and a clear GDPR Art. 5(1)(c) data-minimisation violation. Apple's location always permission (NSLocationAlwaysAndWhenInUseUsageDescription) triggers a two-step authorization flow that explicitly warns users their location is tracked in the background — users decline this at far higher rates than when-in-use. On Android 10+, background location requires an additional ACCESS_BACKGROUND_LOCATION permission that triggers a separate, more alarming system dialog. Apps requesting always-on location for features like map display or restaurant search — where when-in-use is sufficient — face Google Play policy strikes and user complaints.
Severity rationale
High because requesting always-on location for features that only need foreground location violates GDPR Art. 5(1)(c), triggers heightened Apple and Google review scrutiny, and causes significantly higher permission denial rates.
Remediation
Default to LOCATION_WHEN_IN_USE for all location features. Only escalate to LOCATION_ALWAYS when a documented background feature (fitness tracking, delivery tracking, geofencing) specifically requires it.
import { request, PERMISSIONS, RESULTS } from 'react-native-permissions'
// Default: request when-in-use
const foregroundResult = await request(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE)
// Only if a background feature genuinely exists:
if (userEnablesBackgroundTracking) {
const backgroundResult = await request(PERMISSIONS.IOS.LOCATION_ALWAYS)
}
In app.json, only add NSLocationAlwaysAndWhenInUseUsageDescription if your app has an active background location feature. Remove the key entirely if the app only needs foreground location — its presence alone triggers additional scrutiny during App Store review.
Detection
-
ID:
location-granularity -
Severity:
high -
What to look for: Count all location permission request calls. For each, quote the actual permission constant used (e.g.,
PERMISSIONS.IOS.LOCATION_WHEN_IN_USEvsPERMISSIONS.IOS.LOCATION_ALWAYS). Check iOSInfo.plistforNSLocationWhenInUseUsageDescriptionvsNSLocationAlwaysAndWhenInUseUsageDescription. On Android, checkACCESS_FINE_LOCATIONvs background location. -
Pass criteria: If the app needs location, it requests at minimum
when-in-useand only escalates toalwaysif genuinely needed for background location features. At least 1 location permission request uses the granular when-in-use API. User is not forced into always-on location. -
Fail criteria: App requests always-on location for features that only need when-in-use location. OR app provides no distinction between permission levels. Do NOT pass when the app requests
LOCATION_ALWAYSbut has no background location feature. -
Skip (N/A) when: App does not use location (no location permission requests or declarations found).
-
Detail on fail: Quote the actual permission constant.
"App requests location 'always' permission but primary feature (map display) only needs when-in-use access"or"Location permission offers no distinction between levels — user cannot choose when-in-use only" -
Remediation: Minimize location access scope. For most features, when-in-use location is sufficient. Only request always-on location if your app genuinely needs background location (e.g., fitness tracking, delivery tracking):
// iOS: Distinguish permission levels const iosConfig = { NSLocationWhenInUseUsageDescription: 'We use your location to show nearby content while the app is open', NSLocationAlwaysAndWhenInUseUsageDescription: 'We need background location for fitness tracking' } // Request when-in-use by default const result = await request(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE)
External references
- cwe · CWE-272 — Least Privilege Violation
- gdpr · Art. 5(1)(c) — Data minimisation
- external · apple-location-always — Apple: Requesting Always Authorization for Location Services
Taxons
History
- 2026-04-18·v1.0.0·Initial import from mobile-permissions-privacy·automated