Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d8709fe
Minor updates to snippets for doc restructuring
vinishavathwani Oct 22, 2025
bd8dec6
Initialize preferImmediatelyAvailableCredentials
vinishavathwani Oct 22, 2025
4b34cc0
Update PasskeyAndPasswordFunctions.kt
vinishavathwani Oct 22, 2025
e4388f0
Update PasskeyAndPasswordFunctions.kt
vinishavathwani Oct 22, 2025
9c76fa8
Update libs.versions.toml
vinishavathwani Oct 22, 2025
ed69a7f
Update PasskeyAndPasswordFunctions.kt
vinishavathwani Oct 22, 2025
890ced9
Update PasskeyAndPasswordFunctions.kt
vinishavathwani Oct 22, 2025
181442b
Update PasskeyAndPasswordFunctions.kt
vinishavathwani Oct 22, 2025
55b0415
Update PasskeyAndPasswordFunctions.kt
vinishavathwani Oct 22, 2025
628f1f0
Update jsonSnippets.json
vinishavathwani Oct 22, 2025
66061c9
Minor updates to snippets for doc restructuring
vinishavathwani Oct 22, 2025
232f067
Initialize preferImmediatelyAvailableCredentials
vinishavathwani Oct 22, 2025
5a5dfeb
Update PasskeyAndPasswordFunctions.kt
vinishavathwani Oct 22, 2025
ca3cf29
Update PasskeyAndPasswordFunctions.kt
vinishavathwani Oct 22, 2025
742cbf3
Update libs.versions.toml
vinishavathwani Oct 22, 2025
b91c76d
Update PasskeyAndPasswordFunctions.kt
vinishavathwani Oct 22, 2025
5a17a37
Update PasskeyAndPasswordFunctions.kt
vinishavathwani Oct 22, 2025
3f4ef21
Update PasskeyAndPasswordFunctions.kt
vinishavathwani Oct 22, 2025
0c6812f
Update PasskeyAndPasswordFunctions.kt
vinishavathwani Oct 22, 2025
f084880
Update jsonSnippets.json
vinishavathwani Oct 22, 2025
44e83bb
Update jsonSnippets.json
vinishavathwani Oct 23, 2025
bdc2ba6
Merge branch 'identity-doc-updates' of https://github.com/android/sni…
vinishavathwani Oct 23, 2025
b93d630
Update jsonSnippets.json
vinishavathwani Oct 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ androidx-constraintlayout = "2.2.1"
androidx-constraintlayout-compose = "1.1.1"
androidx-coordinator-layout = "1.3.0"
androidx-corektx = "1.17.0"
androidx-credentials = "1.5.0"
androidx-credentials-play-services-auth = "1.5.0"
androidx-credentials = "1.6.0-beta03"
androidx-credentials-play-services-auth = "1.6.0-beta03"
androidx-emoji2-views = "1.6.0"
androidx-fragment-ktx = "1.8.9"
androidx-glance-appwidget = "1.1.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,23 @@ class PasskeyAndPasswordFunctions(
) {
val requestJson = creationResult.toString()
// [START android_identity_get_password_passkey_options]
// Retrieves the user's saved password for your app from their
// password provider.
// Get password logins from the credential provider on the user's device.
val getPasswordOption = GetPasswordOption()

// Get passkey from the user's public key credential provider.
// Get passkeys from the credential provider on the user's device.
val getPublicKeyCredentialOption = GetPublicKeyCredentialOption(
requestJson = requestJson
)
// [END android_identity_get_password_passkey_options]
var result: GetCredentialResponse
var preferImmediatelyAvailableCredentials: Boolean = false
// [START android_identity_get_credential_request]
val credentialRequest = GetCredentialRequest(
// Include all the sign-in options that your app supports.
listOf(getPasswordOption, getPublicKeyCredentialOption),
// Defines whether you prefer to use only immediately available
// credentials or hybrid credentials.
preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials
)
// [END android_identity_get_credential_request]
runBlocking {
Expand All @@ -92,7 +96,8 @@ class PasskeyAndPasswordFunctions(
val response = credentialManager.prepareGetCredential(
GetCredentialRequest(
listOf(
getPublicKeyCredentialOption,
// Include all the sign-in options that your app supports
getPublicKeyCredentialOption,
getPasswordOption
)
)
Expand Down Expand Up @@ -230,19 +235,19 @@ class PasskeyAndPasswordFunctions(

// [START android_identity_create_passkey]
suspend fun createPasskey(requestJson: String, preferImmediatelyAvailableCredentials: Boolean) {
var isConditional: Boolean = false
val createPublicKeyCredentialRequest = CreatePublicKeyCredentialRequest(
// Contains the request in JSON format. Uses the standard WebAuthn
// web JSON spec.
// Contains the request in JSON format.
requestJson = requestJson,
// Defines whether you prefer to use only immediately available
// credentials, not hybrid credentials, to fulfill this request.
// This value is false by default.
// Defines whether you prefer to use only locally-available
// credentials or hybrid credentials.
preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials,
// Automatically create a passkey if the user does not have one.
isConditional = isConditional
)

// Execute CreateCredentialRequest asynchronously to register credentials
// for a user account. Handle success and failure cases with the result and
// exceptions, respectively.
// Execute createCredential asynchronously to register credentials
// for a user account.
coroutineScope {
try {
val result = credentialManager.createCredential(
Expand Down
65 changes: 33 additions & 32 deletions identity/credentialmanager/src/main/jsonSnippets.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"namespace": "android_app",
"package_name": "com.example.android",
"sha256_cert_fingerprints": [
SHA_HEX_VALUE
"<SHA_HEX_VALUE>"
]
}
}
Expand All @@ -57,14 +57,14 @@
// JSON response format
// [START android_identity_format_json_response_passkey]
{
"id": "KEDetxZcUfinhVi6Za5nZQ",
"id": "<credential ID>",
"type": "public-key",
"rawId": "KEDetxZcUfinhVi6Za5nZQ",
"rawId": "<raw credential ID>",
"response": {
"clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiVDF4Q3NueE0yRE5MMktkSzVDTGE2Zk1oRDdPQnFobzZzeXpJbmtfbi1VbyIsIm9yaWdpbiI6ImFuZHJvaWQ6YXBrLWtleS1oYXNoOk1MTHpEdll4UTRFS1R3QzZVNlpWVnJGUXRIOEdjVi0xZDQ0NEZLOUh2YUkiLCJhbmRyb2lkUGFja2FnZU5hbWUiOiJjb20uZ29vZ2xlLmNyZWRlbnRpYWxtYW5hZ2VyLnNhbXBsZSJ9",
"authenticatorData": "j5r_fLFhV-qdmGEwiukwD5E_5ama9g0hzXgN8thcFGQdAAAAAA",
"signature": "MEUCIQCO1Cm4SA2xiG5FdKDHCJorueiS04wCsqHhiRDbbgITYAIgMKMFirgC2SSFmxrh7z9PzUqr0bK1HZ6Zn8vZVhETnyQ",
"userHandle": "2HzoHm_hY0CjuEESY9tY6-3SdjmNHOoNqaPDcZGzsr0"
"clientDataJSON": "<signed client data containing challenge>",
"authenticatorData": "<authenticator metadata>",
"signature": "<digital signature to be verified>",
"userHandle": "<user ID from credential registration>"
}
}
// [END android_identity_format_json_response_passkey]
Expand All @@ -74,40 +74,30 @@
// Json request for creating a passkey
// [START android_identity_create_passkey_request_json]
{
"challenge": "abc123",
"challenge": "<base64url-encoded challenge>",
"rp": {
"name": "Credential Manager example",
"id": "credential-manager-test.example.com"
"name": "<relying party name>",
"id": "<relying party host name>"
},
"user": {
"id": "def456",
"name": "helloandroid@gmail.com",
"displayName": "helloandroid@gmail.com"
"id": "<base64url-encoded user ID>",
"name": "<user name>",
"displayName": "<user display name>"
},
"pubKeyCredParams": [
{
"type": "public-key",
"alg": -7
},
{
"type": "public-key",
"alg": -257
}
],
"timeout": 1800000,
"attestation": "none",
"excludeCredentials": [
{
"id": "ghi789",
"type": "public-key"
},
{
"id": "jkl012",
"type": "public-key"
"id": "<base64url-encoded credential ID to exclude>",
"type": "public-key"
}
],
"authenticatorSelection": {
"authenticatorAttachment": "platform",
"requireResidentKey": true,
"residentKey": "required",
"userVerification": "required"
Expand All @@ -120,16 +110,27 @@
// Json response when creating a passkey
// [START android_identity_create_passkey_response_json]
{
"id": "KEDetxZcUfinhVi6Za5nZQ",
"id": "<identifier>",
"type": "public-key",
"rawId": "KEDetxZcUfinhVi6Za5nZQ",
"rawId": "<identifier>",
"response": {
"clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoibmhrUVhmRTU5SmI5N1Z5eU5Ka3ZEaVh1Y01Fdmx0ZHV2Y3JEbUdyT0RIWSIsIm9yaWdpbiI6ImFuZHJvaWQ6YXBrLWtleS1oYXNoOk1MTHpEdll4UTRFS1R3QzZVNlpWVnJGUXRIOEdjVi0xZDQ0NEZLOUh2YUkiLCJhbmRyb2lkUGFja2FnZU5hbWUiOiJjb20uZ29vZ2xlLmNyZWRlbnRpYWxtYW5hZ2VyLnNhbXBsZSJ9",
"attestationObject": "o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YViUj5r_fLFhV-qdmGEwiukwD5E_5ama9g0hzXgN8thcFGRdAAAAAAAAAAAAAAAAAAAAAAAAAAAAEChA3rcWXFH4p4VYumWuZ2WlAQIDJiABIVgg4RqZaJyaC24Pf4tT-8ONIZ5_Elddf3dNotGOx81jj3siWCAWXS6Lz70hvC2g8hwoLllOwlsbYatNkO2uYFO-eJID6A"
}
"clientDataJSON": "<ArrayBuffer encoded object with the origin and signed challenge>",
"attestationObject": "<ArrayBuffer encoded object with the public key and other information.>"
},
"authenticatorAttachment": "platform"
}
// [END android_identity_create_passkey_response_json]
}

},
{
"SignInJsonRequest":
//Json object sent by server when creating sign-in request
// [START android_identity_create_sign_in_request_json]
{
"challenge": "<your app challenge>",
"allowCredentials": [],
"rpId": "<your app server domain>"
}
// [END android_identity_create_sign_in_request_json]
}
]
}