Passkeys and Credential Manager

Modern Android Mid-level Kotlin 2.0+ API 24+ Reviewed By Best Latest Apps

Order the steps

Order a passkey sign-in.

  • App sends the response JSON to the server
  • Server verifies the signature and starts a session
  • App calls getCredential with a GetPublicKeyCredentialOption
  • User confirms with fingerprint, face or screen lock
  • Server creates a challenge and request JSON

Choose an answer, then open Show answer below to check it.

Show answer

Answer: E C D A B

  1. Server creates a challenge and request JSON From your WebAuthn server library.
  2. App calls getCredential with a GetPublicKeyCredentialOption Shows the system picker.
  3. User confirms with fingerprint, face or screen lock The passkey signs the challenge.
  4. App sends the response JSON to the server Don't trust it locally.
  5. Server verifies the signature and starts a session Then the app stores tokens securely.

30-second answer

Use Jetpack Credential Manager. One API handles passkeys, saved passwords and Sign in with Google. To register, your server creates a WebAuthn challenge and the app calls createCredential with it; to sign in, call getCredential with passkey and password options, then send the response to your server to verify. It replaces older Smart Lock and legacy Google Sign-In APIs.

Practise saying it · 30 s. No recording, just a timer

Explain passkeys with Credential Manager.

Say your answer out loud, then check which of these points you covered:

  • One API for passkeys, passwords, Google
  • Server challenge
  • createCredential / getCredential
  • Server verifies
  • Digital Asset Links

Deep dive

Passkeys need Digital Asset Links between your app and your website's domain.

The user picks from one bottom sheet for all credential types.

Handle NoCredentialException by offering sign-up or another method.

Passkeys sync through Google Password Manager or other providers.

Requesting a passkey or password Compile-checked · Kotlin 2.4.21
suspend fun signIn(context: android.content.Context, requestJson: String): androidx.credentials.Credential? {
    val manager = androidx.credentials.CredentialManager.create(context)
    val request = androidx.credentials.GetCredentialRequest(
        listOf(
            androidx.credentials.GetPublicKeyCredentialOption(requestJson),
            androidx.credentials.GetPasswordOption(),
        ),
    )
    return try {
        manager.getCredential(context, request).credential
    } catch (e: androidx.credentials.exceptions.NoCredentialException) {
        null
    }
}

Common mistakes

  • Verifying the passkey on the device instead of the server.
  • No assetlinks setup for the relying party.
  • Still building on legacy Google Sign-In.

Senior take & follow-ups

Describe the server challenge flow and the single picker.

Follow-up questions

Think of your answer first, then open the hint.

  1. Why are passkeys phishing-resistant?

    Show hint

    They're bound to the website's domain, so a fake site can't use them.

  2. Where's the challenge created?

    Show hint

    On your server.

Free tool

assetlinks.json validator

Free tool: generate and check your Digital Asset Links file, including the Play App Signing fingerprint that App Links and passkeys need.

Suggest a fix if something here is wrong or out of date.