Using Android’s new Credential Manager API

Priya Sindkar
Novumlogic
Published in
7 min readApr 20, 2023
Photo by Franck on Unsplash

Android’s new Credential Manager API provides a seamless way for your app’s users to login to your apps with one-click solutions.

Credential Manager is a Jetpack API that supports multiple sign-in methods, such as username and password, passkeys, and federated sign-in solutions (such as Sign-in with Google) in a single API, thus simplifying the integration for developers.

Furthermore, for users, Credential Manager unifies the sign-in interface across authentication methods, making it clearer and easier for users to sign into apps, regardless of the method they choose.

Thus, by using the Credential Manager API, our app can-

  1. Save user’s credentials like- username and password when they first login/register with our app.
  2. Secure the saved credentials with Google Password Manager (which syncs the saved credentials with the google account selected by the user while saving).
  3. Offer one-click login to the registered users when they again come to sign-in into our app either after a long while or from another device with the same google account.

Let’s get started with integrating the Credential Manager API into our app.

There are 2 types of Authentications provided by the Credential Manager API- using Passkeys and using Passwords.

🔐Authentication using passkeys

When using Passkeys users can sign-in in a quick and secure way like by using biometrics, PIN, or Patterns.

Why is it quicker and how is it safe, then?

It is a quicker and safe because- Passkeys rely on WebAuthn (Web Authentication), a standard jointly developed by the FIDO Alliance and the World Wide Web Consortium (W3C), which internally uses public key cryptography to authenticate users.

There is a detailed blog by Android Developers about how to use passkeys. You can check it by following this link.

If you want to deep dive into how passkeys work in general, you can check out this link.

🔐Authentication using Passwords

In this blog, we are going to see how we can use Credential Manager to securely save our app users’ login data using their username and password.

Github Repo (PRs welcomed) for the same can be found here- https://github.com/novumlogic/CredManager

Prerequisites

For using the Credential Manager API your app must be running on Android 4.4 (API level 19) and higher.

Compilation Prerequisites

Some alpha versions (1.2.0-<alpha_version>) of the API run only on certain SDK versions. Check these out here.

I am running Android 14 Beta 1 on my pixel device, so version 1.2.0-alpha03 works on my device. However, I can also run the below mentioned versions and getting seamless experience as well.

Adding Dependencies

Inside your app-level build.gradle file add the following dependencies

dependencies {
implementation "androidx.credentials:credentials:1.0.0-alpha03"
implementation "androidx.credentials:credentials-play-services-auth:1.0.0-alpha03"
}

Interface to let users login/register with our app

Next we need to prepare a simple login/register page for the same to allow users to enter their usernames and passwords in our app.

Login

For First time users

If a user is a first time user for your app, once they are verified (on your server or using the likes of Firebase Authentication), you need to save their credentials with the Credential Manager.

private suspend fun saveCredential(username: String, password: String) {
// verify or register the users on your server
val isVerifiedOrRegistered = networkCallToYourServer(username, password)
.......
.......
}

After verification of the user, the app now saves the credentials like so-

Initialize the Credential Manager

// Use your app or activity context to instantiate a client instance of
// CredentialManager.
val credentialManager = CredentialManager.create(context)

Use CreatePasswordRequest to save the user credentails with the Google Password Manager

private suspend fun saveCredential(username: String, password: String) {
......
.......

// after user is verified, create the user credential with Credential Manager
val createResponse = credentialManager.createCredential(
request = CreatePasswordRequest(username, password),
activity = activity,
)

// saved credentials succesfully. Now we can let the user in
}

Handling Exceptions

private suspend fun saveCredential(username: String, password: String) {

// handle exceptions while saving the credentials
try {
val createResponse = credentialManager.createCredential(....)
} catch (e: CreateCredentialCancellationException) {
_errorMessage.value = "User cancelled the save flow"
} catch (e: CreateCredentialException) {
_errorMessage.value = "Credentials cannot be saved"
}
}

After createCredential() is succesful, we can let the user into our app.

Recurring User Login

Now lets discuss the flow of our application when the users need to login to our app again or login from some other device (which has the same google account with which they have already saved their credentials).

To proceed with this flow, we need to evaluate whether the new login is done by-

  1. A new user or
  2. A user who have not saved their credentials with us or
  3. A user who have saved their credentials with us in the past

