← All posts

APP UPDATES & COMPATIBILITY

Google Play Zero-Tap Sign-In: Restore User Sessions After a Device Change

Last reviewed against current Google Play Console Help and Android Developers documentation.

Changing phones has always meant one guaranteed chore: opening every app and signing in again. For users that is a mild annoyance; for apps it is churn — accounts abandoned at the first login screen and password-reset tickets. Google Play has made fixing that a requirement: apps that support sign-in must support Zero-Tap Sign-In restoration when a user moves to a new Android device and restores their data, using Android's Restore Credentials API as the primary mechanism. This guide covers what the requirement says, how the API works, and how to test both restore paths before you ship.

A signed-in session moving from an old Android device to a new one On the old device the user is signed in and a restore key is created and backed up. On the new device the user opens the app and is already signed in, with no password entry. The session moves; the login screen does not appear OLD DEVICE Signed in restore key created key backed up cloud or D2D transfer NEW DEVICE Already signed in no password entry The restore key proves identity; your backend still decides whether to issue a session.
Figure 1 — Restore Credentials moves a cryptographic key, not a password, and the server still verifies every claim.

Quick answer: what developers need to know

  • The requirement: apps with optional or mandatory sign-in must restore the user's session after a device-to-device transfer or cloud restore.
  • The recommended method is the Android Restore Credentials API, from Android 9 (API level 28).
  • The timing is Google's announced April enforcement deadline — announced, not yet enforced.
  • A restore key is not a password. It is a WebAuthn-style credential, transferred by Play services, that your backend verifies before issuing a session.
  • Two restore paths are needed: a background attempt in BackupAgent.onRestoreFinished() plus a foreground fallback, because the background path depends on allowBackup="true".
  • Push tokens are not restored. Fetch a fresh FCM token, or notifications stay silent until the app is opened.

What Zero-Tap Sign-In actually means

A restore credential — also called a restore key — can be saved locally or backed up to a cloud provider and used to provision access on the user's new device. Google describes the outcome simply: users get their app accounts restored and are signed in the first time they open the app after setting up a new device.

This is not the same as restoring app data. Backup restores preferences, drafts and databases; it does not prove who the user is. A restore key establishes identity so a session can be issued, and carries no user-facing secret. Use both — identity with Restore Credentials, state with Auto Backup — while excluding raw auth tokens and Keystore ciphertext from backup.

Why Google introduced the requirement

Google frames it as a device-migration problem: silent restoration removes extra login screens and recovery prompts, cutting drop-off on upgrades. The developer benefit is that an app authenticated from first launch reaches the user with notifications immediately, without a login wall.

Which apps are affected — and who is exempt

The scope is stated precisely: apps that support user sign-in, whether optional or mandatory. If your app has no account system at all, this requirement asks nothing of you.

Item Official position What to check
Scope Apps with optional or mandatory sign-in, restored via D2D transfer or cloud backup Account system? Both restore paths?
Recommended API Restore Credentials API, Android 9 (API level 28) and above Credential Manager and Play services versions
Timing Google's announced April enforcement deadline Treat as upcoming; plan the work
Form factors Mobile and tablet only No cross-category restore (Wear OS, TV, Auto, XR, ChromeOS)
Games Out of scope; single-account games are encouraged to use the API Confirm scope before committing engineering time
Enterprise Permanently private and enterprise device-management apps are outside scope; Block Store integrations restoring sign-in state by Google's published cutoff are compliant Confirm your distribution model and the cutoff date
Regulated apps Apps under strict regulatory mandates may be eligible for exemption via a Play Console request before enforcement Submit the request early if this applies

What the Restore Credentials API is

Restore Credentials is a feature of Credential Manager, Android's unified authentication API. The relationship explains both the implementation and the server work:

  • Credential Manager is the client-side entry point. The same object handles passkeys, passwords and Sign in with Google; Restore Credentials is one more credential type inside it.
  • The server side is WebAuthn. The cryptographic validation matches passkeys, so existing WebAuthn registration and assertion endpoints can be reused.
  • Restore keys are not passkeys. Store them with a distinct credential flag so they stay hidden from passkey management screens and exempt from user-verification checks.

Compatibility is explicit: Android 9 (API level 28), Play services core version 242200000, and androidx.credentials 1.5.0 or higher. Where Play services is missing or too old, catch CreateCredentialProviderConfigurationException and GetCredentialProviderConfigurationException and fall back to standard sign-in.

How the restore credential lifecycle works

Google describes a three-stage lifecycle across old and new device, each with a different failure mode.

Three-stage Restore Credentials lifecycle Stage one creates the restore key on the old device. Stage two transfers and retrieves the key on the new device. Stage three sends the assertion to the backend, which verifies it and issues a new session. Three stages, three places to fail A key that is never created cannot be restored. 1 Create the restore key After sign-in, and on launch if already signed in. Server sends creation options; app calls createCredential(); server stores the public key and the app records a local sync flag. 2 Transfer and retrieve Play services moves the key by cloud backup or D2D transfer. The app fetches a userless challenge and calls getCredential() with a single GetRestoreCredentialOption. 3 Verify, then issue a session The assertion goes to your backend, which verifies the signature and only then issues a new session token.
Figure 2 — Creation, transfer and retrieval, and server verification. The client never decides on its own that the user is signed in.

