Run a free ShipCheck before you resubmit. Paste a public GitHub link or upload a zip, no account needed. ShipCheck reads allowlisted config files and names each issue with the guideline, a short label, how serious it is, and how many places. It covers 16 Apple and Google Play checks, including 5.1.1 privacy (like a sensitive permission with no description), account deletion (5.1.1(v)), privacy manifests (5.1.2), and Play permissions. A fix is $9, or 3 for $19, paid first. Run a free ShipCheck

It can't tell from config alone whether your app really uses the camera or the mic, so the "is this permission actually used?" check below is still on you.

Apple rejected my app for permissions it doesn't use (Guideline 5.1.1)

This one surprises a lot of Expo and React Native builders, because you never wrote the permission yourself. A library did. Recently an indie dev on X listed it as the first thing they had to fix before submitting: two Expo libraries had put camera, microphone, motion, and Face ID prompts into their Info.plist, and the app used none of them.

AI coding agents make this more common. An agent installs a package to try something, the feature gets dropped, and the package (and its permission strings) stays in the project.

What Apple's rules say

From Apple's App Store Review Guidelines, 5.1.1 (fetched Nov 10, 2026):

(ii) Permission: ... Ensure your purpose strings clearly and completely describe your use of the data.

(iii) Data Minimization: Apps should only request access to data relevant to the core functionality of the app and should only collect and use data that is required to accomplish the relevant task.

(iv) Access: Apps must respect the user's permission settings and not attempt to manipulate, trick, or force people to consent to unnecessary data access.

So there are two ways to get caught. The purpose string is vague or generic, or the app declares access it has no reason to need.

Why Expo apps end up with extra permissions

Expo config plugins write permission strings into the native project when you run prebuild or an EAS build. Expo's own permissions guide says libraries provide a boilerplate reason, and that "these default messages will most likely need to be tailored to your specific use case for your app to be accepted by the App Store."

Two common examples, from Expo's docs:

  • expo-image-picker sets NSPhotoLibraryUsageDescription, NSCameraUsageDescription, and NSMicrophoneUsageDescription, with defaults like "Allow $(PRODUCT_NAME) to access your camera". (docs)
  • expo-sensors sets NSMotionUsageDescription with "Allow $(PRODUCT_NAME) to access your device motion". (docs)

"Allow MyApp to access your camera" doesn't say why, which is what 5.1.1(ii) asks for. And if the app only picks photos, the camera and mic strings describe access it never uses.

How to find every permission in your build

  1. Run npx expo prebuild --platform ios (or open your existing ios/ folder) and open ios/<YourApp>/Info.plist.
  2. Search for keys ending in UsageDescription, like NSCameraUsageDescription, NSMicrophoneUsageDescription, NSMotionUsageDescription, NSFaceIDUsageDescription, NSLocationWhenInUseUsageDescription, NSContactsUsageDescription.
  3. For each one, find the screen that triggers the prompt. If you can't find one, that permission is a candidate to remove.
  4. Check app.json / app.config.js for the plugins array and ios.infoPlist. That's where the strings come from in a managed project.

If a coding agent built the app, ask it to list every UsageDescription key and the exact file and line that calls the matching API. It's a quick way to spot leftovers from features you dropped.

How to fix it

If the app really uses the permission: rewrite the string so it says what the app does with it. Expo's guide uses this example:

{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSCameraUsageDescription": "This app uses the camera to scan barcodes on event tickets."
      }
    }
  }
}

Many plugins take the same text as an option, for example photosPermission on expo-image-picker.

If the app doesn't use it:

  • Remove the library if nothing uses it anymore. This is the cleanest fix.
  • For expo-sensors, Expo's docs say you can set "motionPermission": false in the plugin config to disable motion permissions.
  • For expo-image-picker, the docs say false on cameraPermission or microphonePermission blocks the Android permission. They don't say what it does on iOS, so check the prebuilt Info.plist after you change it.
  • On Android, Expo's docs say permissions added by a package's own manifest can only be removed with android.blockedPermissions.

Then rebuild, recheck the Info.plist, and upload a new build. Permission strings live in the binary, so this needs a new build, not just a metadata edit.

How to reply to App Review

Keep it short. Say what you removed or rewrote, and where the remaining permissions are used. For example:

We removed the camera, microphone, and motion permissions, which came from libraries the app doesn't use. The only remaining permission is photo library access, used on the Profile screen to pick a profile photo. The purpose string now explains that.

When ShipCheck helps vs when it doesn't

  • Helps: ShipCheck's 5.1.1 check flags permission problems it can see in your config, like a sensitive permission with no description. The same scan also checks account deletion, Sign in with Apple, privacy manifests, and 12 more rules, so you can catch other config issues before the next round. See the guidelines we check.
  • Doesn't help: deciding whether a permission is used. That depends on what your screens actually do, so use the steps above. ShipCheck also can't see your App Store Connect answers, your privacy nutrition label, or your screenshots.

FAQ

Does an unused purpose string show a prompt to users? No. iOS only shows the prompt when the app calls the API. But reviewers can still see what your build declares, and 5.1.1(iii) asks you to only request what the app needs.

Do I need a new build? Yes. Info.plist is part of the binary.

Is "Allow $(PRODUCT_NAME) to access your camera" good enough? Expo's own guide says the defaults most likely need to be tailored for App Store acceptance. Say what the feature is and why it needs the access.

Does Google Play have the same issue? Play has its own permission rules (for example, broad photo and file access is limited). See our guide on Google Play photo and video permissions.

Is this the same as account deletion? No. Unused or vague permission strings sit under 5.1.1(ii) through (iv). If the app lets people create an account, Guideline 5.1.1(v) account deletion is a separate rule, and it's a common follow-up reject.

Related guides

Ready to resubmit? Run a free ShipCheck first. Paste a public GitHub link or upload a zip, no account needed. It names each issue with the guideline, a short label, how serious it is, and how many places. A fix is $9, or 3 for $19, paid first. Run a free ShipCheck

It still can't tell whether a permission is actually used, and it can't see your App Store Connect answers.