{"id":20675578,"url":"https://github.com/bitwarden/passwordless-android","last_synced_at":"2026-03-07T10:31:50.315Z","repository":{"id":210210856,"uuid":"725582874","full_name":"bitwarden/passwordless-android","owner":"bitwarden","description":"Bitwarden Passwordless.dev Android SDK.","archived":false,"fork":false,"pushed_at":"2026-02-05T02:46:45.000Z","size":1001,"stargazers_count":15,"open_issues_count":11,"forks_count":9,"subscribers_count":16,"default_branch":"main","last_synced_at":"2026-02-05T14:55:08.802Z","etag":null,"topics":["android","bitwarden"],"latest_commit_sha":null,"homepage":"https://bitwarden.com/","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bitwarden.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-11-30T12:59:29.000Z","updated_at":"2026-01-16T04:21:21.000Z","dependencies_parsed_at":"2024-01-16T11:41:53.339Z","dependency_job_id":"c44c9fde-a810-4422-a057-27d6ef927527","html_url":"https://github.com/bitwarden/passwordless-android","commit_stats":null,"previous_names":["bitwarden/passwordless-android"],"tags_count":17,"template":false,"template_full_name":"bitwarden/template","purl":"pkg:github/bitwarden/passwordless-android","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwarden%2Fpasswordless-android","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwarden%2Fpasswordless-android/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwarden%2Fpasswordless-android/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwarden%2Fpasswordless-android/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bitwarden","download_url":"https://codeload.github.com/bitwarden/passwordless-android/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwarden%2Fpasswordless-android/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30212049,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-07T09:02:10.694Z","status":"ssl_error","status_checked_at":"2026-03-07T09:02:08.429Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","bitwarden"],"created_at":"2024-11-16T21:09:53.005Z","updated_at":"2026-03-07T10:31:50.292Z","avatar_url":"https://github.com/bitwarden.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Build](https://github.com/bitwarden/passwordless-android/actions/workflows/android.yml/badge.svg)\n[![Maven Central](https://img.shields.io/maven-central/v/com.bitwarden/passwordless-android.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22com.bitwarden%22%20AND%20a:%22passwordless-android%22)\n\n# Android Client SDK\n\nThe Passwordless.dev Android client SDK gives users the ability to leverage their device’s built-in fingerprint sensor and/or FIDO security keys for secure passwordless access to websites and native applications that support the FIDO2 protocols\n\n## Creating your first Android application\n\n### Requirements\n\n- Android 9.0 (API level 28) or higher\n- Java 8 or higher\n- [Completed 'Get started' guide](https://docs.passwordless.dev/guide/frontend/android.html).\n\n### Installation\n\nApache Maven\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.bitwarden\u003c/groupId\u003e\n  \u003cartifactId\u003epasswordless-android\u003c/artifactId\u003e\n  \u003cversion\u003e2.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nGradle Kotlin DSL\n\n```kotlin\nimplementation(\"com.bitwarden:passwordless-android:2.0.0\")\n```\n\nGradle Groovy DSL\n\n```groovy\nimplementation 'com.bitwarden:passwordless-android:2.0.0'\n```\n\n### Permissions\n\nWhen the library has been added to your app, the following permission will be added to your `AndroidManifest.xml` automatically when the app is being built.\n\nIt is not necessary for you to add the following permission.\n\n```xml\n\u003cuses-permission android:name=\"android.permission.INTERNET\" /\u003e\n```\n\n### Configuration (Android application)\n\n```kotlin\ndata class PasswordlessOptions(\n   // Your public API key\n   val apiKey: String,\n\n   // Identifier for your server, for example 'example.com' if your backend is hosted at https://example.com.\n   val rpId: String,\n\n   // Where your backend is hosted\n   val backendUrl:String,\n\n   // Passwordless.dev server, change for self-hosting\n   val apiUrl: String = \"https://v4.passwordless.dev\"\n)\n```\n\n#### .well-known/assetlinks.json\n\nIn your application's `AndroidManifest.xml`, you will then need to add the tag below under `manifest::application`:\n\n```xml\n\u003cmeta-data\n            android:name=\"asset_statements\"\n            android:resource=\"@xml/assetlinks\" /\u003e\n```\n\nIn your application's `res/xml/assetlinks.xml`, you will then need to add the following content. This will tell our Android application where our `.well-known/assetlinks.json` file is hosted.\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cresources\u003e\n    \u003cstring name=\"assetlinks\"\u003ehttps://yourexample.com/.well-known/assetlinks.json\u003c/string\u003e\n\u003c/resources\u003e\n```\n\n### Configuration (Your back-end)\n\n#### Generating SHA-256 Certificate Fingerprints\n\nTo configure your backend, you'll need to host a `.well-known/assetlinks.json` file at the root of your domain. This file contains a list of SHA-256 certificate fingerprints that are allowed to authenticate with your backend.\n\nThis command will print detailed information about the keystore entry with the specified alias, including information about the certificate, its validity, and other details. It's commonly used in Android development to verify the properties of the debug keystore and the associated key used for signing applications during development.\n\n- Option 1:\n  - MacOS \u0026 Linux:\n    ```bash\n    keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android\n    ```\n  - Windows:\n    ```powershell\n    keytool -list -v -keystore \"%USERPROFILE%\\.android\\debug.keystore\" -alias androiddebugkey -storepass android -keypass android\n    ```\n- Option 2:\n  Go to the root directory of the project from the terminal and run the below command\n  ```bash\n  ./gradlew signingReport\n  ```\n  Put this SHA256 along with your root android package name in your backend to generate `assetlinks.json` for your app at `https://yourexample.com/.well-known/assetlinks.json`.\n  If you are using `example-nodejs-backend`. then just put these 2 values in your `.env` file.\n\n#### Host ~/.well-known/assetlinks.json\n\nYou will need store the following file at `https://\u003cyour-domain\u003e/.well-known/assetlinks.json`. To generate the SHA256 hash, read the links below the snippet.\n\nYou may also have to change the 'target::namespace' and 'target::package_name' properties to match your application's.\n\n```json\n[\n  {\n    \"relation\": [\n      \"delegate_permission/common.handle_all_urls\",\n      \"delegate_permission/common.get_login_creds\"\n    ],\n    \"target\": {\n      \"namespace\": \"web\"\n    }\n  },\n  {\n    \"relation\": [\n      \"delegate_permission/common.handle_all_urls\",\n      \"delegate_permission/common.get_login_creds\"\n    ],\n    \"target\": {\n      \"namespace\": \"android_app\",\n      \"package_name\": \"com.example.myapplication\",\n      \"sha256_cert_fingerprints\": [\n        \"3C:E2:29:94:E2:DE:1E:EB:E5:F9:70:10:72:41:F4:0F:06:38:61:BD:72:76:79:CA:72:68:67:FA:38:9B:65:B9\"\n      ]\n    }\n  }\n]\n```\n\n- [Associate apps \u0026 sites - Google](https://developers.google.com/identity/smartlock-passwords/android/associate-apps-and-sites)\n- [Passkeys - Google](https://developer.android.com/training/sign-in/passkeys)\n\n### Using the PasswordlessClient\n\n#### With Dagger Hilt\n\nYou can either set the `ActivityContext` and `CoroutineScope` by injecting it with Dagger Hilt as follows:\n\n```kotlin\n@Module\n@InstallIn(ActivityComponent::class)\nclass PasswordlessModule {\n    @Provides\n    fun provideLifecycleCoroutineScope(activity: Activity): LifecycleCoroutineScope =\n        (activity as AppCompatActivity).lifecycleScope\n\n    @Provides\n    @ActivityScoped\n    fun providePasswordlessClient(\n        @ActivityContext activity: Context, scope: LifecycleCoroutineScope): PasswordlessClient {\n        val options = PasswordlessOptions(\n            DemoPasswordlessOptions.API_KEY,\n            DemoPasswordlessOptions.RP_ID,\n            DemoPasswordlessOptions.ORIGIN,\n            DemoPasswordlessOptions.API_URL\n        )\n\n        return PasswordlessClient(options, activity, scope)\n    }\n}\n```\n\n#### Without Dagger Hilt\n\nOr you can set the Context of PasswordlessClient manually: Ensure the context is set to the current `Activity`.\n\n```kotlin\n/** Context needs to be set according to current activity\n * If there are different activity handling register and signin,\n * then call this on every activity\n*/\n_passwordless.setContext(this)\n```\n\nSet the coroutine scope, passing lifecycleScope of the current fragment, only necessary if you again do not use Dagger Hilt.\n\n```kotlin\n_passwordless.setCoroutineScope(lifecycleScope)\n```\n\n### Registration\n\n1. **Call Your Backend with User Details**:Make a call to your backend with user details (e.g., username, alias) and retrieve the registration token.\n2. **Call Passwordless Register Function**\n\n```kotlin\n_passwordless.register(\n    token =responseToken,\n    nickname = nickname\n) { success, exception, result -\u003e\n        if (success) {\n            Toast.makeText(context, result.toString(), Toast.LENGTH_SHORT).show()\n        } else {\n            Toast.makeText(\n            context,\n            \"Exception: \" + getPasskeyFailureMessage(exception as Exception),\n        Toast.LENGTH_SHORT\n        ).show()\n    }\n}\n```\n\n### Logging in\n\n1. **Take Alias as Input**: Gather the alias as input from the user.\n2. **Call Passwordless Login**: Initiate the login process with the alias and response callback.\n\n```kotlin\n_passwordless.login(alias) { success, exception, result -\u003e\n    if (success) {\n        lifecycleScope.launch {\n             val clientDataResponse =\n                httpClient.login(UserLoginRequest(result?.token!!))\n            if (clientDataResponse.isSuccessful) {\n                val data = clientDataResponse.body()\n                showText(data.toString())\n            }\n        }\n    } else {\n        showException(exception)\n    }\n}\n```\n\n## References\n\n- [Get Started - Passwordless.dev](../get-started.md/)\n- [Integration with your backend - Passwordless.dev](../backend/index.md)\n- [Client Auth - Google](https://developers.google.com/android/guides/client-auth)\n- [Associate apps \u0026 sites - Google](https://developers.google.com/identity/smartlock-passwords/android/associate-apps-and-sites)\n- [Passkeys - Google](https://developer.android.com/training/sign-in/passkeys)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitwarden%2Fpasswordless-android","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbitwarden%2Fpasswordless-android","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitwarden%2Fpasswordless-android/lists"}