gpc-preflight について
GPC Preflight Scannerは、リリース前にAndroidアプリバンドルやAPKをGoogle Playの要件に照らして確認するスキルです。9種類のスキャナー、検出結果の設定、署名の整合性チェック、CIでの利用方法を扱います。
主な機能
- 01AABとAPKのスキャン
- 02マニフェストと権限の確認
- 03ネイティブライブラリとアライメントの検査
- 04シークレットと課金SDKの検出
- 05ストア掲載情報とポリシーの確認
- 06Play APIによる署名証明書の確認
活用シーン
- 01Playへのアップロード前にポリシー違反を発見
- 02CIでスキャン結果をリリース条件に設定
- 03署名証明書の不一致を調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ yasserstudio/ gpc-skills --skill gpc-preflightインストール後、Claude Code で/gpc-preflightを入力して読み込まれたか確認します。
詳細
GPC プリフライトスキャナー
使用する場面
次のようなタスクでは、このスキルを使用します。
- Google Play にアップロードする前に AAB または APK ファイルをスキャンする
- target SDK バージョンへの準拠を確認する
- Google Play ポリシーに照らして権限を監査する
- 64 ビットのネイティブライブラリのサポートを確認する
- ハードコードされたシークレットや認証情報がないか、ソースコードをスキャンする
- Google Play 以外の課金 SDK を検出する
- ストアの掲載情報メタデータがポリシーに準拠しているか確認する
- ポリシー準拠を基準とする CI/CD 品質ゲートを設ける
クイックリファレンス
# Full scan (AAB or APK)
gpc preflight app.aab
gpc preflight app.apk
# With metadata and source scanning
gpc preflight app.aab --metadata fastlane/metadata/android --source app/src
# Specific scanners only
gpc preflight manifest app.aab
gpc preflight permissions app.aab
gpc preflight metadata ./metadata
gpc preflight codescan ./src
# CI mode
gpc preflight app.aab --fail-on error --json
9 つのスキャナー
| スキャナー | チェック項目 | 重大度 |
|---|---|---|
| manifest | targetSdk >= 36(v0.9.79 以降)、debuggable、testOnly(v0.9.80 以降は <application> 要素から読み込み)、cleartext、exported の欠落、FGS のタイプ、ジオフェンシングのフォアグラウンドサービス(v0.9.65 以降) | critical/error/warning |
| permissions | 制限付き権限 18 種、連絡先への広範なアクセス、Health Connect の詳細な権限(v0.9.65 以降)、データセーフティに関するリマインダー | critical/error/warning/info |
| native-libs | 64 ビット ARM への準拠、ABI の検出、16KB ページアラインメント(v0.9.80 以降は AAB と APK が対象。ELF ヘッダーを 4096 バイト読み込み、1 回のスキャンで最大 512 個のライブラリ) | critical/warning |
| metadata | 掲載情報の文字数制限、スクリーンショット、プライバシーポリシー URL | error/warning |
| secrets | AWS キー、Google API キー、Stripe キー、秘密鍵 | critical/warning |
| billing | Stripe、Braintree、PayPal、Razorpay SDK の検出 | warning |
| privacy | トラッキング SDK、Advertising ID、データ収集の相互参照 | warning/info |
| policy | ファミリー/COPPA、金融、健康、UGC、オーバーレイ | warning/info |
| size | デバイスごとの推定ダウンロードサイズ(AAB:最大の ABI のみ。バンドルメタデータやオンデマンド/ファストフォローモジュールは含めない。APK:ファイル全体)、大きなネイティブライブラリ、大きなアセット | warning/info |
設定(.preflightrc.json)
{
"failOn": "error",
"targetSdkMinimum": 36,
"maxDownloadSizeMb": 200,
"allowedPermissions": ["android.permission.READ_SMS"],
"disabledRules": ["cleartext-traffic"],
"severityOverrides": { "billing-stripe-sdk": "info" }
}
Google Play では、すべての新しいアプリとアップデートに対して、2026 年 8 月 31 日までに API レベル 36(Android 16)が必須になります。この期限を反映するため、GPC preflight の targetSdkMinimum のデフォルト値は v0.9.79 で 36 に更新されました。
ダウンロードサイズ(v0.9.99 以降)
AAB の場合、size-over-limit は Google Play がバンドルを配信する方法に従って、1 台のデバイスがダウンロードするサイズを推定します。対象となるのは最大の ABI のネイティブライブラリのみで、BUNDLE-METADATA/(デバッグシンボル、R8 マッピング)やバンドル署名、オンデマンドまたはファストフォローモジュール、アセットパックは含みません。すべての画面密度と言語は引き続き計上されるため、実際より大きめの値になります。APK の場合はファイル全体が計上されます。デフォルトの maxDownloadSizeMb は 200 です。これは、モバイルデータ通信を利用しているユーザーに Google Play が大容量ダウンロードのダイアログを表示するサイズです。v0.9.99 より前は .aab 全体のサイズを合計していたため、マルチ ABI の Flutter/React Native バンドルは実際のダウンロードサイズの 3~4 倍として検出されていました(GH #116)。古いバージョンでこの問題が発生する場合は、アップグレードするか、"disabledRules": ["size-over-limit"] を追加してください。正確なサイズを確認するには、バンドルに対して bundletool get-size total を実行します。
native-libs-large(native-libs スキャナー)と size-large-native も、AAB の場合は単一の ABI のうち最大のものを測定します。
APK のスキャン: manifest チェック(manifest、permissions、policy、privacy スキャナー)は、現在 AAB のみを対象としています。APK のバイナリ XML マニフェストはまだデコードされないため、APK のスキャンでは「Manifest could not be fully parsed」と報告され、残りのスキャンが実行されます。すべてを網羅するには、アップロードする AAB をスキャンしてください。
終了コード
0— すべてのチェックに合格1— 実行時エラー6—--fail-onで指定した重大度以上の検出結果がある
主なルール
| ルール ID | 重大度 | 内容 |
|---|---|---|
| targetSdk-below-minimum | critical | targetSdkVersion < 36 |
| debuggable-true | critical | android:debuggable="true" |
| testOnly-true | critical | android:testOnly="true" |
| missing-arm64 | critical | 64 ビット版を含まない 32 ビット ARM |
| missing-exported | error | intent-filter を持つコンポーネントに exported 属性がない |
| foreground-service-type-missing | warning | アプリが FOREGROUND_SERVICE を要求しているが、foregroundServiceType を宣言するサービスがない(API 34 以降)。報告は 1 回のみ(v0.9.99 以降。以前はサービスごとに 1 件のエラー) |
| secret-aws-key | critical | ソースコード内の AWS アクセスキー |
| secret-stripe-key | critical | ソースコード内の Stripe シークレットキー |
| contacts-permission-broad | warning | READ_CONTACTS / WRITE_CONTACTS(v0.9.65 以降、2026 年 4 月のポリシー) |
| geofencing-foreground-service | warning | 位置情報 FGS + ACCESS_BACKGROUND_LOCATION(v0.9.65 以降、2026 年 4 月のポリシー) |
| health-connect-granular | warning/info | READ_ALL_HEALTH_DATA。targetSdk が 36 以上の場合は warning、それ以外は info(v0.9.65 以降、2026 年 4 月のポリシー) |
| policy-app-content-declaration | info | 任意の FOREGROUND_SERVICE* 権限。Play Console -> Policy -> App content に対応する申告が必要であることを知らせます(v0.9.94 以降) |
| native-libs-16kb-unchecked | warning | すべてのネイティブライブラリについて 16 KB アラインメントを確認できませんでした(v1.0.0-rc.1 以降) |
native-libs-16kb-unchecked(v1.0.0-rc.1 以降):リーダーは最大 512 個の .so ヘッダーをバッファーするため、数千個のネイティブライブラリを含むバンドルでもメモリ使用量は一定に保たれます。バンドル内のライブラリがそれを超える場合、アラインメントチェックの対象は先頭の 512 個のみとなるため、切り詰められたチェックが問題なしと判定されないよう、preflight はその旨を表示します。この検出結果には、スキップされた数が示されます。バンドル全体を確認するには、Android Studio の APK Analyzer を使用するか、ユニバーサル APK に対して zipalign -c -P 16 -v 4 app.apk を実行してください。このルールに該当するアプリはほとんどありません。
手順
preflight スキャンを全件実行する
- AAB または APK をビルドします:
./gradlew bundleRelease(APK の場合はassembleRelease) - 実行します:
gpc preflight app/build/outputs/bundle/release/app-release.aabAPK の場合:gpc preflight app/build/outputs/apk/release/app-release.apk - critical/error の検出結果を修正します
- 承認済みの権限を許可するか、誤検出を無効にするため、
.preflightrc.jsonを追加します - 問題がなくなるまで再実行します
注:スキャン後、GPC は Android デベロッパー確認要件に関するリマインダーを表示します(BR、ID、SG、TH では 2026 年 9 月 30 日に施行)。詳細は gpc verify を実行してください。
v0.9.80 以降、スキャナーがフィルタリングによって除外された場合(例:マニフェストの解析失敗により、マニフェストに依存するスキャナーがスキップされた場合)、結果の JSON に skippedScanners 配列が含まれるようになりました。これは、スキップされたスキャナーが従来は表示されずに除外されていた動作に代わるものです。
署名キーの整合性(v0.9.66 以降)
gpc preflight signing # Check cert consistency across two most recent bundles
gpc preflight signing --json # JSON output for CI
gpc preflight signing --app com.example.app # Override package name
Play API(generatedApks.list)を介して、直近 2 つのバンドルバージョンの署名証明書を比較します。認証(サービスアカウントまたは OAuth)が必要です。不一致の場合の終了コードは 6(他の preflight のしきい値超過と同じ)です。API エラーの場合の終了コードは 4 です。
これはオフラインスキャンではありません。Play API を呼び出して編集を作成し、バンドルを一覧表示して、上位 2 つのバージョンコードに対応する生成済み APK を取得し、certificateSha256Fingerprint を比較した後、編集を削除します。
2026年4月のポリシールール(v0.9.65以降)
Google Playの2026年4月15日のポリシー更新で、3つのルールが追加されました。準拠期限は2026年5月15日です。
-
連絡先への広範なアクセス(
contacts-permission-broad):READ_CONTACTS/WRITE_CONTACTSを検出します。Googleは現在、広範なアクセスの代わりにAndroid Contact Pickerを使用することを求めています。両方の権限が指定されていても、検出結果は1件だけ出力されます。ダイヤラー/メッセージアプリの場合は、allowedPermissionsで抑制できます。 -
ジオフェンシングのフォアグラウンドサービス(
geofencing-foreground-service):サービスのforegroundServiceTypeに「location」が含まれ、かつアプリがACCESS_BACKGROUND_LOCATIONを宣言している場合に検出します。Googleは、承認済みのフォアグラウンドサービスのユースケースからジオフェンシングを削除しました。正当なバックグラウンド位置情報の追跡(ナビゲーション、フィットネス)では、"disabledRules": ["geofencing-foreground-service"]で抑制できます。 -
Health Connectの詳細な権限(
health-connect-granular):READ_ALL_HEALTH_DATAを検出します。targetSdk >= 36(Android 16の要件)の場合、重大度はwarning、それ以外の場合はinfoです。health.READ_STEPS、health.READ_HEART_RATEなどの詳細な権限に置き換えてください。
アプリのコンテンツ申告に関する通知(v0.9.94以降)
AABがFOREGROUND_SERVICE*権限をリクエストするたびに、該当する権限を一覧表示してinfo重大度のpolicy-app-content-declarationが発生します。これは、Googleがリリースを受け付ける前に、Play Console → ポリシー → アプリのコンテンツで、対応する「フォアグラウンドサービスの権限」の申告を完了する必要があることを知らせるものです。
通知しかできない理由:申告はPlay Consoleに保存され、Publisher APIでは公開されず、バンドルから読み取ることもできません。Preflightで確認できるのは、アプリが権限をリクエストしていることだけです。フォームに入力したかどうかは確認できません。そのため、--fail-onの設定にかかわらず、実行が失敗することはありません。
これはforeground-service-type-missingと同じチェックではありません。 こちらは<service>要素のandroid:foregroundServiceTypeを確認するもので、startForeground()を呼び出すサービスに必要なマニフェスト要件です。すべてのサービスに正しい型を設定していても、Consoleでの申告がないためにアップロードがブロックされることがあります。このルールは、まさにその組み合わせをきっかけに導入されました。
申告が不完全な場合、アップロードはAPI_DECLARATION_REQUIREDで失敗します(v0.9.94以降)。v0.9.94より前は、同じ失敗がサービスアカウントの権限の問題として報告されていたため、アプリのコンテンツではなく「ユーザーと権限」に誘導されていました。
権限ごとではなく、スキャンごとに1件の検出結果が出力されます。
偽陰性の修正(v0.9.80)
v0.9.80では、スキャナーの精度を改善する4つの修正がリリースされました。
-
testOnly属性の読み取り元:testOnlyスキャナーが、マニフェストの<application>要素からandroid:testOnlyを読み取るようになりました。以前は誤って<manifest>ルートから読み取っていたため、アプリケーションにtestOnly="true"が設定されていても、チェックでは常に検出結果がないと報告されていました。 -
16KBアラインメントスキャナーの対象範囲:16KBページアラインメントスキャナーが、AABに加えてAPK内のネイティブライブラリもチェックするようになりました。以前はAABアーティファクトのみを検査していたため、APKのネイティブライブラリがスキャンされていませんでした。
-
ELFヘッダーの読み取りサイズ:ELFヘッダーの読み取りサイズが256バイトから4096バイトに増えました。読み取りサイズが小さいと、一部のネイティブライブラリ形式には不十分で、アラインメントのチェックが通知なしにスキップされていました。
-
結果の
skippedScanners:skippedScannersで無効化されたスキャナー(または入力不足でスキップされたスキャナー)が、スキャン結果のJSON内のskippedScanners配列に報告されるようになりました。これにより、スキャナーが実行されなかったことをCIで確認できます。
CIへの追加
# GitHub Actions
- name: Preflight
run: gpc preflight app.aab --fail-on error --json > preflight.json
- name: Upload report
if: always()
uses: actions/upload-artifact@v4
with:
name: preflight-report
path: preflight.json
関連スキル
gpc-release-flow— Preflightの合格後にアップロードしてリリースするgpc-ci-integration— PreflightゲートなどのCI/CDパターンgpc-troubleshooting— 終了コード6への対処gpc-security— 認証情報の取り扱いとキーのローテーション