In the 1st two cases, we need to follow the same procedure as with the First Time Users flow (i.e. verify or register the user and save their credentials with the Credential Manager).

And in the 3rd case, we need to retrieve the saved credentails and directly let the user login to our app without requiring them to enter their username and password.

NOTE- In this case, we do not need to show the username and password TextFields but only the login button.

Re-login

The flow of our app for the 3rd scenario would be like so-

Check whether the credentials are already saved or not

suspend fun signIn(
activity: Activity,
credentialManager: CredentialManager,
username: String,
password: String
): CredManagerResult {
return if (isCredentialsSaved(activity, credentialManager) != null) {
// 3rd case
getCredential(activity, credentialManager)
} else {
// 1st two cases
saveCredential(activity, credentialManager, username, password)
}
}

Initialize the Credential Manager like before. (Reuse the same instance)

Initialize the password authentication option

// Retrieves the user's saved password for your app from their
// password provider.
val passwordOption = GetPasswordOption()

Fetch the password credentails and return them

private suspend fun getCredential(): PasswordCredential? {
// Get only the password credentials
val getCredRequest = GetCredentialRequest(listOf(passwordOption))

// Shows the user a dialog allowing them to pick a saved credential
val credentialResponse = credentialManager.getCredential(
request = getCredRequest,
activity = activity,
)
// Return the user choosen credential
return credentialResponse.credential as? PasswordCredential
}

Handling Exceptions

private suspend fun getCredential(): PasswordCredential? {
try {
val getCredRequest = GetCredentialRequest(....)
val credentialResponse = credentialManager.getCredential(....)
return ...
} catch (e: GetCredentialCancellationException) {
_errorMessage.value = "User cancelled the request"
return null
} catch (e: NoCredentialException) {
_errorMessage.value = "Credentials not found"
return null
} catch (e: GetCredentialException) {
_errorMessage.value = "Error fetching the credentials"
return null
}
}

After getCredential() is succesful, login your user into our app.

That’s All Folks!

📝 Credential Manager API still in Alpha

This API is still in alpha and I have faced an issue with using the latest version to this date. I have logged the same with the official issue tracker. It can be found here.

🔩 Some loose ends still to connect

I mentioned in the blog that we show username-password fields for first time users to ask them to save credentials and show only login button to use one of the saved credentials from the API.

But there is, till now, no way to check if there are some saved credentials to determine our app’s flow. Shall we use the GetPasswordOption() or call the GetCredentialRequest() method to confirm this? Or the API team is planning to add more support for this? All this is still unclear as of now.

PS: For now, I used getCredential() to determine if there are some saved credentails or not. But that opens the dialog to choose saved credentials and do not let us direct the flow as we need. I have created an issue for the same here. This flow is still not 100% optimized in the demo app I made 😕, thus PRs to it are welcomed! 🙌

👩‍🏫 Educate users how to delete the saved passwords anytime

As developers, we all know that the saved passwords are indeed secure with Google’s On-Device Password Manager how we can delete the saved passwords easily. But the users may require some knowledge about it. And it is good to educate our users with the steps with which they can feel secure if they want to revert their decision of saving the passwords.

Here are the steps to delete the saved credentials-

  1. Go to settings in your device
  2. Go to Google
  3. Click on ‘Manage your Google Account’
  4. Go to the ‘Security’ tab
  5. Navigate down to the ‘Signing in to other sites’
    Here we can see that Google’s Password Manager has 2 saved passwords. This itself is reassuring of the security. However, if the user still wishes to go ahead and delete the saved passwords,

6. Click on ‘Password Manager’

7. Choose your app (listed under the title of your app’s package name)

8. Delete the saved creds.

✏️To sum up

We saw how Credential Manager is a useful API to provide for a seemless and safe login experience for your app users. We saw the two authentication methods available for us to allow our users to login. And we saw how we can use the username-password authentication method to save and retrieve user Credentials with the Credential Manager to have a seemless login experience as first time logins and recurring logins. The library is still in alpha and I think we should wait for it to mature a bit before using it in our apps.

Meanwhile, we can still use Biometric Authentication to ensure secure logins.

--

--

Priya Sindkar
Novumlogic

Sr. Android Developer 💚 | Believer in neat code and clean architecture | Loves to read | A coder through and through 👩🏻‍💻