本文へ移動
cccskills
無料GitHub で公開

data-minimization-audit

Detects data collection patterns that exceed what is necessary for the app's stated functionality, enforcing Guideline 5.1.1(iii) data minimization requirements.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md6.7 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Skill: Data Minimization Audit

<!-- SEO: data minimization PHPickerViewController full photo library contacts IDFA background location over-broad permission Guideline 5.1.1(iii) iOS rejection -->

Purpose

Detects data collection patterns that exceed what is necessary for the app's stated functionality, enforcing Guideline 5.1.1(iii) data minimization requirements.

Apple Guideline

  • Primary: 5.1.1(iii) — Data Collection and Storage: Data Minimization
  • Related: 5.1.1(ii), 5.1.2
  • Reference: references/guidelines/5-legal.md

Real-World Rejection Cases

  • Case: App requested full photo library access just to let user pick a profile picture — rejected Source: Apple Developer Forums Root cause: PHPickerViewController gives access without requiring NSPhotoLibraryUsageDescription — full access not needed for single selection; Apple reviewers specifically look for this pattern

Trigger

Invoke on any iOS/macOS project to identify permission requests and data collection calls that can be replaced with privacy-preserving alternatives.

Inputs

NameTypeDefaultDescription
project_rootpathcwdiOS/macOS project root
shared_contextobjectnilPre-collected context from appstore-full-audit Phase 1

Actions

Phase 1: Context Collection

Skip this phase if shared_context is provided.

  1. Glob **/*.swift — collect all Swift source files.
  2. Glob **/*.m — collect Objective-C source files.
  3. Glob **/*.entitlements — locate entitlements files for background location check.
  4. Glob **/PrivacyInfo.xcprivacy — locate privacy manifest for identifier declaration check.

Phase 2: Checks

  1. Full photo library access for selection use case Grep pattern PHPhotoLibrary.*requestAuthorization.*readWrite in **/*.swift. If found, also Grep PHPickerViewController — if picker not used, flag → 🟠 HIGH. PHPickerViewController provides privacy-preserving photo selection without full library authorization; developers should migrate to this API for profile photo or single-image selection flows.

  2. Full contacts access for selection use case Grep pattern CNContactStore.*requestAccess|requestAccess.*forEntityType in **/*.swift and **/*.m. If found, Read surrounding context — if the use case is only email/phone number retrieval or contact selection (not programmatic contact list enumeration), flag → 🟠 HIGH. CNContactPickerViewController provides privacy-preserving contact selection with no permission required.

  3. Always location without background entitlement Grep pattern requestAlwaysAuthorization in **/*.swift. If found, Glob **/*.entitlements and Read — if com.apple.location.always entitlement absent → 🟠 HIGH. Background location requires explicit entitlement and strong use-case justification.

  4. Device identifiers not declared in privacy manifest Grep pattern identifierForVendor|advertisingIdentifier|ASIdentifierManager in **/*.swift. If found, Glob **/PrivacyInfo.xcprivacy and Read — if identifier type not declared in NSPrivacyAccessedAPITypes → 🟠 HIGH. Required reason API declarations are mandatory.

Phase 3: Output

Collect all findings from Phase 2 and build the prioritised findings list below. Include file paths and line numbers. Omit tiers with no findings.

Output Format

## Data Minimization Audit — Findings

### 🔴 CRITICAL — Guaranteed rejection
- [ ] TODO: <exact actionable step> — `file:line` — Guideline 5.1.1(iii)

### 🟠 HIGH — Very likely rejection
- [ ] TODO: Replace PHPhotoLibrary.requestAuthorization(.readWrite) with PHPickerViewController — full photo library access is unnecessary for profile picture selection — `ProfileEditViewController.swift:67` — Guideline 5.1.1(iii)
- [ ] TODO: Replace CNContactStore.requestAccess with CNContactPickerViewController — full contacts permission is unnecessary for single contact selection — `InviteViewController.swift:33` — Guideline 5.1.1(iii)
- [ ] TODO: Add com.apple.location.always entitlement or replace requestAlwaysAuthorization with requestWhenInUseAuthorization — background location entitlement is absent — `LocationService.swift:21` — Guideline 5.1.1(iii)

