Как поддерживать политику конфиденциальности в соответствии со сборкой
Политику пишут один раз, а устаревает она, когда pull request добавляет SDK. Как заметить это в самом pull request бесплатной проверкой, читающей только файлы сборки.
Зафиксируйте, по каким SDK, типам данных и разрешениям были написаны ваши страницы, а затем сравнивайте с этой записью файлы сборки в каждом pull request. Когда появляется зависимость или разрешение, которых в записи нет, pull request покажет это раньше релиза — пока политику конфиденциальности и формы магазинов ещё легко обновить.
Сделайте это за несколько минут
AppFoyer размещает страницы, о которых это руководство, — политику конфиденциальности, условия использования, поддержку, удаление аккаунта и app-ads.txt — на отдельном поддомене, без собственного домена и сервера. Одно приложение — бесплатно, и ничто из того, что требует магазин, никогда не бывает платным.
Проверено 30 сентября 2026 г. Правила магазинов меняются, иногда без предупреждения. Всё ниже ссылается на официальную документацию, и авторитетна именно она, а не эта страница. Если они расходятся, прав магазин. Это руководство переведено с английского; цитаты из документации магазинов приведены в оригинале на английском.
Написать политику конфиденциальности — разовая работа. Поддерживать её правдивой — нет: политика описывает сборку, которая была у вас в момент написания, а сборка продолжает меняться. Pull request добавляет crash reporting, библиотеку подписок или разрешение на геолокацию, приложение выходит, а политика, форма Data safety и сведения App Privacy всё ещё описывают старое приложение.
Оба магазина считают это вашей проблемой, а не своей. Google Play говорит, что ваши ответы в Data safety должны всегда оставаться точными и полными и что данные, собираемые сторонними библиотеками и SDK в вашем приложении, декларируете вы. Apple говорит то же самое о сведениях App Privacy и добавляет, что ответы в App Store Connect можно изменить в любой момент без отправки обновления.
Откуда на самом деле берётся расхождение
Почти никогда — из решения «собирать больше данных». Оно возникает из обычной инженерной работы:
- Новая зависимость. Crash reporting, аналитика, SDK paywall, библиотека карт.
- Новое разрешение. Геолокация для одной функции, камера для сканера, отслеживание для рекламы.
- Flavor или target. Бесплатная сборка получает рекламный SDK, которого нет в платной.
- Удаление. Это тоже расхождение: политика теперь декларирует лишнее — более безопасная ошибка, но всё же ошибка.
Каждое из этих изменений попадает в файл сборки — build.gradle, AndroidManifest.xml, Podfile,
Package.swift, Info.plist, pubspec.yaml, package.json. Именно это и делает его проверяемым.
Подход: запись и проверка в каждом pull request
- Когда страницы написаны, зафиксируйте, по чему они написаны: SDK, типы данных и разрешения, которые были в сборке в тот момент.
- В каждом pull request снова читайте файлы сборки и сравнивайте.
- Если что-то отличается, сообщайте, что именно, где (файл и строка) и на какую страницу или форму это может повлиять.
Важны два свойства. Проверка должна читать только файлы сборки — никогда исходный код, никогда секреты, — чтобы её можно было безопасно запускать на любом репозитории. И она должна говорить «может быть устаревшим», а не «нарушение»: библиотека в файле сборки не доказывает, что приложение её использует, и только вы знаете, меняет ли она то, что собирает ваше приложение.
Настройка с AppFoyer
Проверка бесплатна на любом тарифе. Она читает только файлы сборки, не требует ключа или секрета, ничего никуда не отправляет и никогда не меняет страницу.
С плагином Claude Code
- Скажите “make this app store-ready”. Помимо черновиков страниц, плагин записывает
appfoyer.jsonв корень репозитория: запись о том, по чему были написаны страницы. - Скажите “add the AppFoyer drift check”. Он покажет вам GitHub workflow и запишет
.github/workflows/appfoyer.yml, когда вы согласитесь. - Закоммитьте оба файла. Плагин никогда не делает commit или push за вас.
Без плагина
Добавьте workflow сами:
name: AppFoyer drift check
on: pull_request
permissions:
contents: read
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: appfoyer/check-action@v1
Откройте pull request. Пока в репозитории нет appfoyer.json, в job summary показывается файл,
который проверка записала бы по вашей сборке. Сравните его с опубликованными страницами и
закоммитьте.
Или создайте его локально — тем же сканером, опубликованным в npm:
npx @appfoyer/check init
В другой CI-системе
npm-пакет работает везде, где работает Node 20 или новее. Например, для GitLab:
appfoyer-drift-check:
image: node:22
script:
- npx -y @appfoyer/check --fail-on-drift
--format markdown даёт тот же отчёт, что показывает GitHub job summary; --format json — для
скриптов.
Как выглядит находка
Pull request, который добавляет RevenueCat в приложение, чьи страницы были написаны без него:
"Trail Notes": 2 changes
+ In-app purchases / subscriptions (data collected) app/build.gradle.kts:28
→ Privacy policy may not declare "In-app purchases / subscriptions"
→ Google Play Data safety and Apple App Privacy answers may be outdated
→ Terms may not cover purchases and subscriptions
+ RevenueCat (SDK) app/build.gradle.kts:28
→ Store forms: RevenueCat is not in the app's SDK list
→ Privacy policy may not name this SDK
По умолчанию job сообщает о находках и проходит успешно. Добавьте fail-on-drift: "true" в
with:, чтобы он падал, пока запись не обновлена.
Когда проверка сообщает об изменении
- Обновите то, на что влияет изменение. Снова скажите “make this app store-ready” в той же
ветке: плагин заново прочитает сборку, обновит факты о приложении, перепишет черновики затронутых
страниц и перезапишет
appfoyer.json. Или отредактируйте страницы и вкладку Store forms в дашборде сами. - Обновите запись. Плагин уже сделал это. После правки в дашборде выполните
npx @appfoyer/check updateили скопируйте обновлённый файл из job summary, где он находится под находками. - Закоммитьте её в том же pull request. Следующий запуск не покажет изменений, а в истории зависимость и изменение раскрытия появятся вместе.
- Обновите формы магазинов в консолях. Ни проверка, ни AppFoyer не имеют доступа к Play Console или App Store Connect. Черновики ответов находятся на вкладке Store forms в дашборде.
- Опубликуйте обновлённые черновики с экрана проверки.
Несколько приложений в одном репозитории
appfoyer.json содержит одну запись на каждую страницу приложения в магазине. Product flavor с
собственным application id получает собственную запись, поэтому рекламный SDK, используемый только
бесплатным flavor, сравнивается со страницами бесплатного flavor, а не платного. Плагин записывает
по одной записи на каждый flavor, который он подготовил к магазину. Вручную запись принимает список
sourceSets — ["free"], а для сборки с несколькими измерениями — каждый flavor в комбинации плюс
саму комбинацию — и папку root, если приложение находится внутри monorepo.
Чего она не видит
- Зависимости зависимостей, кроме iOS, где их перечисляет
Podfile.lock. SDK, подтянутый другой библиотекой, не появляется в вашем файле сборки, поэтому не появляется и здесь. - Конфигурацию только в коде.
app.config.js/app.config.tsв Expo — это JavaScript, и он не читается;app.jsonиpackage.json— читаются. - Используете ли вы то, что объявили. Зависимость, которая присутствует, но не используется, всё равно попадает в отчёт.
- Ваш бэкенд. Ничто в файле сборки не говорит, что хранит ваш сервер и как долго.
Это напоминание в тот момент, когда раскрыть изменение дешевле всего, а не вердикт о соответствии и не юридическая консультация.
Официальные источники
- Предоставление информации для раздела Data safety в Google Play — Справка Google Play Console: поддержание формы в точном состоянии и данные сторонних SDK
- Сведения App Privacy в App Store — Apple: поддержание ответов в актуальном состоянии и их обновление без обновления приложения
appfoyer/check-actionи@appfoyer/check— Action и npm-пакет, с описанием того, что они читают