iOS uses a consent-based permission model: when your app first tries to use a protected resource such as the camera, location, or contacts, the system shows the user a one-time prompt, and the user grants or denies access. To request any protected resource, you must declare a purpose string in your Info.plist under the matching usage-description key, and the text you write there is shown in that prompt, so it has to clearly explain why your app needs the access. Miss the key and your app crashes when it touches the resource, and App Review rejects it. Tracking users across other apps and sites is a separate consent handled by the App Tracking Transparency prompt. The security principle throughout is least privilege: request only what your features actually need.
Short answer
iOS gates protected resources behind runtime consent prompts, and each requires a usage-description key in your Info.plist. Per Apple's privacy documentation, you declare a purpose string like NSCameraUsageDescription, and the system shows it when it asks the user; without the key, accessing the resource crashes the app and fails review. Cross-app tracking is separate, requiring the App Tracking Transparency prompt and its own key, per Apple's ATT documentation. Request access at the point of use, write clear and specific strings, handle denial gracefully, and, per the OWASP MASVS, request only the permissions your features need.
How iOS permissions work
iOS permissions are consent-based and prompted at runtime, meaning the user decides at the moment your app first needs a protected resource. When your code accesses something like the camera, the microphone, location, photos, or contacts for the first time, the system presents a permission alert, the user allows or denies it, and the choice is remembered. Your app does not get silent access to these resources; it must ask, and the user is always in control of the answer.
This differs from simply listing a capability. The permission is granted by the user at runtime, not by your app declaring it, so your code has to be prepared for either outcome and must not assume access. The declaration you make ahead of time, in your Info.plist, is what enables the prompt to appear and provides the explanation the user reads. So there are two parts working together: the Info.plist entry that describes why you want the resource, and the runtime prompt where the user actually decides, and both must be correct for access to work.
Info.plist usage-description keys
The Info.plist usage-description keys are how you declare a purpose string for each protected resource, and they are required. Each resource has a specific key, such as NSCameraUsageDescription for the camera, NSMicrophoneUsageDescription for the microphone, NSLocationWhenInUseUsageDescription for foreground location, NSContactsUsageDescription for contacts, and NSPhotoLibraryUsageDescription for the photo library. The string you set for the key is the message the user sees in the consent prompt, so it must clearly and specifically explain why your app needs that access.
Getting these keys right is not optional, because iOS enforces them strictly. If your app accesses a protected resource without the corresponding usage-description key present, the app crashes at that point, and App Review will reject a build that requests a resource without a clear purpose string, commonly under the privacy guideline. So for every protected resource your app touches, add the matching key with an honest, specific description of the feature it supports, and avoid vague text like the app needs access, which both serves the user poorly and draws review scrutiny.
The App Tracking Transparency prompt
App Tracking Transparency, or ATT, is a separate consent from resource permissions, and it governs tracking users across other companies' apps and websites. If your app tracks, for example by using the advertising identifier or sharing user data with data brokers for cross-app advertising, you must present the ATT prompt using the tracking authorization request and declare the NSUserTrackingUsageDescription key with a purpose string. Until the user grants tracking permission, you are not permitted to track them, and the identifier your app would use is unavailable.
Keep ATT distinct from the resource prompts in your thinking. A camera or location permission is about accessing a device resource, while ATT is specifically about tracking across other parties, and it falls under a different App Store rule than the resource usage descriptions. If your app does not track users in that cross-app sense, you do not need the ATT prompt at all. If it does, ATT is required, and your App Privacy disclosures must reflect that tracking honestly, since a mismatch between your tracking behavior and your declarations is a common source of privacy rejections.
Handling denial and changes
Because the user controls the answer, your app must handle denial gracefully rather than assuming access. When a user denies a permission, the affected feature should degrade in a sensible way, explaining what is unavailable and why, rather than breaking or repeatedly prompting. iOS will not show the system prompt again after the first decision, so re-requesting in code does nothing; if a user wants to change their choice, they do it in Settings, and your app can guide them there when it makes sense.
Design for the full range of states. A permission can be not yet determined, granted, denied, or restricted, and your code should check the current status before using a resource and behave correctly in each case. Requesting a permission at the point where the feature is used, with context about why, tends to earn more grants than asking for everything at launch. Handling denial and status changes well is both a better user experience and part of respecting the consent model iOS is built around, rather than fighting it.
Least privilege: request only what you need
The security principle underlying all of this is least privilege: request only the permissions your features genuinely require. Every protected resource your app can access is both a privacy consideration for the user and a piece of attack surface, so a permission you request but do not need adds risk without benefit. Over-requesting also draws App Review attention, since the review expects each permission to map to a real feature, and it erodes user trust when the prompts do not obviously match what the app does.
Apply this by auditing what your app actually asks for against what it actually uses. Remove usage-description keys and access for resources tied to features you removed or never shipped, and make sure each remaining permission has a clear purpose the user would understand. This is the same discipline that applies to Android permissions, and it is reflected in OWASP's guidance to minimize the data and capabilities an app accesses. A lean permission set is easier to justify at review, safer for users, and a sign of an app that respects the privacy model.
Permission keys reference
Mapping common resources to their keys makes the declarations concrete. The table below lists frequent ones.
| Protected resource | Info.plist key | Needed when |
|---|---|---|
| Camera | NSCameraUsageDescription | Accessing the camera |
| Microphone | NSMicrophoneUsageDescription | Recording audio |
| Photo library | NSPhotoLibraryUsageDescription | Reading or adding photos |
| Location, in use | NSLocationWhenInUseUsageDescription | Using foreground location |
| Contacts | NSContactsUsageDescription | Reading contacts |
| Tracking | NSUserTrackingUsageDescription | Cross-app tracking via ATT |
Read the table as a starting point: add the key that matches each resource your app touches, and write a specific purpose string for it rather than reusing a generic line.
Permission hygiene checklist
Working through these steps keeps your permissions correct and minimal. The checklist below covers them.
| Step | Action | Done? |
|---|---|---|
| Declare every key | A usage-description key for each resource used | [ ] |
| Write specific strings | Explain the real feature, not a vague line | [ ] |
| Request at point of use | Prompt in context, not all at launch | [ ] |
| Handle denial | Degrade gracefully, guide to Settings | [ ] |
| Request only what you need | Remove unused permissions and keys | [ ] |
| Add ATT only if tracking | Prompt and key when you track across apps | [ ] |
The row that most affects both users and review is requesting only what you need, because an unused permission adds privacy risk and review scrutiny with no benefit.
Scan for over-permissioning
Because unused or over-broad permissions are easy to accumulate, especially when a template or an AI code generator adds capabilities you never use, checking what your app actually requests is worthwhile. The gap between the permissions declared and the features that need them is exactly what a security review, and App Review, looks at.
A scanner like PTKD.com analyzes your build and reports issues such as over-broad permissions, risky third-party code that may access resources you did not intend, and data-handling problems by severity, mapped to OWASP MASVS, so you can see what your app requests before review does. To be clear about the boundary: PTKD does not write your purpose strings or fill in your App Privacy details. It shows you the permissions and access your app actually carries so your declarations and your least-privilege posture match reality.
What to take away
- iOS gates protected resources behind runtime consent prompts, and each resource needs a usage-description key in your Info.plist, or the app crashes and review rejects it.
- The purpose string you set for each key is shown in the prompt, so write a clear, specific explanation of the feature rather than a vague line.
- App Tracking Transparency is a separate consent for cross-app tracking, requiring its own prompt and key, and is only needed if your app actually tracks users.
- Handle denial gracefully across the not-determined, granted, denied, and restricted states, and request permissions at the point of use for more grants.
- Follow least privilege, requesting only what your features need, and scan for over-permissioning with a tool like PTKD.com.




