---
url: 'https://www.corbado.com/blog/passkeys-sharing'
title: 'How to Sync Passkeys across Devices & Platforms'
description: 'Learn how to sync passkeys across iOS, Android, Windows and web apps. Covers iCloud Keychain, Google Password Manager and third-party sync.'
lang: 'en'
author: 'Vincent Delitz'
date: '2023-11-16T00:00:00.000Z'
lastModified: '2026-08-28T15:31:57.082Z'
keywords: 'Sync Passkeys across Devices, Passkey Sharing, Transfer Passkeys'
category: 'Passkeys Implementation'
---

# How to Sync Passkeys across Devices & Platforms

> ⚠️ **Archived tutorial - outdated integration**
>
> This article uses Corbado Complete, a discontinued product. Corbado now offers
> **[passkey observability and authentication for enterprise CIAM](https://www.corbado.com/features)**
>
> _The tutorial below is preserved for reference only and is no longer maintained._

## Key Facts

- **Unified Relying Party ID**: Web and native apps must use the same rpID so passkeys
  created on either platform are usable across both.
- **Association files** (apple-app-site-association for iOS and assetlinks.json for
  Android) must be hosted at the Relying Party ID domain to link native and web apps.
- **iCloud Keychain** syncs passkeys across Apple devices only. It is not available on
  Android, so cross-ecosystem transfers require third-party managers or CXP.
- **Credential Exchange Protocol (CXP)**, supported from iOS 26, enables secure passkey
  export between platforms and ecosystems for the first time.
- **Microsoft Password Manager** introduced passkey sync in 2024-2025. Windows 11 also
  gained a plugin model for third-party managers like 1Password and Dashlane.

## 1. Introduction: how to Sync Passkeys across Devices

**We strongly recommend reading our article on Relying Party IDs before diving deeper into
this article, as it helps to understand things better.**

One of the biggest advantages of passkeys over traditional WebAuthn credentials is that
**synced passkeys can be shared across different platforms and devices**. This means you
can **sync passkeys between web apps and native apps**, even **across different
ecosystems** like [iOS](https://www.corbado.com/blog/webauthn-errors),
[Android](https://www.corbado.com/blog/how-to-enable-passkeys-android) and Windows.

In this comprehensive guide, we cover both the conceptual side - how passkey sync works
via [iCloud Keychain](https://www.corbado.com/glossary/icloud-keychain),
[Google Password Manager](https://www.corbado.com/blog/how-to-use-google-password-manager), Microsoft
[Password Manager](https://www.corbado.com/blog/passkeys-vs-password-managers) and
[third-party passkey providers](https://www.corbado.com/blog/passkey-implementation-password-managers) - and the
practical implementation side using [Next.js](https://www.corbado.com/blog/nextjs-passkeys),
[Flutter](https://www.corbado.com/blog/flutter-passkeys-package)
(iOS/[Android](https://www.corbado.com/blog/how-to-enable-passkeys-android)) and Golang.

We also cover how to **transfer passkeys to a new phone**, **share passkeys from iPhone to
Android** and what the new Credential Exchange Protocol (CXP) means for passkey
portability.

This blog post is for you if you're looking to **sync passkeys across devices** in your
own apps or just want to understand how
[cross-platform passkey](https://www.corbado.com/faq/passkeys-cross-platform) sharing works. If you're only
interested in a web app tutorial, please see our guides for popular frameworks
([React](https://www.corbado.com/blog/react-passkeys), [Angular](https://www.corbado.com/blog/angular-passkeys),
[Vue.js](https://www.corbado.com/blog/vuejs-passkeys), [Next.js](https://www.corbado.com/blog/nextjs-passkeys),
[Nuxt.js](https://www.corbado.com/blog/passkeys-nuxtjs), [SvelteKit](https://www.corbado.com/blog/sveltekit-passkeys), PHP
[Symfony](https://www.corbado.com/blog/passkeys-php-symfony), [Node.js](https://www.corbado.com/blog/nodejs-passkeys), Python
[Flask](https://www.corbado.com/blog/passkeys-python-flask), [Java Spring](https://www.corbado.com/blog/passkeys-java-spring-boot)), and
for a [Flutter](https://www.corbado.com/blog/flutter-passkeys-package) tutorial, see here. The **real challenge**
is not the code itself but **the setup and configuration**.

As a practical example, we use the setup of the Corbado developer panel with a
[web app](https://app.corbado.com) and native [Flutter](https://www.corbado.com/blog/flutter-passkeys-package)
apps for [iOS](https://www.corbado.com/blog/webauthn-errors) and [Android](https://www.corbado.com/blog/how-to-enable-passkeys-android).

Sharing passkeys in this blog post should not be mistaken with sharing passkeys within
e.g. an Apple account to let other family members access your passkeys. For more details
on this process, please check our guide on sharing passkeys between Apple devices.

You can find the completed code for the Flutter app in
[this GitHub repository](https://github.com/corbado/example-passkeys-flutter).

## 2. Prerequisites: syncing Passkeys across Devices

Before we dive into setting up our applications, let's ensure we're all on the same page
regarding the foundational knowledge and tools needed to follow the tutorial.

### 2.1 Knowledge Base for cross-platform Passkey Sharing

Native & Web Apps Basics: A fundamental understanding of
[native app](https://www.corbado.com/blog/native-app-passkeys) development and general web app architecture is
crucial for implementing [cross-platform passkey](https://www.corbado.com/faq/passkeys-cross-platform) sharing.

Passkeys & WebAuthn: A solid understanding of passkeys and WebAuthn is essential since
we'll be delving into advanced configurations and setups for passkey synchronization.
Ensure you're familiar with the basic processes and functionalities of passkeys and
WebAuthn to smoothly navigate through the tutorial. In case you need some refreshments on
certain topics, please have a look at our other detailed blog posts:

- WebAuthn [User ID](https://www.corbado.com/blog/webauthn-user-id-userhandle),
  [User Handle](https://www.corbado.com/blog/webauthn-user-id-userhandle), User Name and
  [Credential ID](https://www.corbado.com/blog/webauthn-user-id-userhandle)
- WebAuthn Non-Resident Keys: Problem with Multiple Credentials
- WebAuthn [Conditional Registration](https://www.corbado.com/blog/webauthn-conditional-registration-extension)
  Extension
- WebAuthn Passkey QR Codes & Bluetooth: Hybrid Transport
- WebAuthn [Conditional UI](https://www.corbado.com/glossary/conditional-ui) (Passkeys Autofill) Technical
  Explanation
- [Native App Passkeys](https://www.corbado.com/blog/webauthn-origin-validation-native-apps): Native vs.
  [WebView](https://www.corbado.com/blog/native-app-passkeys) Implementation
- WebAuthn [Resident Key](https://www.corbado.com/blog/webauthn-resident-key-discoverable-credentials-passkeys):
  Discoverable Credentials as Passkeys
- WebAuthn [Relying Party](https://www.corbado.com/glossary/relying-party) ID (rpID) & Passkeys: Domains & Native
  Apps

### 2.2 Tools and technologies

**Flutter:**

We'll be using Flutter for developing the [native app](https://www.corbado.com/blog/native-app-passkeys). Ensure
you have it installed and are familiar with its basic functionalities. In Flutter, we use
the [corbado_auth package](https://pub.dev/packages/corbado_auth), which internally uses
the [passkeys package](https://pub.dev/packages/passkeys).

**Next.js:**

The application will be built using [Next.js](https://www.corbado.com/blog/nextjs-passkeys). Next.js provides a
full-stack framework that allows us to handle both client-side and server-side logic
efficiently. Familiarity with Next.js, especially in the context of full-stack
development, will be beneficial.

**Corbado UI Components:**

In the Next.js application, we'll implement the
[Corbado Web UI Components](https://docs.corbado.com/corbado-connect/web-ui-components/overview),
which come with a lot of
[passkey features](https://www.corbado.com/blog/social-logins-pre-filled-passkeys-customization) out-of-the-box
simplifying the integration process and ensuring seamless interaction with the backend.
They are JavaScript-based and work with any frontend framework.

## 3. Architecture for cross-platform Passkey Sharing App

Embarking on a journey to implement passkey sharing between web and native applications
necessitates a thorough understanding of the underlying architecture. Let's delve into the
core concepts and architectural components that will be the backbone of our setup.

![architecture_cross_platform_passkey_sharing_app_cad13ffd04.png](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/architecture_cross_platform_passkey_sharing_app_cad13ffd04_a3361fb281.png)

### 3.1 System architecture

Let's first have a look at the different components that we have in our setup:

#### 3.1.1 Golang backend

**Application Server:**

The application server is written in Golang (while any other programming language or
framework would have worked as well). It manages all the incoming requests and takes care
of all the business logic. In our setup, it is accessible via `https://auth.corbado.com`.

**WebAuthn Server:**

The central part for passkey authentication / WebAuthn is the WebAuthn server (also called
the [relying party](https://www.corbado.com/glossary/relying-party) backend), which is responsible for managing
authentication requests and enabling
[cross-platform passkey](https://www.corbado.com/faq/passkeys-cross-platform) sharing. A WebAuthn server can be
implemented either as an in-process library/SDK integrated into the application server, or
as a separate hosted service (e.g. a managed identity provider). In our example, we use an
integrated library approach. Read this blog post to understand more about WebAuthn server
implementations. The WebAuthn server is not directly reachable but only via the
application server.

**Database:**

The database is used to store information about the users and passkeys. In our example,
we're using [MySQL](https://www.corbado.com/blog/passkey-webauthn-database-guide) (any other database could have
worked as well). The database is not publicly reachable.

#### 3.1.2 Next.js frontend

**Next.js Application:**

We use Next.js as our frontend framework, which provides a robust and efficient way to
build the user interface. You can access the Next.js application at
[https://app.corbado.com](https://app.corbado.com). Our
[integration docs](https://docs.corbado.com/corbado-connect/integration/generic/overview)
show how to wire this up in your own stack.

**Corbado Component:**

In the web app, we'll be integrating the
[Corbado Web UI Components](https://docs.corbado.com/corbado-connect/integration/generic/web)
into the sign-up and login flow.

#### 3.1.3 Flutter (iOS & Android) native App

A straightforward Flutter app is utilized. The Flutter app implements the
[corbado_auth package](https://pub.dev/packages/corbado_auth) (and thus the
[passkeys package](https://pub.dev/packages/passkeys)), which facilitates communication
with the backend. The package name for the Flutter (iOS & Android)
[native app](https://www.corbado.com/blog/native-app-passkeys) is com.corbado.developerpanel.app.

### 3.2 Passkey Sharing implications

#### 3.2.1 Unified Relying Party ID to enable cross-platform Passkey Sharing

The WebAuthn server, which manages the public keys, is the same for the web and native
application. This ensures that the authentication data is consistently available across
the two platforms, facilitating seamless passkey sharing and authentication.

Therefore, the [Relying Party](https://www.corbado.com/glossary/relying-party) ID (rpID) needs to be the same for
passkeys created either in the web or native app to enable proper passkey synchronization.

The Relying Party ID (rpID) we define in our example is set to corbado.com. To help you
find out the suitable Relying Party ID (rpID) for your case, please have a look into our
detailed guide here.

#### 3.2.2 Association Files to link native Apps with web Apps

The apple-app-site-association file for [iOS](https://www.corbado.com/blog/webauthn-errors) apps and the
assetlinks.json file for Android apps are pivotal in establishing and verifying the
relationship between the web and native applications. The files are hosted on our server
at

- iOS:
  [https://corbado.com/.well-known/apple-app-site-association](https://corbado.com/.well-known/apple-app-site-association)
- Android:
  [https://corbado.com/.well-known/assetlinks.json](https://corbado.com/.well-known/assetlinks.json)

They ensure that a created passkey on either of the two applications can be used on the
other one. Its important that server address ([https://corbado.com](https://corbado.com))
where the files are stored is the same like the Relying Party ID (corbado.com).

Let's have a look on the content of these two files:

**apple-app-site-association:**

```json
{
    "appclips": {
        "apps": []
    },
    "applinks": {
        "details": [
            {
                "appID": "T9A667JL6T.com.corbado.developerpanel.app",
                "paths": ["*"]
            }
        ]
    },
    "webcredentials": {
        "apps": ["T9A667JL6T.com.corbado.developerpanel.app"]
    }
}
```

Currently, there are two entitlements set up: applinks and webcredentials.

**applinks** is not necessarily needed for passkeys but still set for better UX. It allows
to directly open suitable links for the Corbado developer panel in the Flutter native app.

**webcredentials** is the important one that must be set for passkey synchronization to
work properly. As the apple-app-site-association file is hosted at the location of the
Relying Party ID server (here at [https://corbado.com](https://corbado.com) with the
Relying Party ID corbado.com) and downloaded during the app install, the native app is
associated to the Relying Party ID.

The value stored in here (the same value as the appID in the applinks entitlement)
consists of two elements. The first part is the Application Identifier Prefix (here:
T9A667JL6T) and your Bundle Identifier (here: com.corbado.developerpanel.app). The
Application Identifier Prefix can be obtained by going to your
[Apple Developer Certificates, Identifier & Profiles](https://developer.apple.com/account/resources/identifiers/bundleId)
associated with your Apple Developer account.

Note: When creating your Bundle Identifier, make sure that the Associated Domains
capability is enabled:

![](https://www.corbado.com/website-assets/658a055b80101def936ed1d2_bundle_identifier_associated_domains_457caa0087.png)

**assetlinks.json**

```json
[
    {
        "relation": [
            "delegate_permission/common.handle_all_urls",
            "delegate_permission/common.get_login_creds"
        ],
        "target": {
            "namespace": "android_app",
            "package_name": "com.corbado.developerpanel.app",
            "sha256_cert_fingerprints": [
                "8B:BF:39:60:61:89:30:A4:45:F3:D7:09:1E:7B:1B:05:0F:8A:FD:AF:24:EB:F1:EB:2E:3D:13:88:09:FC:79:59",
                "AC:B4:93:5D:FC:31:FB:EF:2D:5C:F1:CF:31:E9:B6:8A:1E:7E:F9:0E:FF:23:E5:43:AE:41:44:EF:33:E3:FD:F3",
                "54:4C:94:2C:E9:2F:6A:C1:7D:56:C2:5D:DB:D6:5E:71:32:A4:0D:62:7E:3E:F2:E4:09:A8:18:9F:D0:63:A8:FB"
            ]
        }
    },
    {
        "relation": [
            "delegate_permission/common.handle_all_urls",
            "delegate_permission/common.get_login_creds"
        ],
        "target": {
            "namespace": "web",
            "sha256_cert_fingerprints": null,
            "site": "https://auth.corbado.com"
        }
    }
]
```

As you can see, there are two entries set to associate the web app and the native app.

The first entry is for the target with namespace android_app (our Flutter native app),
while the second one is for the target with namespace web (our Next.js web app). Both
entries contain each the same two required relations
delegate_permission/common.handle_all_urls and delegate_permission/common.get_login_creds.
Moreover, the native app entry contains the used package name (here:
com.corbado.developerpanel.name) and the SHA-256 signing certificate fingerprint (here
e.g.: 8B:BF:39:60:61:89:30:A4:45:F3:D7:09:1E:7B:
1B:05:0F:8A:FD:AF:24:EB:F1:EB:2E:3D:13:88:09:FC:79:59), while the web app contains the URL
to the backend's host (here `https://auth.corbado.com`).

Often generating or extracting the SHA-256 signing certificate causes issues or is
confusing. Please have a look at this blog post, where we help you in great detail to get
your right values.

Understanding this architecture and its passkey implications lays the foundation to the
setup and configuration of our web and native application.

## 4. Setting up the Next.js Web App

Now, we have a look on the practical implementation of the Next.js web application. Let's
see how the web application can be quickly setup by using the Corbado
[React](https://www.corbado.com/blog/react-passkeys) package, which saves a lot of development time, as it comes
with intelligent passkey management, device detection and passkey UI / UX out-of-the-box.
Besides that, we're also using Corbado's session management to have a simple, secure and
efficient session management as well.

### 4.1 Initialization & integration of the Next.js Web App

#### 4.1.1 Simplified setup with the Corbado React Package

While we won't delve deep into the detailed setup of the web application in this guide,
our other guides provide a comprehensive walkthrough for a basic setup. For our Corbado
developer panel example, please have a look at this
[Next.js passkeys](https://www.corbado.com/blog/nextjs-passkeys) guide with our [React](https://www.corbado.com/blog/react-passkeys)
package and into our
[integration docs](https://docs.corbado.com/corbado-connect/integration/generic/overview).
We encourage you to explore it for a thorough understanding of the initial steps.

One of the most crucial steps in the [Next.js passkeys](https://www.corbado.com/blog/nextjs-passkeys) guide is
defining the Relying Party ID. You can do this in the
[Corbado developer panel](https://app.corbado.com/app/settings/general/urls). In there, we
set the Relying Party ID for our web app (and thus also for our native app) to
corbado.com.

#### 4.1.2 Embedded Auth Component location is important

The auth component itself can be embedded at any location of the web app. We decided to
host our developer panel on the subdomain app.corbado.com. This domain also embeds the
Corbado auth component as we wanted to allow our users a sign-up and login from here. As
outlined in our Relying Party ID guide, adding the auth component to a subdomain
(app.corbado.com) of the Relying Party ID (corbado.com) is fine (but not the other way
around).

Additionally, and more as a side note, we also embedded the auth component on our external
website [www.corbado.com](https://www.corbado.com), which is also fine as it still matches
the Relying Party ID (corbado.com), because subdomains can access the passkeys of the
corresponding root domains. Please take a look at this detailed blog post to better
understand the domain matching of the Relying Party ID.

### 4.2 Passkey Authentication Flow in the Next.js web App

After we followed the guide above and deployed our application accordingly, we are ready
to try the passkey authentication process on our web application. In the following, we
explain what happens in the background and which checks are being passed.

Our test device is a MacBook with activated Apple
[iCloud Keychain](https://www.corbado.com/glossary/icloud-keychain) where we stored the passkeys in. This allows
us to later also used them on an iPhone that is synced in the same Apple
[iCloud Keychain](https://www.corbado.com/glossary/icloud-keychain).

1. Go to our web app ([app.corbado.com](https://app.corbado.com)), open the sign-up page
   of the web component to create a new account and provide a name and email address.
   Then, click on Sign up with 1 click for free.

![](https://www.corbado.com/website-assets/658a0591c3ffbc0d6265960d_sign_up_developer_panel_6231bce1ad.png)

2. In the appearing passkey popup create a new passkey and account by authenticating via
   Touch ID on your MacBook.

![](https://www.corbado.com/website-assets/658a05be3400b61bef8a8d5e_macos_touch_id_passkey_bf054b8ffe.png)

3. Youve successfully created a passkey that is synced in the Apple iCloud Keychain and an
   account at the web app. Please confirm the new account by clicking on the email magic
   link sent to your inbox

![](https://www.corbado.com/website-assets/658a05e6f3efd1f4a4be0f93_developer_panel_successful_sign_up_d890ade5d6.png)

In this section, weve laid the groundwork for the web application and showed how to create
a passkey for the web app. With the Relying Party ID accurately defined and a basic
understanding of the authentication flow, were now ready to explore the configuration of
the Flutter application in the next section.

## 5. Setting up the Flutter Native App

Lets have a deeper look now into the setup of the Flutter application. For speeding up the
passkeys implementation process in Flutter, we make use of the
[corbado_auth package](https://pub.dev/packages/corbado_auth) (internally it uses the
[passkeys package](https://pub.dev/packages/passkeys)) that comes with all the required
settings for passkey authentication on iOS and Android and has basic other authentication
SDK features like session management.

### 5.1 Initialization & integration of the Flutter native App

**Simplified Setup with the corbado_auth package:**

While we won't delve deep into the detailed setup of the Flutter app in this guide, the
[corbado_auth package docs](https://pub.dev/packages/corbado_auth) walk through a basic
setup. We encourage you to explore them for a thorough understanding of the initial steps.

See our full [GitHub repository here](https://github.com/corbado/example-passkeys-flutter)
for details.

### 5.2 Passkey Authentication Flow in the Flutter native App

To make things easily reproducible for you, we published a simple Corbado developer panel
app into the
[App Store](https://apps.apple.com/de/app/corbado-developer-panel/id6468424589) and
[Play Store](https://play.google.com/store/apps/details?id=com.corbado.developerpanel.app).
Please download the corresponding app for your platform.

In the following, we describe the process of using the passkey created before on our
MacBook and using it for our login in the iOS app. A synchronization of this passkey to
the Android app is not possible, as it is synced in the iCloud Keychain and thus Android
smartphones wouldn't have access to it. To allow for such a cross-platform passkey
synchronization today, you would need a cross-platform synced
[password manager](https://www.corbado.com/blog/passkeys-vs-password-managers), like
[Dashlane](https://www.corbado.com/blog/dashlane-passkeys) or
[1Password](https://www.corbado.com/blog/1password-passkeys-best-practices-analysis) (which needs to be installed
on both devices) or you can alternatively use the cross-platform passkey authentication
with QR codes and Bluetooth.

1. Open the iOS app. As soon as the login screen is displayed,
   [Conditional UI](https://www.corbado.com/glossary/conditional-ui) is triggered and you should see a passkey
   (including your username / email address you used during creation) as autofill
   suggestion (here for the email address
   [wexeb73750@fgvod.com](mailto:wexeb73750@fgvod.com)). This is not the email address /
   passkey we created before, so we click on the key symbol next to the autofill line:

![](https://www.corbado.com/website-assets/658a05f8205fdc3745ea1ae1_ios_app_conditional_ui_fc6ee8bf23.jpg)

2. After clicking on the icon, we are first asked which cloud account we should use to get
   access to the passkeys. We select iCloud Keychain, as this is the cloud account where
   we stored the passkey during the creation.

![](https://www.corbado.com/website-assets/658a0609a643c0b458876e22_ios_app_select_cloud_account_b9a14e40d5.jpg)

3. After clicking on the right account, the [Face ID](https://www.corbado.com/faq/is-face-id-passkey)
   authentication immediately starts. Next, we get an overview of all the passkeys that
   are available for our iCloud account for this relying party ID. We look for the passkey
   that was created for: [saxofok424@visignal.com](mailto:saxofok424@visignal.com)

![](https://www.corbado.com/website-assets/658a061f822f338b4787e709_ios_app_select_passkey_fcecdc5a32.jpg)

4. After clicking on the desired passkey, we are automatically forwarded to the logged-in
   part of the iOS app.

![](https://www.corbado.com/website-assets/658a06350016c05e38ae5064_ios_app_successful_login_37670b7102.jpg)

Congrats, thats it! Youve successfully managed to
[create a passkey](https://www.corbado.com/blog/passkey-creation-best-practices) on one device (MacBook + web
app), sync it via iCloud Keychain to another device (iPhone +
[native iOS app](https://www.corbado.com/blog/native-app-passkeys)) and use it for authentication. This process
would have also worked the other way round.

In case this does not work take a look at our troubleshooting guide. Alternatively, you
can look up the existing passkey on iOSvia Settings -&gt; Passwords on your iPhone and
search for corbado.com (or whatever Relying Party ID youre looking for). This should show
you all available passkeys for corbado.com: example pictures. This approach works on
macOS, Windows and Android as well (with slight adjustments in the steps to be done).

![](https://www.corbado.com/website-assets/658a0644f1b468de2af5ddfb_ios_passkey_list_75d6fac20c.jpg)

macOS: Settings -&gt; Passwords

![](https://www.corbado.com/website-assets/658a065000518a27e24c0a79_macos_passkey_list_74d8df3346.png)

Android: Settings -&gt; [Password Manager](https://www.corbado.com/blog/passkeys-vs-password-managers)

![](https://www.corbado.com/website-assets/658a065f3c540b89cb3c4f03_android_passkey_list_29da9c0f35.jpg)

Windows: Settings -&gt; Passkey

![](https://www.corbado.com/website-assets/658a066eb0f537022df0e2c0_windows_passkey_list_12368c6a49.png)

## 6. Analyzing the Passkey Sync process

In the previous step, we successfully used the passkey for cross-device synchronization
between a MacBook and an iPhone. Depending on where you synced the passkey during
[passkey creation](https://www.corbado.com/blog/passkey-creation-best-practices) the following scenarios would
also have been possible:

**Scenario 1: Cross-Platform Passkey Sharing Between Web and Native Apps**

![](https://www.corbado.com/website-assets/658a068b5b7d61bf88c56825_passkeys_sync_iphone_android_9c4f7773ad.png)

iOS: If you create the passkey in the web app, it will be automatically stored in your
iCloud Keychain but also locally on your device. When then opening the native app, iOS
will try to access the [secure enclave](https://www.corbado.com/glossary/secure-enclave) with the locally stored
passkeys and make use of it for the login process in the native app. This seamless sync
passkeys functionality is what makes cross-platform passkey sharing possible.

Android: The process is here very much the same to iOS. The passkey is stored during
creation in the [Google Password manager](https://www.corbado.com/blog/how-to-use-google-password-manager) (and
synced here), but also locally in the device itself. In the login process of the native
app, the local passkey is then used to authenticate in the native app.

In case creating a passkey does not work on your iOS or Android device, you probably have
not activated the necessary settings for your platform. Please see here for
troubleshooting guidance and further help.

**Scenario 2: Create passkey in a device that uses passkey-syncable password manager and
use it for login on other device with passkey-syncable password manager**

![](https://www.corbado.com/website-assets/658a069ead8b6fae515d5d96_passkeys_sync_iphone_android_password_manager_a50b8fac6d.png)

Many modern non-OS password managers (e.g.
[1Password](https://www.corbado.com/blog/1password-passkeys-best-practices-analysis) or
[Dashlane](https://www.corbado.com/blog/dashlane-passkeys)) have recently been upgraded to also support passkeys
meaning that they take the place of Apple iCloud Keychain or
[Google Password Manager](https://www.corbado.com/blog/how-to-use-google-password-manager). Therefore, the
passkeys are synced in the non-OS password manager and every passkey-ready device that has
the non-OS password manager installed gets access to the passkey and can use it for
authentication.

**Scenario 3: Create passkey on Android device 1 web app and use it for login on Android
device 2 native app (same would also be valid with iPhone)**

![](https://www.corbado.com/website-assets/658a06b2d73e09aac4b7fc56_passkeys_sync_android_to_android_c7f295a360.png)

![](https://www.corbado.com/website-assets/658a06c05d52e6e1acce2b63_passkeys_sync_iphone_to_iphone_b37daba287.png)

iOS: If you [create a passkey](https://www.corbado.com/blog/passkey-creation-best-practices) on your iPhone 1 and
would have a second iPhone 2, the passkey will be accessible from the second iPhone, as
long as both devices are synced in the same Apple iCloud Keychain.

Android: The process here again is very much the same compared to iOS. The only difference
is that the passkeys are not stored in the iCloud Keychain but instead stored in the
Google Password Manager, which is also available on other Android smartphones from the
same Google account.

**Scenario 4: Create passkey in native / web app on Android / iPhone and use it for login
in web app on Windows 11 via QR code & Bluetooth**

![](https://www.corbado.com/website-assets/658a06cf0016c05e38ae97a9_passkeys_sync_iphone_to_windows_292d2e5fc3.png)

If you [create a passkey](https://www.corbado.com/blog/passkey-creation-best-practices) on your Android or iPhone
(no matter if its within a native app or web app), you can use this for cross-platform
authentication (also called hybrid transport), e.g. to use it in a web app running on a
[Windows 11](https://www.corbado.com/blog/passkeys-windows-11). When trying to log into the web app on
[Windows 11](https://www.corbado.com/blog/passkeys-windows-11), theres the option to display a
[QR code](https://www.corbado.com/blog/qr-code-login-authentication) that you can scan with your Android or
iPhone. Using a Bluetooth proximity check and a tunnel under the hood the passkey from the
Android / iPhone is used for authentication and you will be logged into the web app on the
Windows device. Please read this blog post if you are interested in details on this
process.

## 7. Sync Passkeys with Microsoft / Windows

A major development in passkey sync happened when **Microsoft introduced passkey saving
and syncing via Microsoft Password Manager** in 2024-2025. On
[Windows 11](https://www.corbado.com/blog/passkeys-windows-11), passkeys can now be saved to your
[Microsoft account](https://www.corbado.com/blog/use-windows-11-without-windows-hello-microsoft-account) and
synced across all your Windows devices.

### 7.1 Microsoft Password Manager Passkey Sync

Windows users can now
[sync passkeys to their Microsoft account](https://support.microsoft.com/en-us/windows/synchronize-passkeys-to-your-microsoft-account-be9de83c-6803-4ccc-81f2-e1fcc2fb8110),
making them available on any Windows device signed into the same account. This works
similarly to how iCloud Keychain syncs passkeys across Apple devices or how Google
Password Manager syncs across Android and Chrome.

For a detailed analysis of Microsoft's passkey implementation, see our Microsoft passkeys
best practices analysis.

### 7.2 Third-Party Passkey Manager Support on Windows

Starting in late 2025, Windows 11 also introduced a
[plugin model for third-party passkey managers](https://blogs.windows.com/msedgedev/2025/11/03/microsoft-edge-introduces-passkey-saving-and-syncing-with-microsoft-password-manager/).
This means password managers like
[1Password](https://www.corbado.com/blog/1password-passkeys-best-practices-analysis) or
[Dashlane](https://www.corbado.com/blog/dashlane-passkeys) can now natively integrate with the Windows passkey
system. For more on managing passkeys on Windows and enabling passkeys on Windows, see our
dedicated guides.

## 8. Transfer Passkeys to a new Phone

One of the most common questions around passkey sync is: **what happens to your passkeys
when you switch to a new phone?** The answer depends on your platform and
[passkey provider](https://www.corbado.com/blog/passkey-providers).

### 8.1 Transfer Passkeys to a new iPhone

When you set up a new iPhone and sign in with the same Apple Account, all passkeys stored
in iCloud Keychain automatically sync to the new device. No manual transfer is needed - as
long as iCloud Keychain is enabled, your passkeys are available immediately. For details
on managing your [Apple passkeys](https://www.corbado.com/blog/how-to-use-apple-passwords), see our guide on
[Apple Passwords](https://www.corbado.com/blog/how-to-use-apple-passwords).

### 8.2 Transfer Passkeys to a new Android Phone

Similarly on Android, passkeys stored in Google Password Manager are synced to your Google
account. When you sign in on a new Android device with the same Google account, all
passkeys become available automatically. Google also supports syncing passkeys to Chrome
on Windows and macOS.

### 8.3 Transfer Passkeys from iPhone to Android

Transferring passkeys **from iPhone to Android** (or vice versa) has historically been the
biggest challenge with passkey sync. iCloud Keychain passkeys are not directly accessible
on Android devices, and Google Password Manager passkeys are not accessible on iPhones.

There are several solutions:

- **Third-party password managers**: Using a cross-platform password manager like
  1Password or Dashlane that supports passkeys on both iOS and Android
- **QR code and Bluetooth hybrid transport**: You can use a passkey stored on one device
  to authenticate on another device via WebAuthn QR codes and Bluetooth (cross-device
  authentication)
- **Credential Exchange Protocol (CXP)**: The new [FIDO Alliance](https://www.corbado.com/glossary/fido-alliance)
  standard that enables passkey portability between ecosystems (see section below)

### 8.4 iCloud Keychain on Android: Can you Access Apple Passkeys?

A frequent question is whether you can use iCloud Keychain on Android. The short answer
is: **no, iCloud Keychain is not available on Android**. Apple's passkey sync is limited
to the Apple ecosystem (iPhone, iPad, Mac). However, with [iOS 26](https://www.corbado.com/blog/ios-26-passkeys)
Apple introduced support for exporting passkeys via the Credential Exchange Protocol,
which allows users to transfer passkeys out of iCloud Keychain to other platforms for the
first time.

If you need passkeys accessible on both iOS and Android today, the best approach is using
a cross-platform passkey provider like 1Password or Dashlane.

## 9. Passkey Portability: iOS 26 and the Credential Exchange Protocol

A major shift in passkey portability arrived with [iOS 26](https://www.corbado.com/blog/ios-26-passkeys) and the
Credential Exchange Protocol (CXP). This [FIDO Alliance](https://www.corbado.com/glossary/fido-alliance) standard
enables **secure export and import of passkeys between different credential managers and
platforms**.

### 9.1 What CXP Means for Cross-Platform Passkey Sharing

Before [CXP](https://www.corbado.com/blog/credential-exchange-protocol-cxp-credential-exchange-format-cxf),
passkeys were effectively locked into the ecosystem where they were created. iCloud
Keychain passkeys stayed in Apple's ecosystem, Google Password Manager passkeys stayed in
Google's ecosystem.
[CXP](https://www.corbado.com/blog/credential-exchange-protocol-cxp-credential-exchange-format-cxf) changes this
by defining a standardized, encrypted format for transferring passkeys between providers.

For developers implementing passkey authentication, this means users will increasingly
expect to be able to move their passkeys freely. Read our detailed guide on
[CXP](https://www.corbado.com/blog/credential-exchange-protocol-cxp-credential-exchange-format-cxf) and
[CXF](https://www.corbado.com/blog/credential-exchange-protocol-cxp-credential-exchange-format-cxf) and our
coverage of Apple's [WWDC25](https://www.corbado.com/blog/wwdc25-passkeys-os26) passkey announcements for more
details.

## 10. Troubleshooting and lessons learned

We've spent the last months on providing tools and tutorials to make developers lives
easier when it comes to passkey implementation in general but especially to passkeys in
native apps and sharing them across devices in platforms.

Once you've got everything set up correctly, it's a pretty smooth process from UX view.
Coming there might cause some headaches though due to the lack of documentation and
references. Therefore, we created a list of common issues that weve encountered in the
past to help you avoid these issues.

### 10.1 Local Testing Issues for the Flutter App (Emulator & Physical Devices)

Difficulties in testing [passkey login](https://www.corbado.com/blog/passkey-login-best-practices) on simple
devices led us to develop the Flutter package, aiding developers in circumventing these
issues. Explore our troubleshooting section for insights and check the
[corbado_auth package docs](https://pub.dev/packages/corbado_auth) for the local setup.

### 10.2 Defining the right Relying Party ID

Identifying and accurately setting up the right relying party ID, which this blog post
aims to guide through.

### 10.3 Native vs. WebView implementation of Passkeys in native apps

Deciding on the implementation method of passkeys in a native app, be it via
[WebView](https://www.corbado.com/blog/native-app-passkeys) or natively. Our guide provides detailed guidance on
this aspect.

## 11. How Corbado can help

The setup above works once the Relying Party ID, the association files and the two apps
line up on your own devices. In production the same code meets users whose Android app
runs without Play Services, whose iPhone was restored from a backup and whose Windows
laptop starts the [QR code](https://www.corbado.com/blog/qr-code-login-authentication) flow from scenario 4 and
abandons it halfway.

[Corbado Observe](https://www.corbado.com/observe) is the
[authentication observability](https://www.corbado.com/blog/authentication-observability) layer, and it records
web and native app ceremonies against the same user, which is the exact split this guide
is built around.

[Video: User search debugging](https://www.corbado.com/videos/features/user-search-debugging.mp4) ([See User Debugging in Corbado Observe](https://www.corbado.com/observe/user-debugging))

- **User Search** reconstructs one user's ceremonies across both surfaces, so "the passkey
  I created in the browser never appeared in the Flutter app" becomes a timeline you can
  read
- **Passkey Insights** shows transport and sync state per credential, which is how you
  tell a passkey that actually reached the second device from a user who quietly created a
  second credential there
- **Client Capabilities** charts `hybridTransport` as a share of your web sessions, which
  is the cohort that can run the QR handoff in scenario 4 at all. Bluetooth availability
  is the other half of that flow and it is kept per session in the client environment box
  under User Search, so you read it for the one laptop that stalled rather than for a
  segment
- On native apps the SDK also reports the screen lock, the app build and the Play Services
  version, the device conditions that decide whether a passkey can be created at all

## 12. Conclusion

In this guide we covered **how to sync passkeys across devices and platforms** - from the
conceptual side (how iCloud Keychain, Google Password Manager and Microsoft Password
Manager handle passkey sync) to a practical implementation with Next.js, Flutter and
Golang.

Key takeaways:

- Use the same **Relying Party ID** for web and native apps to enable cross-platform
  passkey sharing
- **Passkeys transfer automatically** when switching to a new phone within the same
  ecosystem (iCloud Keychain for Apple, Google Password Manager for Android)
- **Cross-ecosystem transfer** (iPhone to Android) is now possible via third-party
  password managers and the new Credential Exchange Protocol (CXP)
- **Microsoft/Windows passkey sync** now supports both native and third-party passkey
  managers

Join our [passkeys community](https://bit.ly/passkeys-community) for further discussions
and subscribe to our [passkeys Substack](https://passkeys.substack.com/) for the latest
developments in passkey authentication.

## Frequently Asked Questions

### How do I enable passkey sharing between a Flutter native app and a web app?

Both apps must share the same Relying Party ID, which cryptographically binds passkeys to
a specific domain. For iOS, host an apple-app-site-association file with the
webcredentials entitlement at the Relying Party ID domain; for Android, host an
assetlinks.json file with the delegate_permission/common.get_login_creds relation
including your app's package name and SHA-256 certificate fingerprint. Once configured, a
passkey created in either app can be used to authenticate in the other.

### Can I access iCloud Keychain passkeys on a Windows computer or Android device?

No, iCloud Keychain is limited to Apple's ecosystem and is not available on Windows or
Android. To use passkeys across Apple and non-Apple devices today, use a cross-platform
password manager like 1Password or Dashlane installed on all devices, or authenticate on
another device via QR code and Bluetooth hybrid transport. With iOS 26, Apple introduced
passkey export via the Credential Exchange Protocol (CXP), enabling cross-ecosystem
transfers for the first time.

### What happens to my passkeys if I switch from an iPhone to a new Android phone?

iCloud Keychain passkeys cannot be transferred directly to Android because the two
ecosystems do not share a common passkey store. The best current approach is to use a
cross-platform passkey manager like 1Password or Dashlane on both devices, or to
authenticate cross-device using QR code and Bluetooth hybrid transport. iOS 26's support
for the Credential Exchange Protocol (CXP) also enables passkey migration between
ecosystems for the first time.

### How does Microsoft Windows sync passkeys and which third-party managers are supported?

Microsoft introduced passkey saving and syncing via Microsoft Password Manager in
2024-2025, making passkeys available across all Windows devices signed into the same
Microsoft account, similar to how iCloud Keychain works for Apple devices. Starting in
late 2025, Windows 11 added a plugin model for third-party passkey managers, allowing
tools like 1Password and Dashlane to integrate natively with the Windows passkey system.
