# Feature Specification: Restricted native signature spoofing **Feature Branch**: `005-restricted-signature-spoofing` **Created**: 2026-09-15 **Status**: Draft **Input**: Advance spoofing after `004` packaging: LAB Play/microG Self-Check and Google auth fail without AXP-style restricted signature spoofing. GOLDEN capture 2026-09-15 is the behavioural oracle. Prefer modern LOS 23.2 / A16 path to the **same end state** as AXP (not Magisk modules). ## First working stack (this phase — before `006`/`007`) This feature closes the **first usable Google-compat stack on LAB**: | Must work in this phase | Owner | |-------------------------|--------| | Official microG + GSF (PRESIGNED, F-Droid-updatable) | `004` packaging + `005` ship | | Patched Phonesky priv-app (project-signed, disable/enable OK) | `004` + `005` ship | | Restricted spoofing (Developer Options + grants) | **`005` core** | | Self-Check correct signature + Play auth (no API-console mismatch) | **`005`** | | Modern network location (BeaconDB / Ichnaea-compatible URL; not Déjà Vu NLP) | `005` validation / docs | | `004` packaging leftovers that block a clean flashable zip | **`005` ship gate** (`REPLACE_PREBUILT`, Play FGS privapp) | **Explicitly later (do not pull forward):** - `006` — Insular / Yuh / Swissquote banking hard-gates - `007` — KernelSU-Next / SusFS / root hide ## User Scenarios & Testing *(mandatory)* ### User Story 1 - Developer Options master switch (Priority: P1) As the developer (and later daily-driver user), I can enable **Allow signature spoofing** under Developer Options. When off, spoofing has no effect even if per-app grants remain. When on, authorized apps may use spoofing after grant. **Why this priority**: Matches GOLDEN/AXP (`settings secure allow_signature_fake`) and constitution (not unrestricted platform fake-signature). **Independent Test**: On LAB build with `005`, toggle the setting; read `settings get secure allow_signature_fake` (0/1); confirm UI strings exist. **Acceptance Scenarios**: 1. **Given** a `005` build on LAB, **When** Developer Options is opened, **Then** a **Signature spoofing support** category exposes **Allow signature spoofing** (AXP-equivalent UX). 2. **Given** the toggle is OFF, **When** an app holds a prior spoofing grant, **Then** spoofing has **no effect** (same as AXP documented behaviour). 3. **Given** the toggle is ON, **When** `settings get secure allow_signature_fake` is read, **Then** the value is `1`. --- ### User Story 2 - microG + Phonesky Self-Check signatures (Priority: P1) As the developer, with global spoofing ON and spoofing permission granted to microG GmsCore and patched Phonesky, microG Self-Check marks **correct signature** for both `com.google.android.gms` and `com.android.vending` (Companion/Play Store line), not only “installed”. **Why this priority**: Unblocks the `004` gap that packaging alone cannot fix; required before Play OAuth works. **Independent Test**: LAB only; no GOLDEN modification; screenshots/log of Self-Check before/after grants. **Acceptance Scenarios**: 1. **Given** `004` packages present and global spoofing ON, **When** `FAKE_PACKAGE_SIGNATURE` is granted to GmsCore and Phonesky, **Then** Self-Check shows positive **correct signature** for both. 2. **Given** Self-Check, **When** the user taps the resolution for correct signature on Play/microG, **Then** a grant path exists (system permission UI or equivalent) — not a missing activity / unknown permission. 3. **Given** global spoofing OFF, **When** Self-Check runs, **Then** correct signature checks fail even if packages are installed. --- ### User Story 3 - Play login / auth without API-console mismatch (Priority: P1) As the developer, after spoofing is enabled and granted for Phonesky, Google account sign-in in Play no longer fails with `UNREGISTERED_ON_API_CONSOLE` / “SHA-1 certificate fingerprint” mismatch caused by presenting the project signing key as the Play identity. **Why this priority**: Owner-observed LAB failure; AXP GOLDEN works with spoofing. **Independent Test**: LAB logcat during Play sign-in; compare to pre-`005` failure mode. **Acceptance Scenarios**: 1. **Given** spoofing ON + Phonesky granted, **When** signing into Play, **Then** auth token acquisition does not fail with `UNREGISTERED_ON_API_CONSOLE` due to project cert fingerprint. 2. **Given** Play update prompts that AXP intentionally blocks, **When** the user tries in-app self-update, **Then** failure remains acceptable (out of scope to enable stock Play self-update). --- ### User Story 4 - Restricted allow-list only (Priority: P1) As the project owner, spoofing is **not** a general capability for arbitrary apps. Only explicitly authorized packages/signers may obtain effective spoofing (at minimum official microG GmsCore and project-signed patched Phonesky). **Why this priority**: Constitution: native, restricted, auditable; no LSPosed. **Independent Test**: Attempt spoofing from a third-party test APK that requests `FAKE_PACKAGE_SIGNATURE` without being allow-listed → denied. **Acceptance Scenarios**: 1. **Given** global spoofing ON, **When** a non-authorized app requests spoofing, **Then** it cannot effectively impersonate Google/platform signatures. 2. **Given** documentation, **When** reviewed, **Then** the authorized set and how to extend it are written (for future packages if needed). --- ### User Story 5 - Survives without root (Priority: P2) As the developer, microG and Phonesky spoofing keep working when optional root / Zygisk-style functionality is unavailable (Compatibility MVP is rootless). **Why this priority**: Constitution Compatibility MVP ends at `006` rootless. **Independent Test**: LAB build without Magisk/KSU; spoofing + Self-Check still pass. **Acceptance Scenarios**: 1. **Given** no Magisk/KSU on the `005` validation build, **When** spoofing is configured, **Then** Self-Check signature lines and basic Play auth path still succeed. --- ### User Story 6 - First working stack ship gate (Priority: P1) As the developer, one LAB flash of the `005` validation build includes a **complete** first stack: packaging fixes from `004` that never landed in a clean zip, spoofing, and documented modern location setup — without waiting for banking (`006`) or root (`007`). **Why this priority**: Owner: this phase must work before later features. **Independent Test**: Single zip flash on LAB; follow quickstart; no Magisk/KSU. **Acceptance Scenarios**: 1. **Given** the `005` artifact zip, **When** flashed to LAB, **Then** Phonesky registers (`pm path`) without remount hacks; APK signatures verify (no PRESIGNED strip). 2. **Given** that build, **When** spoofing is configured per quickstart, **Then** Self-Check signature lines and Play auth meet SC-003/SC-004. 3. **Given** microG Location settings, **When** configured for a modern Ichnaea-compatible endpoint (BeaconDB), **Then** the procedure is documented and does not depend on legacy UnifiedNlp backend APKs. --- ### Edge Cases - Stock LOS 23.2 tree on `rom-dev01` has **no** `FAKE_PACKAGE_SIGNATURE` / `allow_signature_fake` (inventory 2026-09-15) → must port/adapt from AXP/EXTENDROM patterns, not “enable a hidden LOS flag”. - Phonesky privapp XML on AXP binds permissions to **cert SHA-256 digest**; our project digest differs from AXP’s — XML must use **our** digest. - Play 52.x FGS / privapp extras (`FOREGROUND_SERVICE_SYSTEM_EXEMPTED`, etc.) remain packaging/`004` follow-ups; `005` must not regress them. - Disabling Play via App info remains supported (owner: useful on AXP). - Island/work profile: spoofing grants may need to exist per user — verify at least owner user 0 for P1; note multi-user as follow-up if broken. ## Requirements *(mandatory)* ### Functional Requirements - **FR-001**: ROM MUST provide a Developer Options control equivalent to AXP **Allow signature spoofing**, persisted as a global setting (GOLDEN: `settings secure allow_signature_fake`). - **FR-002**: ROM MUST define and enforce `android.permission.FAKE_PACKAGE_SIGNATURE` (or AOSP-equivalent restricted spoofing permission) so PackageManager can honour `meta-data fake-signature` for authorized packages when the global toggle is ON and the permission is granted. - **FR-003**: Spoofing MUST be restricted to an explicit allow-list of packages and/or signers; at minimum `com.google.android.gms` (official microG signer) and `com.android.vending` (project Phonesky signer). Unrestricted spoofing is forbidden. - **FR-004**: With toggle ON and grants present, microG Self-Check MUST report positive **correct signature** for GmsCore and Phonesky/Play. - **FR-005**: With toggle ON and Phonesky granted, Play account auth MUST NOT fail with `UNREGISTERED_ON_API_CONSOLE` caused by exposing the project signing certificate as Play’s identity. - **FR-006**: Spoofing MUST NOT depend on Magisk, Zygisk, LSPosed, or other root modules. - **FR-007**: Behaviour and UX SHOULD match GOLDEN/AXP where compatible with Android 16 / LOS 23.2; if the AXP patch set does not apply cleanly, redesign the path to the **same end state** and record deltas in `docs/a15-a16-delta.md`. - **FR-008**: Validation MUST be LAB-only (`11231JEC207477`); GOLDEN remains sample-only. - **FR-009**: Implementation MUST be attributable (source-linked patches / EXTENDROM/AXP/LOS references); no opaque megapatch. - **FR-010**: The `005` validation build MUST incorporate outstanding `004` packaging fixes required for a clean flashable image: PRESIGNED APKs installed via replace-prebuilt (no v2/v3 strip), and Phonesky privapp entries needed for Android 16 / Play 52 FGS (e.g. system-exempted foreground service + exact alarm) so Play does not crash on setup/download services. - **FR-011**: First-stack validation MUST document modern microG network location configuration (Ichnaea-compatible service URL such as BeaconDB); MUST NOT require shipping legacy UnifiedNlp backend packages (Déjà Vu, Nominatim NLP apps). ### Key Entities - **Global spoofing toggle**: User-facing Developer Options switch; gates all spoofing effect. - **Spoofing permission**: Per-app dangerous/runtime-style permission the user (or approved default path) grants to authorized packages. - **Authorized package set**: microG GmsCore + patched Phonesky (extensible later under constitution rules). - **Oracle capture**: `.local-artifacts/002-golden/20260915-spoofing-phonesky/` (settings, `er_*` XMLs, framework strings, dumpsys grants). ## Success Criteria *(mandatory)* ### Measurable Outcomes - **SC-001**: On LAB, Developer Options exposes the spoofing master switch; `allow_signature_fake` reads `1` when enabled. - **SC-002**: `pm` / permission APIs show `FAKE_PACKAGE_SIGNATURE` defined; grants visible for GmsCore and Phonesky when configured. - **SC-003**: microG Self-Check shows **correct signature** checked for GmsCore and Play/Companion within one configuration session after flash. - **SC-004**: Play sign-in logcat no longer shows `UNREGISTERED_ON_API_CONSOLE` fingerprint mismatch for Phonesky under the spoofed identity. - **SC-005**: A non-allow-listed test app cannot obtain effective Google signature spoofing with the global toggle ON. - **SC-007**: One LAB flash of the `005` zip boots without remount overlays for Phonesky; `apksigner verify` equivalent on-device package is registered; Play does not crash-loop on VpaService/DownloadService for missing FGS privapp allowlist entries. - **SC-008**: Quickstart includes BeaconDB (or successor) location steps; Self-Check / location UI does not depend on empty UnifiedNlp backend lists. ## Assumptions - `004` packaging (PRESIGNED `LOCAL_REPLACE_PREBUILT_APK_INSTALLED`, Phonesky patch with `fake-signature`, privapp XMLs) remains the base; `005` does not replace FakeStore for Play. Unmerged `004` leftovers ship in the same `005` validation build (single first-stack artifact). - Default for the global toggle is **OFF** until the user enables it (AXP “explicitly enable” model), unless plan proves a safer first-boot prompt. - Official microG continues to update via F-Droid same-signer; Phonesky via project JKS. - Primary patch reference: AXP/EXTENDROM signature spoofing + GOLDEN 2026-09-15 capture; inventory shows stock LOS 23.2 lacks these hooks. Spoofing MUST also cover modern `PackageInfo.signingInfo` (not only legacy `signatures[]`). - Play self-update remaining broken/blocked is acceptable (AXP parity). - Multi-user/Island spoofing parity is best-effort for P1 (user 0 first). - MLS (Mozilla Location Service) is retired; BeaconDB (or documented successor) is the modern network-location endpoint for microG 0.3.x. ## Out of Scope - KernelSU / Magisk / DenyList (`007`) - Banking Insular hard-gates / Yuh / Swissquote (`006`) - Call recording / FLAG_SECURE (`008`/`009`) - Changing Phonesky to Google’s proprietary signer - Unrestricted signature spoofing for all apps - Reintroducing UnifiedNlp backend APKs as the primary location design