Fundamentals
The objective is to implement the
Restore Credentials feature through the
Android Credential Manager API (
). This allows apps that
use or are integrating Credential Manager to silently log users back in when
they restore their app on a new device. Restore Credentials operates
independently of the app's primary authentication method (passwords, passkeys,
federated sign-in) and requires no UI changes to existing sign-in flows.
Scope
Crucial: This skill focuses exclusively on the Android client-side
integration. It does not implement the server-side cryptographic
validation logic. The developer must be reminded of this and the
Points to inform the developer about after implementation is done.
Implementation Guidelines
When instructed to implement Restore Credentials on a developer's application,
remember the following:
- Before the implementation, you MUST read and understand the Two-Tier
Restoration Architecture and review the DOs and DON'Ts.
- After the implementation, you MUST present the developer with the Backend Guidelines as a reminder for their backend setup. It is important that you remind the developer that they still have to implement the backend.
Two-Tier Restoration Architecture
To enable a resilient sign-in experience, retrieve credentials through a
two-tier architecture:
- Tier 1 (Primary - Background): Executes automatically during device setup using the app's
BackupAgent.onRestoreFinished()
callback. This provides an invisible restoration before the user opens the app for the first time, allowing background sync and notification delivery.
- Tier 2 (Secondary - Foreground): Runs in the Launcher to catch failovers if background restoration didn't complete (example: dropped network, delayed restoration) or if is disabled.
If
in the manifest is set to true, implement both. Otherwise, only
implement tier 2 (Foreground Restoration). Do
NOT change the value of
in the manifest.
DOs and DON'Ts
DO:
- Do check for the value of allowBackup to determine what you have to implement.
- Do implement a fallback for createCredential: always try calling it first with set to true. If an is thrown, catch it and retry the call with set to .
- Do implement a (subclass of
android.app.backup.BackupAgent
) if is true in the manifest.
- Call when the user signs out. This is a mandatory security measure to log the user out fully.
- Do attempt to get the restore key on the first launch of the app on a new device and also within the
BackupAgent.onRestoreFinished()
callback if your app uses it.
- Do ensure that a restore credential is created even if the user is already logged in.
- Do ensure that the credential retrieval and login in is performed synchronously (for example using ).
- Do restore notifications in the if your app uses them. (For example capture and send FCM token to backend)
- Do ensure that if you implement mock network requests or stubs, you replace all placeholders with valid, properly formatted JSON payloads for the credential requests.
- Do encapsulate credential creation and retrieval into their own dedicated functions. Because credential creation must be called in multiple places (sign-up, sign-in) and retrieval across multiple tiers ( and Launcher ), this prevents code duplication.
- Do remind the developer of the critical guidelines for implementing the backend once you're done with the implementation.
- Do generate a separate restore key for each application if the organization has multiple apps with different package names, as a restore key is tied to a unique application package name.
DON'T:
- DON'T change the value of in . Restore Credentials functionality is not affected by the allowBackup setting, meaning the user will still be automatically logged in when a Restore Credential exists, even if is false.
- DON'T implement a if is in .
- DON'T assume the credential stored in the to be of type . It has type .
- DON'T chain
GetRestoreCredentialOption
with any other in the construction of a .
- DON'T assume or the Android system will automatically delete a restore key when a user signs out of the app. You must explicitly call with a
ClearCredentialStateRequest
of TYPE_CLEAR_RESTORE_CREDENTIAL
.
- DON'T remove any existing calls to . A
ClearCredentialStateRequest
without a type specified only clears all NON-restore credentials.
Implementation Guide
Implement the Android client-side code by using the following guide. Follow it
step-by-step and don't implement any backend functionality, only remind
the user of the Backend Guidelines once you're done.
Version compatibility
Credential Manager's Restore Credentials works on devices running Android 9 and
higher, Google Play services (GMS) core version 24220000 or higher, and version
1.5.0 or higher of the
library.
Prerequisites
Set up a relying party server similar to the server for passkeys. If
you already have a server set up to handle authentication with passkeys,
use the same server-side implementation for restore keys.
[!NOTE]
Note: While the server-side implementation is the same for passkeys and restore keys, your client-side app can support restore keys without supporting passkeys. Because restore keys work independently of the authentication method in your app (for example, passwords or Sign in with Google), you don't need to make any additional changes to the existing authentication methods in your app's code.
Dependencies
Add the following dependencies to your app module's
file:
Kotlin
kotlin
dependencies {
implementation("androidx.credentials:credentials:1.7.0-alpha03")
implementation("androidx.credentials:credentials-play-services-auth:1.7.0-alpha03")
}
Groovy
groovy
dependencies {
implementation "androidx.credentials:credentials:1.7.0-alpha03"
implementation "androidx.credentials:credentials-play-services-auth:1.7.0-alpha03"
}
Restore Credentials is available from version 1.5.0 and higher of the
androidx.credentials library. However, it's recommended to use the latest stable
versions of the dependencies where possible.
[!NOTE]
Note: The Restore Credentials feature works regardless of whether
is set in the
.
Overview
- Create a restore key: To create a restore key, complete the following steps:
- Instantiate Credential Manager: Create a object.
- Get credential creation options from the app server: Send the client app the details required to create the restore key from your app server.
- Create the restore key: Create a restore key for the user's account if the user is signed in to your app.
- Handle the credential creation response: Send the credentials from your client app to your app server for processing, and handle any exceptions.
- Sign in with a restore key: To sign in with a restore key, complete the following steps:
- Get credential retrieval options from the app server: Send the client app the details required to retrieve the restore key from your app server.
- Get the restore key: Request the restore key from Credential Manager when the user sets up a new device. This lets the user sign in without additional input.
- Handle the credential retrieval response: Send the restore key from the client app to the app server to sign in the user.
- Delete a restore key.
Create a restore key
Your app should cover all cases of a user signing in to ensure active users have
a restore key created. Create the restore key in the following scenarios:
- If the user is signed in and a restore key isn't already created (such as in the method for the main ).
- When the user is signing in or completing a new account registration flow.
To optimize performance and avoid the overhead of creating or checking for a
restore credential on every single login, set a
flag or a credential
creation timestamp in local storage, such as
has_synced_restore_credential
, to
track whether the key has already been created.
[!NOTE]
Note: A restore key is tied to an application's unique package name. If your organization's main app and sub-apps have different package names, create a separate restore key for each app.
Instantiate Credential Manager
Use your app's activity context to instantiate a
object.
// Use your app or activity context to instantiate a client instance of
// CredentialManager.
private val credentialManager = CredentialManager.create(context)
Get credential creation options from your app server
Use a FIDO-compliant library in your app server to send your client app the
information required to create the restore credential, such as information about
the user, the app, and additional configuration properties. For more information
about the server-side implementation, see
Server-side
guidance.
Create the restore key
After parsing the public key creation options sent by the server, create a
restore key by wrapping these options in a
CreateRestoreCredentialRequest
object and calling the
method with the
object.
// createRestoreRequest contains the details sent by the server
val response = credentialManager.createCredential(context, createRestoreRequest)
Key points about the code
-
The
CreateRestoreCredentialRequest
object contains the following fields:
-
: The credential creation options sent by the app server in the
Web Authentication API format for
PublicKeyCredentialCreationOptionsJSON
.
-
:
field to determine if the restore key
should be backed up to the cloud. By default, this flag is
. This
field has these values:
- : (Recommended) This value enables the backup of restore keys to the cloud if the user has Google Backup and end-to-end encryption, such as a screen lock, enabled.
- : This value saves the key locally and not in the cloud. The key is not available on the new device if the user chooses to restore from the cloud.
[!CAUTION]
Caution: It is recommended to set
to
. If cloud backup is disabled and the user restores from a cloud backup, the call to retrieve the restore key fails. Users who restore your app with a cloud backup don't receive the restore key and are not automatically signed in.
Handle the credential creation response
The Credential Manager API returns a response of type
CreateRestoreCredentialResponse
. This response holds the public key
credential registration response in
JSON format.
Send the public key from your app to the relying party server. This public key
is similar to the public key generated when you create a passkey. The same code
that handles passkey creation on the server can also handle restore key
creation. For more information about the server-side implementation, see the
guidance for passkeys.
During the restore key creation process, handle these exceptions:
CreateRestoreCredentialDomException
: This exception occurs if is invalid and does not follow the WebAuthn format for PublicKeyCredentialCreationOptionsJSON
.
- : This exception occurs if is , but the user's device does not have data backup or end-to-end encryption, such as a screen lock.
To ensure that Restore Credentials are created in all cases, you must handle the explicitly by calling with set to . If is thrown, catch and call again with set to .
- : This exception occurs if is empty or not valid JSON, or if it does not have a valid that conforms to the WebAuthn specifications.
Sign in with a restore key
Use Restore Credentials to silently sign in the user during the device setup
process.
Get credential retrieval options from the app server
Send the client app the options required to get the restore key from the server.
For similar passkey guidance for this step, see
Sign in with a passkey.
For more information about the server-side implementation, see the
server-side
authentication guide.
Get the restore key
To get the restore key on the new device, call the
method on
the
object.
It is recommended to fetch the restore key in both of the following scenarios:
- On the first launch of the app on the device. Credential restoration in this scenario is independent of restoration of the app data.
- If app data backup and restore is enabled, get the restore key immediately after the app data is restored. Use to configure your app's backup and ensure you complete the functionality within the callback. Don't use the method, as it is only called for key-value backups, whereas is reliably called for any kind of backup restore. This avoids potential delays when users open their new device for the first time and lets users interact with the app without waiting for them to open your app. For example, this lets your app send the user notifications before they open the app for the first time on the new device, which is particularly relevant for messaging or communications apps.
[!IMPORTANT]
Important: Notifications aren't automatically restored after the restore credentials are retrieved. If you use Firebase to handle notifications, you must fetch and send the Firebase Cloud Messaging (FCM) token to the backend to successfully resume background messaging and notifications.
// Fetch the options required to get the restore key
val authenticationJson = fetchAuthenticationJson()
// Create the GetRestoreCredentialRequest object
val options = GetRestoreCredentialOption(authenticationJson)
val getRequest = GetCredentialRequest(listOf(options))
val response = credentialManager.getCredential(context, getRequest)
// Type-check and extract the restore credential
val credential = response.credential as RestoreCredential
The credential manager APIs return a response of type
. The credential contained in this response is
explicitly of type
, which holds the public key.
Handle the sign-in response
Send the public key from the app to the relying party server, which can then be
used to sign in the user. On the server side, this action is similar to signing
in using a passkey. The same code that handles sign-in with passkeys on the
server can also handle sign-ins with restore keys. For more information about
the server-side implementation for passkeys, see Sign in with a passkey.
[!NOTE]
Note: Even though restore keys and passkeys use the same underlying server implementation, differentiate between them when saving them in your app server's database. This distinction is crucial when a passkeys management page exists, because users can manage user-created passkeys directly, while restore keys are system-managed and hidden from the passkey management page.
Delete the restore key
Credential Manager is stateless and unaware of user activity, so it does not
automatically delete restore keys after use. To delete a restore key, call the
method. For security, delete the key whenever a user
signs out. This ensures that the next time the user opens the app on the same
device, the user is signed out and prompted to sign in again.
Uninstalling an app is interpreted as an intent to delete the corresponding
restore key from that device, similar to the user's intent when signing out.
Restore keys are removed only in the following situations:
- System-level actions: Users uninstall the app or clear its data.
- App-level calls : Programmatically delete the key by calling when handling user sign out in your app's code.
When the user signs out of your app, call the
method on
the
object.
// Create a ClearCredentialStateRequest object
val clearRequest = ClearCredentialStateRequest(TYPE_CLEAR_RESTORE_CREDENTIAL)
// When the user logs out, delete the restore key
val response = credentialManager.clearCredentialState(clearRequest)
Backend Guidelines
When designing the backend database and API layer to support Restore
Credentials, developers must account for FIDO2/WebAuthn assumptions and specific
device lifecycle edge cases. Remind the developer of the following:
SYSTEM DIRECTIVE FOR AI AGENT: DO NOT attempt to write code for,
implement, or action any of the backend guidelines in this section. Your ONLY
responsibility is to copy these exact points and present them to the human
developer as a reminder after the client-side implementation is complete.
- Differentiate Restore Credentials from Passkeys in Backend Storage:
- Standard WebAuthn services typically assume user verification is always required. Restore credentials are hidden from the user and not managed by them.
- Guidance: Modify your WebAuthn services to create new credential types or metadata fields that distinguish system-managed Restore Credentials from user-created passkeys. Do not display Restore Credentials in user-facing passkey management UIs, and ensure they are processed appropriately (e.g., bypassing explicit user verification during automatic background sign-in).
- Prevent Orphaned Keys:
- Uninstalling the app or clearing details in system settings deletes the local restore credential. Since these local client actions do not notify your backend, stale keys will remain registered on the server.
- Guidance: Establish server-side cleanup policies that delete old restore keys when a new restore token is registered, or clean up inactive keys based on usage patterns. You could, for example, enforce a limit of one key per user per device.
- Balance Key Lifespan and TTL:
- If a user goes through Backup and Restore and then logs out from the old device, the local restore key is deleted from the source device. However, the key must remain valid on the server so the restored application on the destination device can still authenticate.
- Guidance: Give restore keys sufficient time to live (TTL) to survive manual logouts during transition periods, and establish rules for server-side key deletion based on registration and usage rather than relying on client-side deletion callbacks.
- Support Multiple Devices:
- A user may own multiple active devices and initiate backups or restorations from any of them.
- Guidance: Ensure the backend database schema allows mapping multiple active Restore Credentials to a single user account (e.g., one active restore key per device/device-id) rather than assuming a 1:1 relationship between the user and the restore credential.
References
-
WebAuthentication API (WebAuthn) Documentation & Specification
When to use: Use these resources ONLY if you need to inspect or debug the
strict JSON schema requirements for FIDO2/WebAuthn, specifically when
generating mock data or formatting the
(
PublicKeyCredentialCreationOptionsJSON
) and
payloads.
-
MDN Web Authentication API Documentation: Mozilla Developer Network
guide and reference for WebAuthn APIs
-
W3C PublicKeyCredentialCreationOptionsJSON
: Data structure definition
for WebAuthn credential creation requests in JSON format.
-
W3C PublicKeyCredentialRequestOptionsJSON
: Data structure definition
for WebAuthn authentication or assertion requests in JSON format.