Jak utrzymać politykę prywatności w zgodzie z buildem
Politykę prywatności pisze się raz, a dezaktualizuje się w dniu, w którym pull request dodaje SDK. Jak zauważyć to w samym pull requeście dzięki bezpłatnej kontroli, która czyta tylko pliki builda.
Zapisz, na podstawie jakich SDK, typów danych i uprawnień powstały Twoje strony, a potem porównuj z tym zapisem pliki builda w każdym pull requeście. Gdy pojawi się zależność lub uprawnienie, którego zapis nie zawiera, pull request pokaże to przed wydaniem, gdy politykę prywatności i formularze w sklepach nadal łatwo zaktualizować.
Zrób to zamiast tego w kilka minut
AppFoyer hostuje strony, o których jest ten poradnik — politykę prywatności, regulamin, wsparcie, usuwanie konta i app-ads.txt — na ich własnej subdomenie, bez Twojej własnej domeny i serwera. Jedna aplikacja jest za darmo, a nic, czego wymaga sklep, nigdy nie jest płatne.
Sprawdzono 30 września 2026. Zasady sklepów się zmieniają, czasem bez zapowiedzi. Wszystko poniżej linkuje do oficjalnej dokumentacji i to ona — nie ta strona — jest rozstrzygająca. Jeśli się różnią, rację ma sklep. Ten poradnik jest przetłumaczony z angielskiego; cytaty z dokumentacji sklepów pozostawiono w oryginalnym brzmieniu angielskim.
Napisanie polityki prywatności to jednorazowa praca. Utrzymanie jej prawdziwości już nie: polityka opisuje build, który miałeś w chwili jej pisania, a build ciągle się zmienia. Pull request dodaje raportowanie awarii, bibliotekę subskrypcji albo uprawnienie do lokalizacji, aplikacja trafia do wydania, a polityka, formularz Data safety i szczegóły App Privacy nadal opisują starą aplikację.
Oba sklepy traktują to jako Twój problem, nie swój. Google Play mówi, że Twoje odpowiedzi w Data safety muszą być zawsze dokładne i kompletne, a dane zbierane przez biblioteki i SDK firm trzecich w Twojej aplikacji musisz zadeklarować sam. Apple mówi to samo o szczegółach App Privacy i dodaje, że odpowiedzi w App Store Connect możesz zmienić w dowolnym momencie bez przesyłania aktualizacji.
Skąd naprawdę bierze się rozbieżność
Prawie nigdy z decyzji, by „zbierać więcej danych”. Bierze się ze zwykłej pracy inżynierskiej:
- Nowa zależność. Raportowanie awarii, analityka, SDK paywalla, biblioteka map.
- Nowe uprawnienie. Lokalizacja dla jednej funkcji, aparat dla skanera, śledzenie na potrzeby reklam.
- Flavor lub target. Darmowy build dostaje SDK reklamowy, którego nie ma build płatny.
- Usunięcie. To też rozbieżność: polityka deklaruje teraz za dużo, co jest bezpieczniejszym błędem, ale nadal błędem.
Każda z tych zmian trafia do pliku builda: build.gradle, AndroidManifest.xml, Podfile,
Package.swift, Info.plist, pubspec.yaml, package.json. Dzięki temu da się to sprawdzić.
Podejście: zapis i kontrola w każdym pull requeście
- Gdy Twoje strony są pisane, zapisz, na podstawie czego powstały: SDK, typy danych i uprawnienia obecne w tym momencie w buildzie.
- W każdym pull requeście ponownie przeczytaj pliki builda i porównaj.
- Gdy coś się różni, powiedz co, gdzie (plik i linia) i na którą stronę lub formularz może to wpłynąć.
Liczą się dwie właściwości. Kontrola musi czytać wyłącznie pliki builda, nigdy kod źródłowy, nigdy sekrety, więc można ją bezpiecznie uruchomić w każdym repozytorium. I musi mówić „może być nieaktualne”, a nie „naruszenie”: biblioteka w pliku builda nie dowodzi, że aplikacja jej używa, a tylko Ty wiesz, czy zmienia ona to, co zbiera Twoja aplikacja.
Konfiguracja z AppFoyer
Kontrola jest bezpłatna w każdym planie. Czyta tylko pliki builda, nie potrzebuje klucza ani sekretu, niczego nigdzie nie wysyła i nigdy nie zmienia żadnej strony.
Z pluginem Claude Code
- Powiedz “make this app store-ready” (przygotuj tę aplikację do sklepów). Oprócz przygotowania
projektów stron plugin zapisuje
appfoyer.jsonw katalogu głównym repozytorium: zapis tego, na podstawie czego powstały strony. - Powiedz “add the AppFoyer drift check” (dodaj kontrolę rozbieżności AppFoyer). Plugin pokaże Ci
workflow GitHub i zapisze
.github/workflows/appfoyer.yml, gdy się zgodzisz. - Zatwierdź (commit) oba pliki. Plugin nigdy nie robi za Ciebie commitów ani pushy.
Bez pluginu
Dodaj workflow samodzielnie:
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
Otwórz pull request. Gdy w repozytorium nie ma jeszcze appfoyer.json, podsumowanie zadania (job
summary) pokazuje plik, który zostałby zapisany na podstawie Twojego builda. Porównaj go z
opublikowanymi stronami i zatwierdź.
Albo utwórz go lokalnie, tym samym skanerem opublikowanym w npm:
npx @appfoyer/check init
W innym systemie CI
Pakiet npm działa wszędzie tam, gdzie działa Node 20 lub nowszy. Na przykład w GitLab:
appfoyer-drift-check:
image: node:22
script:
- npx -y @appfoyer/check --fail-on-drift
--format markdown daje ten sam raport, który pokazuje podsumowanie zadania w GitHub;
--format json jest przeznaczony dla skryptów.
Jak wygląda wynik
Pull request, który dodaje RevenueCat do aplikacji, której strony napisano bez niego:
"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
Domyślnie zadanie raportuje i przechodzi. Dodaj fail-on-drift: "true" pod with:, aby kończyło
się niepowodzeniem, dopóki zapis nie zostanie zaktualizowany.
Gdy kontrola zgłosi zmianę
- Zaktualizuj to, na co zmiana wpływa. Powiedz ponownie “make this app store-ready” na tej
samej gałęzi: plugin ponownie przeczyta build, zaktualizuje fakty o aplikacji, przygotuje nowe
projekty stron, których dotyczy zmiana, i przepisze
appfoyer.json. Albo samodzielnie edytuj strony i kartę Store forms w panelu. - Odśwież zapis. Plugin już to zrobił. Po edycji w panelu uruchom
npx @appfoyer/check updatealbo skopiuj odświeżony plik z podsumowania zadania, gdzie znajduje się pod wynikami. - Zatwierdź go w tym samym pull requeście. Następne uruchomienie nie pokaże zmian, a historia pokaże, że zależność i zmiana w ujawnieniach pojawiły się razem.
- Zaktualizuj formularze w konsolach sklepów. Ani kontrola, ani AppFoyer nie mają dostępu do Play Console ani App Store Connect. Projekty odpowiedzi są na karcie Store forms w panelu.
- Opublikuj zaktualizowane projekty z ekranu przeglądu.
Kilka aplikacji w jednym repozytorium
appfoyer.json zawiera jeden wpis na każdą stronę aplikacji w sklepie. Product flavor z własnym
application id dostaje własny wpis, więc SDK reklamowy używany tylko przez darmowy flavor jest
porównywany ze stronami darmowego flavora, a nie płatnego. Plugin zapisuje jeden wpis na każdy
flavor, który przygotował do sklepów. Ręcznie wpis przyjmuje listę sourceSets (["free"] albo, w
buildzie z wieloma wymiarami, każdy flavor z kombinacji plus samą kombinację) oraz folder root,
gdy aplikacja znajduje się w monorepo.
Czego kontrola nie widzi
- Zależności zależności, z wyjątkiem iOS, gdzie wymienia je
Podfile.lock. SDK dołączony przez inną bibliotekę nie pojawia się w Twoim pliku builda, więc nie pojawia się też tutaj. - Konfiguracji zapisanej tylko w kodzie.
app.config.js/app.config.tsw Expo to JavaScript i nie jest czytany;app.jsonipackage.jsonsą. - Czy używasz tego, co deklarujesz. Zależność, która jest obecna, ale nieużywana, i tak zostanie zgłoszona.
- Twojego backendu. Nic w pliku builda nie mówi, co i jak długo przechowuje Twój serwer.
To przypomnienie w chwili, gdy ujawnienie zmiany jest najtańsze, a nie werdykt zgodności i nie porada prawna.
Źródła oficjalne
- Provide information for Google Play’s Data safety section — Pomoc Google Play Console: utrzymywanie dokładności formularza i dane z SDK firm trzecich
- App privacy details on the App Store — Apple: utrzymywanie aktualności odpowiedzi i ich zmiana bez aktualizacji aplikacji
appfoyer/check-actioni@appfoyer/check— Action i pakiet npm wraz z opisem tego, co czytają