{"id":348112,"date":"2025-09-15T15:59:49","date_gmt":"2025-09-15T20:59:49","guid":{"rendered":"https:\/\/michigandigitalnews.com\/index.php\/2025\/09\/15\/the-evolution-of-wear-os-authentication\/"},"modified":"2025-09-15T15:59:49","modified_gmt":"2025-09-15T20:59:49","slug":"the-evolution-of-wear-os-authentication","status":"publish","type":"post","link":"https:\/\/michigandigitalnews.com\/index.php\/2025\/09\/15\/the-evolution-of-wear-os-authentication\/","title":{"rendered":"The evolution of Wear OS authentication"},"content":{"rendered":"<p> [ad_1]<br \/>\n<\/p>\n<div>\n<meta content=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEieK5NxefEs0wwVBn6fxvkV9nHNxMkU1536dzGGFiIgl5NkaZh5H6yADhtcSG-ZGi8Nu8xpr51qLpoip7wYGgDXobv1j_CMhtURHTrhhh7h3BHDNYh9bOtBW4DhnbizuCnsbIFQPJ9997yRA4ahN9-wHvHe8HUKMDd9puNT_E7vWcNbqkRfalZhXhFgF2s\/s1600\/credential-manager-wear-os%20%282%29.png\" name=\"twitter:image\"\/><br \/>\n<img decoding=\"async\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEieK5NxefEs0wwVBn6fxvkV9nHNxMkU1536dzGGFiIgl5NkaZh5H6yADhtcSG-ZGi8Nu8xpr51qLpoip7wYGgDXobv1j_CMhtURHTrhhh7h3BHDNYh9bOtBW4DhnbizuCnsbIFQPJ9997yRA4ahN9-wHvHe8HUKMDd9puNT_E7vWcNbqkRfalZhXhFgF2s\/s1600\/credential-manager-wear-os%20%282%29.png\" style=\"display: none;\"\/><\/p>\n<p><em>Posted by John Zoeller \u2013 Developer Relations Engineer<\/em><\/p>\n<p><a href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhixN5tFhfrjYWSjcqKvsvrWf-zTFdROS_piAYDWzHHJccNn9zsqNsZbVfSKXVA-LUo4SlE7Cl0NZeR4hls3bzvkK8GDeO0kISiAsjSaGahaAZ9NUMA0vj8kacuSxAxgeqLzszBUcZije6vposhRkREnhmjoxe8GiBfEH9Rt-8H8BnSttUOT21Xw1popRQ\/s1600\/credential-manager-wear-os%20%281%29.png\"><img decoding=\"async\" border=\"0\" data-original-height=\"800\" data-original-width=\"100%\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhixN5tFhfrjYWSjcqKvsvrWf-zTFdROS_piAYDWzHHJccNn9zsqNsZbVfSKXVA-LUo4SlE7Cl0NZeR4hls3bzvkK8GDeO0kISiAsjSaGahaAZ9NUMA0vj8kacuSxAxgeqLzszBUcZije6vposhRkREnhmjoxe8GiBfEH9Rt-8H8BnSttUOT21Xw1popRQ\/s1600\/credential-manager-wear-os%20%281%29.png\"\/><\/a><\/p>\n<blockquote><p><i>This post is part of <a href=\"https:\/\/android-developers.googleblog.com\/2025\/08\/spotlight-week-wear-os.html\" target=\"_blank\" rel=\"noopener\">Wear OS Spotlight Week<\/a>. Today, we&#8217;re focusing on <b>implementing Credential Manager on Wear OS<\/b>, aiming to streamline the authentication experience.<\/i><\/p><\/blockquote>\n<p>For all software developers, crafting a fast and secure authentication flow is paramount, and this is equally important on Wear OS.<\/p>\n<p>The traditional Wear OS methods require users to have their phone nearby to complete authentication, often with a separate mobile flow or 2-factor auth code.<\/p>\n<p><a href=\"https:\/\/developer.android.com\/identity\/sign-in\/credential-manager\" target=\"_blank\" rel=\"noopener\">Credential Manager<\/a>&#8216;s arrival simplifies this process, allowing for authentication directly from a user&#8217;s watch with no need for a nearby phone.<\/p>\n<p>As a unified API, Credential Manager enables you to reuse your mobile app\u2019s code on Wear OS, streamlining development across form factors. With a single tap, users can authenticate with passwords, federated identities like Sign in with Google, or <b><a href=\"https:\/\/developer.android.com\/courses\/pathways\/passkeys\" target=\"_blank\" rel=\"noopener\">passkeys<\/a><\/b>, the new industry standard for security.<\/p>\n<p><image><\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" alt=\"Credential Manager on a wearable device providing the security of passkey authentication\" border=\"0\" id=\"imgCaption\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEif176UuhH2g7k1PSDWiJ8T9vqzmIBE3gzu_NSLalpuOvyz0m0Uzt2e5bxVr7BX4tsxiIEovUREPYl9iOwOwsCfRSuO1Dh5KVyj9vFqug-04QHtWLvyww8j29uyExAmbXNdPwZn_j9yZ-iQ3KkAki45Nhqo6VXtxf-PA9K_GUJTy-vXMHd-5AADywl2by4\/s1600\/credential-manager-passkey-authentication-wear-os.png\" width=\"25%\"\/><\/div>\n<p><imgcaption><center><em>Credential Manager provides the security of passkey authentication with a single tap<\/em><\/center><\/imgcaption><\/image><\/p>\n<h2><span style=\"font-size: x-large;\">The power of passkeys<\/span><\/h2>\n<p>Passkeys are built on the principle of asymmetric encryption. During creation, a system authenticator generates a unique, mathematically linked pair of keys: a public key that is securely stored online with the service, and a private key that remains exclusively on the user&#8217;s device.<\/p>\n<p>When signing in, the device uses the private key to cryptographically prove to the service that it possesses the key.<\/p>\n<p>This process is highly secure because the private key never leaves the device during authorization (only during syncs from credential providers) and can only be used with the user&#8217;s explicit permission. This makes passkeys resistant to server breaches, as a breach could only ever expose the public half of the key pair. Additionally, since there is no passphrase to steal, passkeys are virtually phishing-proof.<\/p>\n<p id=\"designing-authentication-credential-manager\">The user experience of passkeys is seamless: to log in, a user confirms their presence with their device&#8217;s lock (e.g., biometric credential or PIN), and they are signed in. This eliminates the need to remember complex passphrases and provides a faster, more secure method of authentication that works seamlessly across devices.<\/p>\n<p><image><\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" alt=\"flow chart illustrating movement of secured information between the user's device and the app server\" border=\"0\" id=\"imgCaption\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhT2DU2NoahA6Jbif_PM-6KTt9ag4WK14EM5YuDCTcv6nAdBk6_i96NL3rIELfGB_SDV-eyG5pHJVw9zdc09YtLGCw5K1crgAXEY67rbPMjS2rWVOTTib36DP0q1sTFbzmknOG5oaEBY4Inz_m4FMFXQWggAYctBmHqAStXA7R3FhSvICltt_vIPCr9OA4\/s1600\/passkey-authentication-flow-chart-wear-os.png\" width=\"100%\"\/><\/div>\n<p><imgcaption><center><em>Passkeys are cryptographically linked, and accessed securely from user devices<\/em><\/center><\/imgcaption><\/image><\/p>\n<h2><span style=\"font-size: x-large;\">Designing authentication with Credential Manager<\/span><\/h2>\n<p>Credential Manager should be the base of a Wear app\u2019s authentication flow. Developers should decide which of its built-in methods to implement based on what is implemented in their mobile experiences, and based on the variety of authentication methods their users need.<\/p>\n<p>Passkeys are the preferred built-in solution due to their inherent security and simplicity, but the other built-in options Credential Manager provides can also be implemented. Passwords are valuable because of their familiarity to users, and federated identities like Sign in with Google provide users with the comfort of a trusted provider.<\/p>\n<p><image><\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" alt=\"Credential Manager on a wearable device providing the security of passkeys, passwords, and sign in with google\" border=\"0\" id=\"imgCaption\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiSoQ9qqTsmM9FIJ0G5U6eG7xPXv0d14s6y3A4hBrCD-qGTzS1J2EUusAMuTu-i12Jjko5n_yBnyTo5bPDZUe_DX9PWRYZbWjHfRz7mswslwt7lXe4wufAB0F4MEd80SxErf0m4peLbI0TfiPim-epypfZCsuRAhP1_KVOmG74g6RqZmIsMH3pqmXU5rpg\/s1600\/credential-manager-passkeys-passwords-sign-in-with-google-wear-os.png\" width=\"25%\"\/><\/div>\n<p><imgcaption><center><em>Passkeys, passwords, and sign in with google can be provided by Credential Manager<\/em><\/center><\/imgcaption><\/image><\/p>\n<p>Developers should maintain at least one of their existing authentication options as a backup as they transition their users to Credential Manager. If Credential Manager is dismissed by a user, or if all of its methods fail, or if credentials are not available, developers can present their backup options.<\/p>\n<p>The <a href=\"https:\/\/developer.android.com\/training\/wearables\/apps\/auth-wear#fallback-methods\" target=\"_blank\" rel=\"noopener\">Wear Authentication developer guide<\/a> includes details on supported Wear OS backup authentication options. These include solutions like OAuth 2.0, which has traditionally been a popular choice on Wear OS; and data layer token sharing, which can be used to automatically authenticate users at app launch time if their phone is nearby to sync a signed in account.<\/p>\n<p>Read the full <a href=\"https:\/\/developer.android.com\/design\/ui\/wear\/guides\/m2-5\/behaviors-and-patterns\/sign-in#correct-prompting\" target=\"_blank\" rel=\"noopener\">Wear sign-in design guidance<\/a> to learn about all the best practices for designing your authentication flow, including our special guidance around data layer token sharing.<\/p>\n<p><image><\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" alt=\"authentication flow on the left with dismiss highlighted, and sign in flow on the right\" border=\"0\" id=\"imgCaption\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgtIaDmiHhL9-3bQxi5WlLVoPvIWpJ5fXf7tyzgsDSxfA9KfexQPJQ2eqW2yIWJScumgvUwlsweaBDkT273h3T6YGFkklYZ_UX5uzRwwEoQoCVNt8WXTBR1aIe2lSuY5TagaU1vSVPTBTfdSKNyBU4WlWOcV3VRKbGaOjKCiP5yGSolgOgsW73BxEfWlgk\/s1600\/credential-manager-dismiss-wear-os.png\" width=\"100%\"\/><\/div>\n<p><imgcaption><center><em>Tapping dismiss should bring up your backup authentication methods<\/em><\/center><\/imgcaption><\/image><\/p>\n<h2><span style=\"font-size: x-large;\">Implementing Credential Manager on Wear OS<\/span><\/h2>\n<h3><span style=\"font-size: large;\">Basic GetCredential setup<\/span><\/h3>\n<p>At its core, Credential Manager consolidates multiple authentication methods into a single, unified API call: <span style=\"font-family: courier;\"><a href=\"https:\/\/developer.android.com\/reference\/androidx\/credentials\/CredentialManager#getCredential%28android.content.Context,androidx.credentials.PrepareGetCredentialResponse.PendingGetCredentialHandle%29\" target=\"_blank\" rel=\"noopener\">getCredential<\/a><\/span>. By configuring a <span style=\"font-family: courier;\"><a href=\"https:\/\/developer.android.com\/reference\/androidx\/credentials\/GetCredentialRequest\" target=\"_blank\" rel=\"noopener\">GetCredentialRequest<\/a><\/span> with your authentication options, you can use the response to validate a user&#8217;s identity with your app&#8217;s server that contains the credentials, like so:<\/p>\n<p><!--Kotlin--><\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\"><span\/><span style=\"color: green; font-weight: bold;\">val<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #19177c;\">request<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #666666;\">=<\/span><span style=\"color: #bbbbbb;\"> <\/span>GetCredentialRequest(getCredentialOptions())\n<span style=\"color: green; font-weight: bold;\">val<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #19177c;\">getCredentialResponse<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #666666;\">=<\/span><span style=\"color: #bbbbbb;\"> <\/span>credentialManager.<span style=\"color: #687822;\">getCredential<\/span>(activity,<span style=\"color: #bbbbbb;\"> <\/span>request)\n\nlogin(getCredentialResponse.<span style=\"color: #687822;\">credential<\/span>)\n<\/pre>\n<\/div>\n<h3><span style=\"font-size: large;\">Sync Credentials with Digital Asset Links<\/span><\/h3>\n<p>For a truly seamless experience, a user&#8217;s credentials must sync effortlessly from their other devices to their watch, since it is currently not possible to create credentials on Wear OS.<\/p>\n<p>To enable this, you must add an entry for Wear OS in your <b><a href=\"https:\/\/developer.android.com\/identity\/sign-in\/credential-manager#add-support-dal\" target=\"_blank\" rel=\"noopener\">Digital Asset Links<\/a><\/b> to associate your Wear OS app with other versions of your app. Be sure to precisely fill out the asset link entry, including your app&#8217;s <span style=\"color: #0d904f; font-family: courier;\">applicationId<\/span> and the SHA-256 cryptographic hash from your application\u2019s digital signature. You can test them out with our <a href=\"https:\/\/developer.android.com\/training\/app-links\/verify-android-applinks\" target=\"_blank\" rel=\"noopener\">app link verification guide<\/a>.<\/p>\n<h3><span style=\"font-size: large;\">Furnishing <span style=\"color: #0d904f; font-family: courier;\">getCredential<\/span> with built-in credentials<\/span><\/h3>\n<p>To allow users to sign in with Credential Manager, provide <span style=\"color: #0d904f; font-family: courier;\">getCredential<\/span> with options for the three built-in authentication types: passkeys, passwords, and federated identities like Sign in With Google.<\/p>\n<p><!--Kotlin--><\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\"><span\/><span style=\"color: #3d7b7b; font-style: italic;\">\/\/ Adding options is part of creating the credential request<\/span>\nGetCredentialRequest(getCredentialOptions()))\n\n<span style=\"color: #3d7b7b; font-style: italic;\">\/\/ Furnish list of CredentialOptions for the request<\/span>\n<span style=\"color: green; font-weight: bold;\">suspend<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: green; font-weight: bold;\">fun<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: blue;\">getCredentialOptions<\/span>():<span style=\"color: #bbbbbb;\"> <\/span>List<span style=\"color: #666666;\">&lt;<\/span>CredentialOption<span style=\"color: #666666;\">&gt;<\/span><span style=\"color: #bbbbbb;\"> <\/span>{\n<span style=\"color: #bbbbbb;\">  <\/span><span style=\"color: green; font-weight: bold;\">return<\/span><span style=\"color: #bbbbbb;\"> <\/span>listOf(\n<span style=\"color: #bbbbbb;\">    <\/span><span style=\"color: #3d7b7b; font-style: italic;\">\/\/ Passkey: Furnish a GetPublicKeyCredentialOption with public key<\/span>\n<span style=\"color: #bbbbbb;\">    <\/span><span style=\"color: #3d7b7b; font-style: italic;\">\/\/ data from your authentication server<\/span>\n<span style=\"color: #bbbbbb;\">    <\/span>GetPublicKeyCredentialOption(authServer.<span style=\"color: #687822;\">getPublicKeyRequestOptions<\/span>()),\n<span style=\"color: #bbbbbb;\">    <\/span><span style=\"color: #3d7b7b; font-style: italic;\">\/\/ Password: Add the provided GetPasswordOption type in your list<\/span>\n<span style=\"color: #bbbbbb;\">    <\/span>GetPasswordOption(),\n<span style=\"color: #bbbbbb;\">    <\/span><span style=\"color: #3d7b7b; font-style: italic;\">\/\/ Federated Identity: Add your desired option type (GetGoogleIdOption, below)<\/span>\n<span style=\"color: #bbbbbb;\">    <\/span><span style=\"color: #3d7b7b; font-style: italic;\">\/\/ to orchestrate a token exchange with the federated identity server.<\/span>\n<span style=\"color: #bbbbbb;\">    <\/span>GetGoogleIdOption.<span style=\"color: #687822;\">Builder<\/span>().<span style=\"color: #687822;\">setServerClientId<\/span>(SERVER_CLIENT_ID).<span style=\"color: #687822;\">build<\/span>(),\n<span style=\"color: #bbbbbb;\">  <\/span>)\n}\n<\/pre>\n<\/div>\n<p>When <span style=\"color: #0d904f; font-family: courier;\">getCredential<\/span> is called, Credential Manager will use the options developers provide to present users with a UI to choose how they want to log in.<\/p>\n<p><image><\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" alt=\"Credential Selection screen display on a wearable device\" border=\"0\" id=\"imgCaption\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjxMTME6N8xaTBicW_ZuFzVeZj-uzVCkJM6QiVwKROJs5gMvBQKtYN6Tsz9Wf_OyaqubXA9PWWp2EfYGxYe2hMw59sXzCCSNRzJwNoUjV1IQrXb8c_yy_ldnawRbu50X2_lzgMZ-BW5j-2fdOy3FotEXu_dgPiiEurn76HmGxEsTCMtvowzReqVq0cTSVM\/s1600\/credential-selection-screen-wear-os.png\" width=\"25%\"\/><\/div>\n<p><imgcaption><center><em>The Credential Selection Screen displays developer-provided options<\/em><\/center><\/imgcaption><\/image><\/p>\n<h3><span style=\"font-size: large;\">Handling built-in Credential types<\/span><\/h3>\n<p>After a user selects their desired credential in the Credential Manager UI, use the result of <span style=\"color: #0d904f; font-family: courier;\">getCredential<\/span> (which contains the selected credential) to route to your authentication handlers.<\/p>\n<p><!--Kotlin--><\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\"><span\/><span style=\"color: #3d7b7b; font-style: italic;\">\/\/ getCredential returns the selected credential<\/span>\nlogin(getCredentialResponse.<span style=\"color: #687822;\">credential<\/span>)\n\n<span style=\"color: #3d7b7b; font-style: italic;\">\/\/ Route to your credential handling functions to login<\/span>\n<span style=\"color: green; font-weight: bold;\">suspend<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: green; font-weight: bold;\">fun<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: blue;\">login<\/span>(credential:<span style=\"color: #bbbbbb;\"> <\/span>Credential):<span style=\"color: #bbbbbb;\"> <\/span>LoginResult<span style=\"color: #bbbbbb;\"> <\/span>{\n<span style=\"color: #bbbbbb;\">  <\/span><span style=\"color: green; font-weight: bold;\">when<\/span><span style=\"color: #bbbbbb;\"> <\/span>(credential)<span style=\"color: #bbbbbb;\"> <\/span>{\n<span style=\"color: #bbbbbb;\">    <\/span><span style=\"color: green; font-weight: bold;\">is<\/span><span style=\"color: #bbbbbb;\"> <\/span>PublicKeyCredential<span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #666666;\">-&gt;<\/span><span style=\"color: #bbbbbb;\"> <\/span>{\n<span style=\"color: #bbbbbb;\">      <\/span><span style=\"color: green; font-weight: bold;\">return<\/span><span style=\"color: #bbbbbb;\"> <\/span>authHandler.<span style=\"color: #687822;\">loginWithPasskey<\/span>(credential.<span style=\"color: #687822;\">authenticationResponseJson<\/span>)\n<span style=\"color: #bbbbbb;\">    <\/span>}\n<span style=\"color: #bbbbbb;\">    <\/span><span style=\"color: green; font-weight: bold;\">is<\/span><span style=\"color: #bbbbbb;\"> <\/span>PasswordCredential<span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #666666;\">-&gt;<\/span><span style=\"color: #bbbbbb;\"> <\/span>{\n<span style=\"color: #bbbbbb;\">      <\/span><span style=\"color: green; font-weight: bold;\">return<\/span><span style=\"color: #bbbbbb;\"> <\/span>authHandler.<span style=\"color: #687822;\">loginWithPassword<\/span>(credential.<span style=\"color: #687822;\">id<\/span>,<span style=\"color: #bbbbbb;\"> <\/span>credential.<span style=\"color: #687822;\">password<\/span>)\n<span style=\"color: #bbbbbb;\">    <\/span>}\n<span style=\"color: #bbbbbb;\">    <\/span><span style=\"color: green; font-weight: bold;\">is<\/span><span style=\"color: #bbbbbb;\"> <\/span>CustomCredential<span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #666666;\">-&gt;<\/span><span style=\"color: #bbbbbb;\"> <\/span>{\n<span style=\"color: #bbbbbb;\">      <\/span><span style=\"color: green; font-weight: bold;\">return<\/span><span style=\"color: #bbbbbb;\"> <\/span>authHandler.<span style=\"color: #687822;\">loginWithCustomCredential<\/span>(\n<span style=\"color: #bbbbbb;\">          <\/span>credential.<span style=\"color: #687822;\">type<\/span>,<span style=\"color: #bbbbbb;\"> <\/span>credential.<span style=\"color: #687822;\">data<\/span>)\n<span style=\"color: #bbbbbb;\">    <\/span>}\n<span style=\"color: #bbbbbb;\">    <\/span><span style=\"color: #3d7b7b; font-style: italic;\">\/\/ \u2018else\u2019 case, etc\u2026<\/span>\n<\/pre>\n<\/div>\n<p>The handling logic for each of the above <span style=\"color: #0d904f; font-family: courier;\">loginWith\u2019x\u2019<\/span> methods is slightly different, although they all set up network calls to dedicated authentication endpoints. Below are simplified versions of these methods which demonstrate network calls to authenticate users based on their selected method.<\/p>\n<p><b>Passkeys<\/b> require the signed passkey JSON data. Your server will use this data to cryptographically verify the user.<\/p>\n<p><!--Kotlin--><\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\"><span\/><span style=\"color: green; font-weight: bold;\">suspend<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: green; font-weight: bold;\">fun<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: blue;\">loginWithPasskey<\/span>(passkeyResponseJSON:<span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #b00040;\">String<\/span>):<span style=\"color: #bbbbbb;\"> <\/span>LoginResult<span style=\"color: #bbbbbb;\"> <\/span>{\n<span style=\"color: #bbbbbb;\">  <\/span><span style=\"color: green; font-weight: bold;\">val<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #19177c;\">validatedPasskey<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #666666;\">=<\/span><span style=\"color: #bbbbbb;\"> <\/span>httpClient.<span style=\"color: #687822;\">post<\/span>(\n<span style=\"color: #bbbbbb;\">      <\/span><span style=\"color: #ba2121;\">\"myendpoint\/passkey\"<\/span>,<span style=\"color: #bbbbbb;\"> <\/span>passkeyResponseJSON,<span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #3d7b7b; font-style: italic;\">\/*other args*\/<\/span>)\n\n<span style=\"color: #bbbbbb;\">  <\/span><span style=\"color: green; font-weight: bold;\">return<\/span><span style=\"color: #bbbbbb;\"> <\/span>LoginResult(validatedPasskey)\n}\n<\/pre>\n<\/div>\n<p><b>Passwords<\/b> require network logic to validate the username and password, our example uses subsequent calls to validate the username first. Your backend will validate these against its user database.<\/p>\n<p><!--Kotlin--><\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\"><span\/><span style=\"color: green; font-weight: bold;\">suspend<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: green; font-weight: bold;\">fun<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: blue;\">loginWithPassword<\/span>(userName:<span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #b00040;\">String<\/span>,<span style=\"color: #bbbbbb;\"> <\/span>password:<span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #b00040;\">String<\/span>):<span style=\"color: #bbbbbb;\"> <\/span>LoginResult<span style=\"color: #bbbbbb;\"> <\/span>{\n<span style=\"color: #bbbbbb;\">  <\/span><span style=\"color: green; font-weight: bold;\">val<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #19177c;\">validatedUserName<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #666666;\">=<\/span><span style=\"color: #bbbbbb;\"> <\/span>httpClient.<span style=\"color: #687822;\">post<\/span>(\n<span style=\"color: #bbbbbb;\">      <\/span><span style=\"color: #ba2121;\">\"myendpoint\/username\"<\/span>,<span style=\"color: #bbbbbb;\"> <\/span>userName,<span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #3d7b7b; font-style: italic;\">\/*other args*\/<\/span>)\n<span style=\"color: #bbbbbb;\">  <\/span><span style=\"color: green; font-weight: bold;\">val<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #19177c;\">validatedPassword<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #666666;\">=<\/span><span style=\"color: #bbbbbb;\"> <\/span>httpClient.<span style=\"color: #687822;\">post<\/span>(\n<span style=\"color: #bbbbbb;\">      <\/span><span style=\"color: #ba2121;\">\"myendpoint\/password\"<\/span>,<span style=\"color: #bbbbbb;\"> <\/span>password,<span style=\"color: #bbbbbb;\"> <\/span>validatedUserName,<span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #3d7b7b; font-style: italic;\">\/*other args*\/<\/span>)\n\n<span style=\"color: #bbbbbb;\">  <\/span><span style=\"color: green; font-weight: bold;\">return<\/span><span style=\"color: #bbbbbb;\"> <\/span>LoginResult(ValidatedPassword)\n}\n<\/pre>\n<\/div>\n<p><b>Federated identities<\/b> like Sign in with Google require that a secure connection is established between your server and your app. Our sample shows a challenge-response flow initiated from the server, but a client generated nonce works as well.<\/p>\n<p>Our sample server provides a challenge to our app on request (<span style=\"color: #0d904f; font-family: courier;\">federatedSessionId<\/span>, below) which is subsequently used to validate the federated token to authenticate the user.<\/p>\n<p><!--Kotlin--><\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\"><span\/><span style=\"color: green; font-weight: bold;\">suspend<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: green; font-weight: bold;\">fun<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: blue;\">loginWithCustomCredential<\/span>(type:<span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #b00040;\">String<\/span>,<span style=\"color: #bbbbbb;\"> <\/span>data:<span style=\"color: #bbbbbb;\"> <\/span>Bundle):<span style=\"color: #bbbbbb;\"> <\/span>LoginResult<span style=\"color: #bbbbbb;\"> <\/span>{\n<span style=\"color: #bbbbbb;\">  <\/span><span style=\"color: green; font-weight: bold;\">if<\/span><span style=\"color: #bbbbbb;\"> <\/span>(type<span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #666666;\">==<\/span><span style=\"color: #bbbbbb;\"> <\/span>GoogleIdTokenCredential.<span style=\"color: #687822;\">TYPE_GOOGLE_ID_TOKEN_CREDENTIAL<\/span>)<span style=\"color: #bbbbbb;\"> <\/span>{\n<span style=\"color: #bbbbbb;\">    <\/span>token<span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #666666;\">=<\/span><span style=\"color: #bbbbbb;\"> <\/span>GoogleIdTokenCredential.<span style=\"color: #687822;\">createFrom<\/span>(data).<span style=\"color: #687822;\">idToken<\/span>\n<span style=\"color: #bbbbbb;\">  <\/span>}\n\n<span style=\"color: #bbbbbb;\">  <\/span><span style=\"color: #3d7b7b; font-style: italic;\">\/\/ Establish a federated session for with your server and obtain its info<\/span>\n<span style=\"color: #bbbbbb;\">  <\/span><span style=\"color: green; font-weight: bold;\">val<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #19177c;\">federatedSessionId<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #666666;\">=<\/span><span style=\"color: #bbbbbb;\"> <\/span>httpClient.<span style=\"color: #687822;\">post<\/span>(<span style=\"color: #ba2121;\">\"myendpoint\/ObtainFederatedSession\"<\/span>,\n<span style=\"color: #bbbbbb;\">      <\/span><span style=\"color: #3d7b7b; font-style: italic;\">\/*federated backend address=*\/<\/span><span style=\"color: #ba2121;\">\"https:\/\/accounts.google.com\"<\/span>)\n\n<span style=\"color: #bbbbbb;\">  <\/span><span style=\"color: #3d7b7b; font-style: italic;\">\/\/ Validate the token with the established federated session.<\/span>\n<span style=\"color: #bbbbbb;\">  <\/span><span style=\"color: green; font-weight: bold;\">val<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #19177c;\">validatedCustomCredential<\/span><span style=\"color: #bbbbbb;\"> <\/span><span style=\"color: #666666;\">=<\/span><span style=\"color: #bbbbbb;\"> <\/span>httpClient.<span style=\"color: #687822;\">post<\/span>(\n<span style=\"color: #bbbbbb;\">      <\/span><span style=\"color: #ba2121;\">\"myendpoint\/verifyToken\"<\/span>,<span style=\"color: #bbbbbb;\"> <\/span>token,<span style=\"color: #bbbbbb;\"> <\/span>federatedSessionID,\n<span style=\"color: #bbbbbb;\">      <\/span><span style=\"color: #3d7b7b; font-style: italic;\">\/*federated backend address=*\/<\/span><span style=\"color: #ba2121;\">\"https:\/\/accounts.google.com\"<\/span>)\n\n<span style=\"color: #bbbbbb;\">  <\/span><span style=\"color: green; font-weight: bold;\">return<\/span><span style=\"color: #bbbbbb;\"> <\/span>LoginResult(validatedCustomCredential)\n}\n<\/pre>\n<\/div>\n<h3><span style=\"font-size: large;\">Handling secondary Credential types<\/span><\/h3>\n<p>If a user taps dismiss, or swipes back from Credential Manager, a <span style=\"color: #0d904f; font-family: courier;\">GetCredentialCancellationException<\/span> will be thrown for developers to use to navigate to their backup login screens, which will provide secondary authentication options to users. These options are detailed in the <i><a href=\"#designing-authentication-credential-manager\">Designing Authentication with Credential Manager<\/a><\/i> section, above.<\/p>\n<p><!--Kotlin--><\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\"><span\/><span style=\"color: #3d7b7b; font-style: italic;\">\/\/ Catch the user dismissal<\/span>\n<span style=\"color: green; font-weight: bold;\">catch<\/span><span style=\"color: #bbbbbb;\"> <\/span>(e:<span style=\"color: #bbbbbb;\"> <\/span>GetCredentialCancellationException)<span style=\"color: #bbbbbb;\"> <\/span>{\n<span style=\"color: #bbbbbb;\">  <\/span><span style=\"color: #3d7b7b; font-style: italic;\">\/\/ Trigger event that navigates to \u2018BackupLoginScreen\u2019<\/span>\n<span style=\"color: #bbbbbb;\">  <\/span>uiEvents.<span style=\"color: #687822;\">send<\/span>(UiEvent.<span style=\"color: #687822;\">NavigateToBackupLogin<\/span>)\n}\n<\/pre>\n<\/div>\n<blockquote><p><b>Special Note:<\/b> The version of <a href=\"https:\/\/developer.android.com\/identity\/sign-in\/legacy-gsi-migration\" target=\"_blank\" rel=\"noopener\">Google Sign in<\/a> that exists outside of Credential Manager is now deprecated and will be removed, and <b>should not be provided as a secondary option<\/b> to avoid presenting two buttons for the same purpose.<\/p><\/blockquote>\n<p>See the <a href=\"https:\/\/developer.android.com\/training\/wearables\/apps\/auth-wear#legacy-siwg\" target=\"_blank\" rel=\"noopener\">Wear OS transition guide<\/a> for more details.<\/p>\n<h2><span style=\"font-size: x-large;\">Get started with Credential Manager on Wear OS<\/span><\/h2>\n<p>Implementing Credential Manager on Wear OS is a straightforward process that delivers significant benefits. By adopting this API, you can provide your users with a secure, seamless, and efficient way to authenticate.  To begin implementation, explore our <a href=\"https:\/\/developer.android.com\/training\/wearables\/apps\/auth-wear\" target=\"_blank\" rel=\"noopener\">developer documentation<\/a> and <a href=\"https:\/\/github.com\/android\/identity-samples\/tree\/credman-compose\/Shrine\/\" target=\"_blank\" rel=\"noopener\">official sample app<\/a>.<\/p>\n<p>To learn how apps have migrated to Credential Manager on Wear OS, check out our <a href=\"https:\/\/android-developers.googleblog.com\/2025\/08\/todoists-journey-to-modernize-wear-os-experience-with-material-3-expressive-credential-manager.html\" target=\"_blank\" rel=\"noopener\">case study with Todoist<\/a>, who were able to streamline their authentication whilst reusing their mobile implementation.<\/p>\n<p>For a look at how passkeys can improve login success rate, you can read all about how <a href=\"https:\/\/android-developers.googleblog.com\/2024\/11\/x-improved-login-success-rate-after-adopting-passkeys.html\" target=\"_blank\" rel=\"noopener\">X adopted passkeys<\/a> to achieve a more secure and user-friendly authentication experience.<\/p>\n<p>Finally, you can watch the new <a href=\"https:\/\/www.youtube.com\/watch?v=SfkxK-rFeNM\" target=\"_blank\" rel=\"noopener\">credential manager video blog<\/a> on YouTube to reinforce everything you\u2019ve learned here.<\/p>\n<p><i>Happy coding!<\/i><\/p>\n<\/div>\n<p>[ad_2]<br \/>\n<br \/><a href=\"http:\/\/android-developers.googleblog.com\/2025\/08\/the-evolution-of-wear-os-authentication.html\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>[ad_1] Posted by John Zoeller \u2013 Developer Relations Engineer This post is part of Wear OS Spotlight Week. Today, we&#8217;re focusing on implementing Credential Manager<\/p>\n","protected":false},"author":1,"featured_media":348113,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[146],"tags":[],"_links":{"self":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts\/348112"}],"collection":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/comments?post=348112"}],"version-history":[{"count":0,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts\/348112\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/media\/348113"}],"wp:attachment":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/media?parent=348112"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/categories?post=348112"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/tags?post=348112"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}