Stage 1 — Create the key on the old device

Cover every route into a signed-in state, because an active user with no restore key cannot be restored later: create the key on sign-in or registration, and on startup when already signed in.

Two details cause most trouble. First, store a sync flag such as has_synced_restore_credential to avoid calling createCredential() on every launch — but exclude it from backup, or Auto Backup copies true to the new device and stops it generating its own key. Second, call with isCloudBackupEnabled = true and fall back to false only on E2eeUnavailableException; reversing that order produces a key that transfers over a cable but is missing after a cloud restore.

Stage 2 — Retrieve on the new device

The retrieval request is unusual: the app does not yet know who the user is, so the challenge endpoint must be unauthenticated. Send allowCredentials empty or omit it, and use the userHandle in the response to identify the account.

Two constraints trip people up. Never combine GetRestoreCredentialOption with another option — that throws an IllegalArgumentException. And set userVerification to "discouraged": restoration is silent, so the authenticator data your server receives carries uv = false.

Stage 3 — Verify and issue a session

Send the assertion to your backend, which must verify the cryptographic proof and issue a new session token — not flip a local flag.

Implementation architecture

How the pieces of a Restore Credentials integration fit together The app calls Credential Manager, which is backed by Google Play services and the platform backup system. The app talks to its own backend, which performs WebAuthn verification before issuing a session. Who does what Your Android app createCredential() getCredential() Credential Manager credential type and API surface your app calls Google Play services holds and transfers the key Backup system BackupAgent.onRestoreFinished() Your backend — WebAuthn relying party issues creation and request options, verifies the assertion signature, accepts uv = false, then issues a session token The only component that can grant access
Figure 3 — Credential Manager and Play services handle the key. Your backend remains the only authority that can issue a session.

Backend verification and security

Restore Credentials is a WebAuthn flow, so the security properties depend on your server, not your app.

Verify the signature, always. The assertion carries authenticator data and a signature over a server-issued challenge. A backend that trusts a client-supplied user identifier, or a local "signed in" flag, has turned a cryptographic proof into a claim anyone can fake.

Accept uv = false for restore keys only. Restoration is silent, so user verification is not performed. Keep that exemption scoped to restore-key assertions rather than weakening passkey verification.

Keep restore keys out of user-facing passkey lists. Tag them with a distinct credential flag so they never appear in passkey management screens.

Allow several keys per user, with a TTL. A user may have a phone and a tablet, so support multiple active keys per account — keyed by device or installation ID — rather than overwriting one row. Uninstalling the app deletes the local key without telling your server, so retain keys long enough to survive an upgrade window and prune by inactivity.

Restore keys versus normal sign-in

Aspect Normal manual sign-in Credential restoration
User experience User types or selects credentials on the new device Silent; no prompt in the normal path
Device migration Same friction as any first login Works after cloud restore or D2D transfer, subject to the conditions below
Backend verification Password or passkey assertion verified WebAuthn assertion verified, with uv = false accepted
Fallback required None — it is the fallback Yes: no key, old Play services, managed profile, offline restore
Sign-out behaviour Session token cleared Session token and restore key must both be cleared

Note the last row: restoration is not unconditional. It depends on a key having been created, on current Play services, on the user having restored data, and on your backend accepting the assertion. A user who skips restore, or installs fresh with no backup, sees a normal login.

Background restoration and foreground fallback

Google specifies two tiers, and the reason is android:allowBackup: Play services transfers the restore key regardless of that flag, but the background sign-in only runs when backup is enabled and a backupAgent is declared. Studio's cloud-backup test also needs allowBackup="true"; device-to-device does not.

Implement both: the background pass means sync and push resume before the user opens the app, and the foreground fallback — getCredential() from lifecycleScope before showing the login screen — covers allowBackup="false" and offline restores. Override onRestoreFinished(), not onRestore(), which only serves legacy key-value backups, and set android:fullBackupOnly="true" if you add a BackupAgent to an app already using Auto Backup. Then register a fresh FCM token: push tokens are not restored with the credential, so confirm delivery again using our Android push notification testing checklist.

Testing Restore Credentials in Android Studio

Google documents two testing shapes: a source device plus a target device, or a single device where you back up, uninstall, reinstall and restore. Cover more than one API level, since minimum and target SDK differences change which Play services version you are really testing against.

Backup and restore testing sequence in Android Studio Sign in on the source device, run Backup App Data choosing Device to Device or Cloud, then reinstall or move to the target device, restore app data, and confirm an authenticated session. The four-step test loop 1. Sign in key is created 2. Back up D2D or Cloud 3. Reinstall or new device 4. Restore signed in Test Tier 1 without opening the app first Set Run > Edit Configurations > Launch Options > Launch to Nothing, then restore. Opening the app first sends you to the login screen, because the key has not reached the device yet.
Figure 4 — The Android Studio loop, including the launch configuration that lets you observe background-only restoration.

