# Privacy manifest file exists and is complete for iOS

- **Pattern:** `ab-001893` (`mobile-permissions-privacy.permission-requests.privacy-manifest-ios`)
- **Severity:** critical
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001893
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001893)

## Why it matters

Apple has required a Privacy Manifest (`PrivacyInfo.xcprivacy`) for all iOS app submissions since May 2024. An app without one — or with an incomplete one — is rejected at review. Beyond compliance, the manifest forces an audit of every SDK that touches protected APIs (NSUserDefaults, file timestamps, disk space, system boot time, active keyboard). GDPR Art. 13 requires informing users of the legal basis and purpose of data collection before collection begins; the Privacy Manifest is Apple's enforcement mechanism for that disclosure at the SDK layer. Missing reason codes for third-party SDKs (e.g., Firebase, Amplitude) are the most common rejection cause, because those SDKs access protected APIs on your behalf even if your own code does not.

## Severity rationale

Critical because a missing or incomplete Privacy Manifest causes immediate App Store rejection and signals unchecked SDK data access that violates GDPR Art. 13 disclosure requirements.

## Remediation

Create `ios/PrivacyInfo.xcprivacy` and declare every protected API your app and its SDKs access. Check each SDK's documentation for its required reason codes.

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>NSPrivacyTracking</key>
  <false/>
  <key>NSPrivacyTrackingDomains</key>
  <array/>
  <key>NSPrivacyAccessedAPITypes</key>
  <array>
    <dict>
      <key>NSPrivacyAccessedAPIType</key>
      <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
      <key>NSPrivacyAccessedAPITypeReasons</key>
      <array>
        <string>CA92.1</string>
      </array>
    </dict>
  </array>
</dict>
</plist>
```

Run `xcrun privacy-assistant` (Xcode 15+) to detect SDK API access automatically. Add a `<dict>` block for each accessed API category. Missing entries for Firebase Crashlytics, Amplitude, or Segment are the most common rejection sources — check each SDK's published reason codes.

## Detection

- **ID:** `privacy-manifest-ios`
- **Severity:** `critical`
- **What to look for:** For iOS apps, check for a `PrivacyInfo.xcprivacy` file in the `ios/` directory. Count all required sections: NSPrivacyTracking, NSPrivacyTrackingDomains, NSPrivacyAccessedAPITypes, NSPrivacyAccessedAPITypeReasons. Enumerate all third-party SDKs that access protected APIs and check each is documented.
- **Pass criteria:** A `PrivacyInfo.xcprivacy` file exists with at least 2 required sections (NSPrivacyTracking and NSPrivacyAccessedAPITypes), and all third-party SDKs that access protected APIs are documented with reason codes.
- **Fail criteria:** No `PrivacyInfo.xcprivacy` file exists, OR the file is incomplete (missing NSPrivacyAccessedAPITypes for dependencies that access protected APIs), OR the file is invalid XML. Do NOT pass when the file exists but contains only placeholder or empty arrays.
- **Skip (N/A) when:** App is Android-only and has no iOS build (no `ios/` directory and no iOS target in `app.json`).
- **Detail on fail:** Quote the actual file contents or note absence. Example: `"No PrivacyInfo.xcprivacy file found in ios/ directory"` or `"PrivacyInfo.xcprivacy exists but missing NSPrivacyAccessedAPITypes entries for Firebase Analytics"`
- **Remediation:** Apple requires all iOS apps to declare their privacy practices in a Privacy Manifest. Create `ios/PrivacyInfo.xcprivacy`:

  ```xml
  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
  <dict>
    <key>NSPrivacyTracking</key>
    <false/>
    <key>NSPrivacyAccessedAPITypes</key>
    <array>
      <dict>
        <key>NSPrivacyAccessedAPIType</key>
        <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
        <key>NSPrivacyAccessedAPITypeReasons</key>
        <array>
          <string>CA92.1</string>
        </array>
      </dict>
    </array>
  </dict>
  </plist>
  ```

  Reference Apple's Privacy Manifest documentation to add the correct reason codes for each API your app and its SDKs access.

## External references

- gdpr Art. 13
- external apple-privacy-manifest — https://developer.apple.com/documentation/bundleresources/privacy_manifest_files

Taxons: regulatory-conformance, privacy-consent

HTML version: https://auditbuffet.com/patterns/ab-001893