### 🟡 MEDIUM — Possible rejection
- [ ] TODO: Declare identifierForVendor usage in PrivacyInfo.xcprivacy under NSPrivacyAccessedAPITypes — `AnalyticsManager.swift:45`

### 🟢 LOW — Best practice
- [ ] TODO: Audit all permission requests against Apple's privacy-preserving API list — prefer system pickers and restricted-access APIs over full authorization wherever possible

Tools Used

Glob, Grep, Read

Constraints

  • Read-only. No file edits.
  • No network calls.
  • Skip Phase 1 if shared_context is provided by orchestrating agent.
  • Works on Swift, Objective-C, React Native, Flutter projects.

Quick Commands

Run these in your project root to check manually:

# Check for full photo library access
!grep -rn "PHPhotoLibrary.requestAuthorization" . --include="*.swift"

# Check for full contacts access
!grep -rn "CNContactStore" . --include="*.swift"

# Check for device identifiers
!grep -rn "identifierForVendor\|advertisingIdentifier" . --include="*.swift"

Swift Anti-Pattern Reference

examples/swift/PrivacyPatterns.swift

Detection Steps

  1. Find target files

    • Glob: **/*.swift, **/*.m, **/Info.plist
  2. Search for rejection patterns

    • Grep CNContactStore\|requestAccess.*contacts — full contacts access
    • Grep CNContactPickerViewController — out-of-process picker (correct alternative)
    • Grep requestAlwaysAuthorization — always-on location
    • Grep requestWhenInUseAuthorization — when-in-use (acceptable for most apps)
    • Grep PHPhotoLibrary.requestAuthorization — full photo library access
    • Grep PHPickerViewController — out-of-process photo picker (correct alternative)
  3. Determine verdict

    • CNContactStore used + no CNContactPickerViewController → 🟠 HIGH (Guideline 5.1.1(iii))
    • requestAlwaysAuthorization without navigation/tracking justification → 🟠 HIGH
    • PHPhotoLibrary.requestAuthorization without PHPickerViewController alternative → 🟠 HIGH
    • Out-of-process pickers used throughout → 🟢 pass
  4. Report

    • File path + line where full access is requested
    • Fix: Replace CNContactStore with CNContactPickerViewController; replace PHPhotoLibrary.requestAuthorization with PHPickerViewController

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Detects missing or insufficient in-app account deletion functionality required since June 30, 2022 under Guideline 5.1.1(v) for all apps that support account creation.

日本語の概要は準備中です。原文の説明を表示しています。

cruisediary/apple-app-review-skills192026年5月2日 更新

Detects feature patterns that require a higher age rating than commonly submitted, enforcing Guideline 2.3.6 which requires age ratings to accurately reflect the app's content and social features.

日本語の概要は準備中です。原文の説明を表示しています。

cruisediary/apple-app-review-skills192026年5月2日 更新

Detects apps that send user data to third-party AI systems without explicit in-app consent and disclosure, enforcing Guideline 5.1.2(i).

日本語の概要は準備中です。原文の説明を表示しています。

cruisediary/apple-app-review-skills192026年5月2日 更新

Detects placeholder content, stub UI, hardcoded test credentials, and non-production endpoints that signal an incomplete app to reviewers under Guideline 2.1.

日本語の概要は準備中です。原文の説明を表示しています。

cruisediary/apple-app-review-skills192026年5月2日 更新

Detects app name violations including names exceeding 30 characters, beta labels, Apple trademark terms, and version numbers in the display name, enforcing Guideline 2.3.7.

日本語の概要は準備中です。原文の説明を表示しています。

cruisediary/apple-app-review-skills192026年5月2日 更新

App Store rejection prevention for iOS/macOS apps. Covers privacy, UGC, IAP, metadata, layout, and quality checks based on real Apple rejection cases.

日本語の概要は準備中です。原文の説明を表示しています。

cruisediary/apple-app-review-skills192026年5月2日 更新

cruisediary のスキルをすべて見る

このスキルの問題を報告する