Prerequisites: Android Studio Otter or higher; a virtual or physical device on Android 9 (API level 28) with a Google Play system image and Play services 242200000; a Google Account with a screen lock set, so cloud end-to-end encryption is active; and a debuggable build.

The flow: sign in, use Backup App Data on the running device window, choose Device to Device or Cloud, then uninstall and reinstall (or install on the second device) and use Restore App Data. Confirm in Logcat that onRestoreFinished() retrieved the credential, or just open the app and check you are signed in.

Command line and CI: use bmgr for headless testing — bmgr enable true, bmgr backupnow <package>, bmgr list sets, bmgr restore <token> <package> — or JUnit 5 host tests with BackupRestoreController to cover CLOUD_ENCRYPTED and DEVICE_TO_DEVICE.

Cloud backup versus device-to-device testing

Aspect Cloud backup Device to device
Setup Google Account, backup enabled, screen lock Two devices, or one with uninstall/reinstall
Studio test needs allowBackup Yes No
What to verify Key arrives, backend accepts uv = false, session issued Same, plus that the key moved without cloud backup
Known limitation Returns nothing if E2EE is unavailable or the user opted out Does not exercise the cloud-specific failure modes

Common problems and troubleshooting

Log the device model, API level, Play services version and whether a key was created before you debug. Following a reproducible bug report template stops the same restore failure being rediscovered by every tester.

Symptom Likely cause Safe investigation step
No restore credential on the new device Key never created, or created only after sign-out Confirm createCredential() runs on sign-in and launch; check the sync flag
Restore silently does nothing Play services older than 242200000 Check the GMS version; catch the provider-configuration exceptions and fall back
Works over cable, fails after cloud restore Key created with isCloudBackupEnabled = false Confirm you pass true first and only fall back on E2eeUnavailableException
E2eeUnavailableException thrown No cloud backup or no screen lock Retry with isCloudBackupEnabled = false so D2D still works
Backend rejects the assertion Verifier requires uv = true, or the challenge came from elsewhere Accept uv = false; verify challenge issuance and origin
IllegalArgumentException on retrieval GetRestoreCredentialOption combined with another option Send a request containing only the restore option
Signed out, but still restored next launch Only the session was cleared, not the restore key Perform the dual clear and delete the local sync flag
No restoration in a managed work profile Enterprise policy blocks cross-device credential transfer Fall back to standard sign-in; not a bug

Pre-release checklist

  • Key creation covered on every entry point: sign-in, registration, and app launch when already signed in.
  • Sync flag excluded from backup so the new device still generates its own key.
  • isCloudBackupEnabled = true first, with the local-only retry on E2eeUnavailableException.
  • Background tier implemented in onRestoreFinished(), with fullBackupOnly set if you already use Auto Backup, plus a foreground fallback.
  • Backend verifies signatures and accepts uv = false for restore keys only.
  • Restore keys flagged separately from passkeys and hidden from passkey management, with multiple active keys per user allowed.
  • Dual clear on sign-out, plus removal of the local marker.
  • Fresh FCM token registered after restoration.
  • Both restore paths tested: cloud and device-to-device, single-account and multi-account, managed profile if relevant.

Frequently asked questions

Is this requirement already enforced?

Google describes it as taking effect from its announced April enforcement deadline. Treat it as a published upcoming requirement and plan the work.

Do we need passkeys to use Restore Credentials?

No. Your client app can support restore keys without user-facing passkeys; you need a WebAuthn-capable relying party server, and an existing passkey setup can reuse its endpoints.

Why does allowBackup="false" still restore on some devices?

Because key transfer is independent of that flag: Play services moves the RestoreCredential pair over encrypted cloud backup or local D2D regardless. The flag only affects background sign-in and Studio's cloud test.

Does this work when moving from a phone to a tablet?

Yes, on phones, foldables and tablets on Android 9 or higher with current Play services. Cross-category restoration — to Wear OS, TV, Auto, XR or ChromeOS — is not supported.

Our app is a game — does this apply?

Google states games are out of scope, with dedicated guidance for complex gaming authentication coming. For single-account games it encourages the API anyway.

Conclusion

Google Play Zero-Tap Sign-In turns a long-standing annoyance into an engineering requirement: after a device migration with data restore, an app that supports sign-in should already know who the user is.

The implementation is narrower than it looks. Create a restore key on every path into a signed-in state, back it up with cloud enabled and fall back to local-only when end-to-end encryption is unavailable, retrieve it with a single userless request, and let your backend verify the assertion before issuing a session. Test both restore paths, because the background tier depends on allowBackup while key transfer does not. What teams most often miss is unglamorous: the sync flag leaking into backup, tokens not re-registered, and sign-out clearing the session but leaving the key behind.

Official sources

Requirements, library versions and supported platforms change over time. Verify current details in the documentation linked above before making release decisions.

Ready for your 12 testers?

Stop reading — start testing. Real people on real devices, 14 days, zero chasing.

WhatsApp