2026-04-29 Манифест конфиденциальности iOS, Required Reason API и конвейер аудита CI на арендованном облачном Apple Silicon Mac (HK / JP / KR / SG / US)
Если в 2026 году вы поставляете потребительские iOS-приложения, App Review всё строже ожидает точность манифеста конфиденциальности — не обещание в PDF от юристов, а файлы PrivacyInfo.xcprivacy, которые идут с бинарниками и декларируют Required Reason API там, где Apple каталогизирует чувствительное использование фреймворков. Релиз-менеджеры, уже арендующие Mac mini M4 в Сингапуре или Токио для ночных xcodebuild archive, должны относиться к приватности как к подписанию кода: падать в CI до того, как человек загрузит IPA. Руководство с датой 2026-04-29 даёт практический поток аудита: что держать в Git, как сопоставлять категории API с вызовами Swift/ObjC, как встраивать манифесты SPM/XCFramework и как на общих хостах 1–2 TB подключить две стадии CI — lint и archive — чтобы регрессии приватности не проскальзывали после пятничного спешного bump CocoaPods. Дополняет CI с кейчейном и профилем, экспорт IPA + API App Store Connect и изоляцию DerivedData, когда одна машина подтверждает и подпись, и метаданные приватности.
Почему в 2026 команды не сводят приватность только к Legal
Инструменты Apple пересекаются с инженерией: сторонние SDK несут вложенные манифесты, Xcode агрегирует их в отчёт. Три типичных болевых точки на арендованных фермах между Гонконгом, Сеулом и востоком США:
- Дрифт зависимостей — минор аналитического SDK добавляет новую категорию Required Reason; никто не обновляет
PrivacyInfo.xcprivacy, пока App Store Connect не предупредит неделями позже. - Путаница мульти-target — расширение watchOS и основная iOS цель нуждаются в согласованных декларациях; CI собирает только iOS-схему и скрывает расхождения watch.
- Разрыв бинарных доказательств — инженеры grep-ят исходники, но не сверяют связанные фреймворки в
.xcarchive; пропускаются категории только из Objective-C categories.
Манифесты привязаны к собранным артефактам, в отличие от старой истории «nutrition label». Когда инженер поднимает аналитику с 4.3.1 на 4.3.2, diff манифеста должен быть в том же PR, что и lockfile. На арендованных хостах, где десятки репозиториев делят один Xcode, каждый pipeline пишет доказательства под уникальный префикс артефактов.
Продукт и Legal говорят о «целях»; инженеры переводят в перечисленные коды причин Apple. Ведите живой словарь в хендбуке. Сообщения CI должны ссылать имя SDK и feature flag, сокращая триаж между UTC+8 и US Eastern.
Что обязано быть в репозитории (не «где-то в Notion»)
Минимум под версионным контролем:
- Цель приложения
PrivacyInfo.xcprivacyс корректным NSPrivacyTracking, доменами и Required Reason для прямых вызовов API. - Инвентарь SDK — каждая зависимость SPM/CocoaPods/XCFramework с ожидаемым путём манифеста.
- Ссылки политик — URL должны открываться (404 бьют по доверию при человеческом ревью).
find . -name PrivacyInfo.xcprivacy
grep -R NSPrivacyAccessedAPIType -n Sources/
Для бинарных SDK проверьте, манифест внутри XCFramework или sidecar; зеркала в ThirdPartyManifests/ с checksum ловят тихие CDN-замены. SwiftPM упаковывает иначе, чем CocoaPods — рекурсию .build ограничьте эфемерными агентами.
Домены трекинга: маркетинг меняет endpoints — обновляйте манифест до DNS. Несовпадение декларации и реального SDK — классика «локально всё прошло» из-за укороченных путей в симуляторе.
Матрица решений: сигнал API против инженерного доказательства
Используйте таблицу при сбоях отчёта Xcode или lint — адаптируйте таксономию Apple.
| Сигнал | Инженерное доказательство | Типичный CI-guard |
|---|---|---|
| API меток времени файлов | Показать пользовательскую функцию, нуждающуюся в timestamps; без сторонней аналитики | Fail при новых импортах линкера без строк манифеста |
| API свободного места | Описать UX кеша и чтения свободного места | Снапшот-тест + reason ID совпадает с внутренней докой |
| UserDefaults за пределами группы | Доказать кросс-приложение только при реальном entitlement | Статический скан + матрица схем по планам тестов |
| SDK без манифеста | Тикет upstream или временный pin старого бинарника | Блок merge при смене checksum без совпадения хэша манифеста вендора |
Расширяйте колонками под ваш комплаенс. Количественный пример: новые категории Required Reason > ноль к прошлому GA при изменении Swift < 400 строк — блок merge до PRIVACY_OK от security в Slack.
CI на общем арендованном Mac: двухступенчатое принуждение
Изолируйте задачи по lane, как в детерминизме Bundler + Pods.
Стадия A — быстрый статический lint (каждый PR)
Перечислить все PrivacyInfo.xcprivacy, проверить plist, сверить enum Required Reason с allowlist в репо, при инкременте grep подозрительных import в Swift. Цель < 8 минут на M4 для среднего приложения (~450 kLOC Swift + сгенерированный код).
Стадия B — истина archive (релизные ветки)
Ночной или релизный xcodebuild archive с той же дисциплиной DEVELOPER_DIR, что в мульти-Xcode матрице; JSON приватности приложите рядом с .xcarchive. Рост категорий — блокер релиза.
Машины archive: единая локаль и таймзона. При ротации подписей перебазируйте артефакты приватности после первого успешного archive с новым сертификатом.
DEPLOY_lane; типично 4 lint + 2 archive на 24 GB UMA.
Девять шагов перед тегом release/x.y
- Заморозить граф зависимостей —
Podfile.lock, SPM resolved, checksums бинарников. - Обновить ожидания манифестов вендоров — diff вложенных манифестов в XCFrameworks.
- Обновить PrivacyInfo уровня приложения — согласовать коды причин с продуктовыми заметками Sales.
- Запустить lint стадии A — ошибки как JSON в Slack.
- Archive стадии B — ближайший к тестировщикам арендованный регион (JP vs SG).
- Сравнить экспорт приватности с предыдущим GA.
- QA-тикет для новых категорий с копирайтом первого запуска.
- Пакет доказательств в примечаниях App Store Connect.
- После релиза — хеши и снапшоты манифестов в холодное хранилище на 13 месяцев аудита.
Между шагами 4–5 — человеческая проверка скриншотов метаданных. Между 7–8 — согласование push-entitlements с тем, что реально читает сервис-расширение.
Enterprise «Labs» — те же девять шагов; внутренние инструменты утекают в клиентские сборки чаще, чем признают, особенно при общих Fastlane Ruby-хелперах.
FAQ: CI приватности и предупреждения App Store Connect
| Вопрос | Практический ответ (2026-04-29) |
|---|---|
| Пропускают ли внутренние enterprise-сборки манифесты? | Нет — распределение enterprise тоже ожидает честного раскрытия; те же ворота CI. |
| Можно ли заглушить lint переменной shell? | Временно на ветке-болванке; никогда на main — агрегация App Store всё равно покажет категории. |
Короткие ответы для JSON-LD и Slack в мобильном. Обновляйте таблицу при новых каталогах причин Apple.
Почему Mac mini M4 с большим NVMe всё ещё важен для аудита приватности
Аудит IO-ёмкий: повторные archive, нарезка символов, экспорт xcresult могут сжигать сотни GB в неделю. Bare-metal Mac mini M4 с 1–2 TB на узлах MacXCode в Гонконге, Токио, Сеуле, Сингапуре и США стабилизирует стадию B. Это согласуется с SSH-доступом и региональными ценами: машина, которая подписывает приложение, — тот же класс, которому ревьюеры неявно доверяют в плане toolchain Apple.
Запускайте lint приватности рядом с пулом archive
1–2 TB · Apple Silicon · SSH / опционально VNC