brainstorming
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or planning anything new, in software or out of it (a talk, a business, a renovation).
restore-credentialsProvides knowledge and workflows to implement Android's Restore Credentials feature using the androidx.credentials library. Use this skill to create, sign in with, and delete restore keys, enabling silent user sign-in on new devices after a restore. It covers version compatibility, dependencies, server-side prerequisites, and the complete client-side implem…
Independent GitHub snapshot · Automated classification · Original documentation governs
name: restore-credentials description: Provides knowledge and workflows to implement Android's Restore Credentials feature using the androidx.credentials library. Use this skill to create, sign in with, and delete restore keys, enabling silent user sign-in on new devices after a restore. It covers version compatibility, dependencies, server-side prerequisites, and the complete client-side implementation for creating, retrieving, and clearing restore keys. license: Complete terms in LICENSE.txt metadata: author: Google LLC last-updated: '2026-09-14' keywords:
The objective is to implement the Restore Credentials feature through the
Android Credential Manager API (androidx.credentials). 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.
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.
When instructed to implement Restore Credentials on a developer's application, remember the following:
To enable a resilient sign-in experience, retrieve credentials through a two-tier architecture:
BackupAgent.onRestoreFinished() callback. This provides an invisible restoration before the user opens the app for the first time, allowing background sync and notification delivery.Activity.onCreate() to catch failovers if background restoration didn't complete (example: dropped network, delayed restoration) or if allowBackup is disabled.If allowBackup in the manifest is set to true, implement both. Otherwise, only
implement tier 2 (Foreground Restoration). Do NOT change the value of
allowBackup in the manifest.
If you added a BackupAgent to the app, you MUST also set
android:fullBackupOnly="true" in the manifest. Do NOT do this if there
already existed a BackupAgent in the app before your implementation.
DO:
AndroidManifest.xml for the value of allowBackup to determine what you have to implement.isCloudBackupEnabled set to true. If an E2eeUnavailableException is thrown, catch it and retry the call with isCloudBackupEnabled set to false.BackupAgent (subclass of android.app.backup.BackupAgent) if allowBackup is true in the manifest.android:fullBackupOnly="true" in the manifest if you added a BackupAgent to the app.clearCredentialState() when the user signs out. This is a mandatory security measure to log the user out fully.BackupAgent.onRestoreFinished() callback if your app uses it.onRestoreFinished() is performed synchronously (for example using runBlocking).BackupAgent if your app uses them. (For example capture and send FCM token to backend)BackupAgent and Launcher Activity), this prevents code duplication.DON'T:
allowBackup in AndroidManifest.xml. 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 allowBackup is false.BackupAgent if allowBackup is false in AndroidManifest.xml.GetCredentialResponse to be of type PublicKeyCredential. It has type RestoreCredential.GetRestoreCredentialOption with any other CredentialOption in the construction of a GetCredentialRequest.CredentialManager or the Android system will automatically delete a restore key when a user signs out of the app. You must explicitly call clearCredentialState with a ClearCredentialStateRequest of TYPE_CLEAR_RESTORE_CREDENTIAL.clearCredentialState(). A ClearCredentialStateRequest without a type specified only clears all NON-restore credentials.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.
Credential Manager's Restore Credentials works on devices running Android 9 (API
level 28) and higher, Google Play services (GMS) core version 24220000 or
higher, and version 1.5.0 or higher of the androidx.credentials library.
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.
Add the following dependencies to your app module's build.gradle file:
dependencies {
implementation("androidx.credentials:credentials:1.7.0-alpha03")
implementation("androidx.credentials:credentials-play-services-auth:1.7.0-alpha03")
}
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
allowBackupis set in the manifest.
CredentialManager object.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:
onCreate method for the main Activity).To optimize performance and avoid the overhead of creating or checking for a
restore credential on every single login, set a boolean 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.
Use your app's activity context to instantiate a CredentialManager object.
// Use your app or activity context to instantiate a client instance of
// CredentialManager.
private val credentialManager = CredentialManager.create(context)
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.
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
createCredential() method with the CredentialManager object.
// createRestoreRequest contains the details sent by the server
val response = credentialManager.createCredential(context, createRestoreRequest)
The CreateRestoreCredentialRequest object contains the following fields:
requestJson: The credential creation options sent by the app server in the Web Authentication API format for PublicKeyCredentialCreationOptionsJSON.
isCloudBackupEnabled: Boolean field to determine if the restore key
should be backed up to the cloud. By default, this flag is true. This
field has these values:
true: (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.false: 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's recommended to set
isCloudBackupEnabledtotrue. 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 aren't automatically signed in.
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 requestJson is invalid and does not follow the WebAuthn format for PublicKeyCredentialCreationOptionsJSON.E2eeUnavailableException: This exception occurs if isCloudBackupEnabled is true, but the user's device doesn't have data backup or end-to-end encryption, such as a screen lock.E2eeUnavailableException explicitly by calling createCredential with isCloudBackupEnabled set to true. If E2eeUnavailableException is thrown, catch and call createCredential again with isCloudBackupEnabled set to false.IllegalArgumentException: This exception occurs if createRestoreRequest is empty or not valid JSON, or if it doesn't have a valid user.id that conforms to the WebAuthn specifications.Use Restore Credentials to silently sign in the user during the device setup process.
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.
To get the restore key on the new device, call the getCredential() method on
the CredentialManager object.
It's recommended to fetch the restore key in both of the following scenarios:
BackupAgent to configure your app's backup and ensure you complete the getCredential functionality within the onRestoreFinished callback. Don't use the onRestore method, as it is only called for key-value backups, whereas onRestoreFinished 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.If you create a new BackupAgent and previously had backup enabled with
allowBackup="true", set the boolean value android:fullBackupOnly="true" in
your app's manifest. This ensures that your app's backup and restore behavior is
maintained.
[!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
GetCredentialResponse. The credential contained in this response is
explicitly of type RestoreCredential, which holds the public key.
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.
Credential Manager is stateless and unaware of user activity, so it doesn't
automatically delete restore keys after use. To delete a restore key, call the
clearCredentialState 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.
[!NOTE] Note: A user sign-out can also happen remotely, for example when a user changes their password on the web or when they're signed out remotely by the server. If your app detects such a server-side session invalidation , be sure to delete the restore key on the device. (An example of this is your server returning an HTTP
401 Unauthorizederror)
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:
clearCredentialState() when handling user sign out in your app's code.When the user signs out of your app, call the clearCredentialState() method on
the CredentialManager 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)
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.
401 Unauthorized indicating session expiry.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 requestJson
(PublicKeyCredentialCreationOptionsJSON) and authenticationJson 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.