webauthn-relying-party-id-rpid-passkeysWebAuthn Know-How

WebAuthn Relying Party ID (rpID) & Passkeys: Domains & Native Apps

This blog post explains WebAuthn Relying Party ID for passkey authentication. It outlines the right configuration, domains matching & native app configurations.

Blog-Post-Author

Vincent

Created: September 21, 2023

Updated: October 2, 2024


Our mission is to make the Internet a safer place, and the new login standard passkeys provides a superior solution to achieve that. That's why we want to help you understand passkeys and its characteristics better.

1. Introduction#

Passkey authentication is quickly becoming the norm as tech giants like TikTok, GitHub, and WhatsApp, X (Twitter), LinkedIn, and Amazon roll them out or already have so. Its evident that the tech world is recognizing the importance of simple and secure authentication.

Beyond the seamless user experience of authenticating with Face ID, Touch ID or Windows Hello, passkeys offer unparalleled security compared to traditional authentication methods like passwords. One of the standout features is the 100% phishing-resistance.

Demo Icon

Want to try passkeys yourself? Check our Passkeys Demo.

Try Passkeys

A phishing attack is an attack where the victim is tricked to provide credentials to a fake site that mimics to be the original site. For instance, imagine receiving an email from what seems to be your bank, asking you to log in. You click the link, and the website looks legitimate, so you enter your credentials and the attacker can use them to log into the original site. This is becoming an ever-increasing problem in the digital era and even major companies like Okta (an authentication provider!) or Retool have fallen victim to spear-phishing attacks (a special form of phishing where single victims are particularly targeted speared with very personal phishing tricks), emphasizing the need for robust security measures.

Contrary, if you use a passkey, and the site is a fake, your authentication will fail. This is because passkeys are bound to the domains they were created for via the Relying Party ID.

You cannot login with a passkey on any other site it is technically impossible it is a 100% phishing protection for the user.

This mechanism is baked into WebAuthn, the passkey- underlying web standard for passwordless authentication. WebAuthn is built on two core ceremonies: the registration and authentication ceremony.

During the registration (sign-up) ceremony a new passkey is created for an online service (the Relying Party) via a web or native app. In this process, the domain (Relying Party ID) for which the passkey is created is stored in the passkey.

This allows the authentication (login) ceremony to check if the online service (the Relying Party), that the web or native app belongs to, matches with the Relying Party ID stored in the passkey.

In the following, well see in detail how this domain matching process works and how, in particular, native apps are secured.

2. What is the Relying Party ID?#

The Relying Party ID is essentially a domain stored within the passkey, ensuring the passkey only works if the current browser URL (the users origin that is automatically sent on every request) matches it (see the native app approach below). It's a crucial component of the WebAuthn specification, which you can delve into here. The Relying Party ID can be the root domain (e.g. corbado.com) or a subdomain (auth.corbado.com). You cannot store the root domain as Relying Party ID it if it is on the public suffix list (find the list and libraries for public suffix detection here). Changing the Relying Party ID for an online service will break existing passkeys (the only exception: the new Relying Party ID is a subdomain of the old Relying Party ID).

During the authentication process, the Relying Party ID is checked against the browser URL (user's origin) to ensure they match. Matching in this sense means that either:

  • The browser URL (users origin) matches precisely Relying Party ID OR
  • The browser URL (user's origin) is a subdomain that matches the Relying Party ID and the parent domain is registrable (e.g. com or any domain on the Public Suffix List don't work)

Here is a detailed outline which originalHost(second column) is allowed to access its parent domain:

WebAuthn: Which originalHost is allowd to access its parent domain

In the following, you see the parsed PublicKeyCredentialCreationOptions:

{ "publicKey":{ "attestation":"direct", "authenticatorSelection":{ "authenticatorAttachment":"platform", "requireResidentKey":false, "userVerification":"preferred" }, "challenge":"qNqrdXUrk5S7dCM1MAYH3qSVDXznb-6prQoGqiACR10=", "excludeCredentials":[ ], "pubKeyCredParams":[ { "alg":-7, "type":"public-key" } ], "rp":{ "id":"corbado.com", "name":"Corbado" }, "timeout":30000, "user":{ "displayName":"Corbado user", "id":"bz9ZDfHzOBLycqISTAdWwWIZt8VO-6mT3hBNXS5jwmY=" } } }

rp stands for Relying Party.

One of the major benefits of the Relying Party ID is the prevention of phishing attacks. Imagine the following scenario:

  1. An attacker develops a PayPal clone which is a fake website that tries to steal your PayPal credentials to log in in the name of you and send money to the attackers account. This fake PayPal website is hosted on the domain paybal.com (so its often not visible that its a different domain at first sight).
  2. You have already created a passkey in the past for the legitimate PayPal site. This passkey stored the Relying Party ID paypal.com.
  3. You visit the PayPal fake website at paybal.com (as you visit this site, the origin of your request is paybal.com*) and the site sends your device (the authenticator) a challenge for the Relying Party ID paypal.com (here it tries to trick you) and asks you to sign it with your passkey for the Relying Party ID paypal.com.
  4. Your device (the authenticator) checks if the origin of the request (paypal.com) and the Relying Party ID it stored in the passkey (paypal.com) match.
  5. As they obviously do not match, the authentication fails and it saves you from giving some attacker access to your PayPal account.

In the case of a native app, the origin is the native app itself, e.g. for iOS apps <App Identifier Prefix>.<BundleIdentifier>. Here, its checked if there is an association between your locally installed native app and the server that needs to provide the corresponding association file (see below).

Slack Icon

Become part of our Passkeys Community for updates and support.

Join

3. The Two Different Integration Options for Native Apps#

To implement passkeys in a native app, a developer can decide between adding them via WebView or natively. Lets examine the benefits and disadvantages of both approaches in the following.

3.1 Passkey Integration via WebView#

Passkey Integration WebView (GitHub)

Using a WebView* to integrate passkeys means embedding a web browser within the native app to handle the authentication process. This approach essentially displays a web page inside the app, making it easier to reuse web- based authentication flows without having to rewrite them for the native platform. However, there are some drawbacks. WebViews might not support all passkey features, and there's a potential risk of "man-in-the-middle" attacks if not implemented securely. Additionally, the user experience might not be as smooth as with native integrations, and there can be challenges in maintaining consistent behavior across different devices and OS versions.

*There are multiple types of WebViews : On iOS (WKWebView, SFSafariViewController or SFAuthenticationSession / ASWebAuthenticationSession for OAuth/OpenID Connect based authentication flows) and Android (WebView, CCT-Chrome Custom Tabs). See this blog post for details. We recommend to use SFSafariViewController/ ASWebAuthenticationSession and Chrome Custom Tabs in the context of passkeys if you do not want a native integration.

StateOfPasskeys Icon

Want to find out how many people can use passkeys?

View Adoption Data

3.2 Native Passkey Integration#

Native Passkey Integration (Kayak)

Native integration involves building the passkey functionality directly into the iOS or Android app using platform-specific APIs and libraries. This method offers a more seamless user experience, as there's no need to transition between the native app and a WebView. It also allows for better performance and a more consistent look and feel. From a security standpoint, the native integration can offer enhanced protection against certain types of attacks, especially when combined with platform-specific security features. However, the implementation effort can be higher, as developers need to write and maintain separate code for each platform (Android and iOS). Additionally, staying updated with the latest passkey / WebAuthn specifications might require more frequent app updates.

In the following, we focus on the native passkey integration.

Analyzer Icon

Are your users passkey-ready?

Test Passkey-Readiness

4. Configuring the Relying Party for Native Apps#

Native apps (e.g. iOS or Android apps) present a challenge compared to web apps. Unlike web apps, there's no browser URL to match against the Relying Party ID. Nevertheless, to ensure the same level of security, domains are connected to native apps via association files , so that trust between a domain and a native app is established.

This is particularly important if a passkey was created on a web app and should be used for the same Relying Party ID on a native app (and vice versa).

4.1 Association Files on iOS: apple-app-site-association#

iOS uses the apple-app-site-association file. This file contains various entitlements, but for WebAuthn and passkeys, the webcredentials entitlement is important.

{ "webcredentials":{ "apps":[ "9RF9KY88B2.com.corbado.passkeys" ] } }

In webcredentials.apps, you need to store your Application Identifier Prefix (e.g. 9RF9KY77B2) and your Bundle Identifier (e.g. com.corbado.passkeys).

For iOS native apps to work, the apple-app-site-association file must be stored under the Relying Party IDs /.well-known directory (https://<Relying Party ID>/.well-known/apple-app-site-association).

See a live example here.

4.2 Association Files on Android: assetlinks.json#

Android uses the assetlinks.json file, which, like its iOS counterpart, requires particular configurations for WebAuthn and passkeys.

[ { "relation":[ "delegate_permission/common.handle_all_urls", "delegate_permission/common.get_login_creds" ], "target":{ "namespace":"android_app", "package_name":"com.corbado.passkeys.pub", "sha256_cert_fingerprints":[ "F8:90:4E:9A:99:01:71:75:25:38:D5:36:16:2D:B3:65:EB:41:51:D4:53:9A:72:BC:4B:56:C5:16:43:62:E2:C0" ] } } ]

You need to have the relation values delegate_permission/common.handle_all_urls and delegate_permission/common.get_login_creds set. Besides, you need to add your package name and the SHA-256 fingerprint of your signing certificate.

To allow the sharing of a passkey between a native app and a web app, you need to add two entries. One for the namespace web and one for the namespace android_app.

See a live example here.

For Android apps to work, the assetlinks.json file must be stored under the Relying Party IDs /.well-known directory https://<Relying Party ID>/.well- known/assetlinks.json - so pretty much like on iOS).

Check out this blog post to see a sample implementation that shares passkeys between a native Android / iOS app and a web app.

Debugger Icon

Want to experiment with passkey flows? Try our Passkeys Debugger.

Try for Free

5. Establish Trust between a Native App and Web App#

5.1 iOS#

The process to establish trust between an iOS app and web app looks as follows:

  1. The iOS app developer has to specify a list of domains he wants to associate with the native app. These domains are hardcoded in the iOS apps entitlements, e.g.:
  • webcredentials:auth.corbado.com
  • webcredentials:*.corbado.com
  1. Every time the iOS app is installed or updated, iOS will download the apple-app-site-association file for each entry of the iOS apps entitlement list.

  2. When a credential (e.g. passkey) is created inside an iOS app, the iOS app validates if the relying party servers domain is associated with the iOS app by checking the following two aspects:

  • Is there an apple-app-site-association file for this relying party servers domain existing on the device?
  • Is the iOS app listed in that apple-app-site-association file?

If, and only if, both questions can be answered with yes, a passkey can be created within the iOS app.

Ben Gould Testimonial

Ben Gould

Head of Engineering

I’ve built hundreds of integrations in my time, including quite a few with identity providers and I’ve never been so impressed with a developer experience as I have been with Corbado.

10,000+ devs trust Corbado & make the Internet safer with passkeys. Got questions? We’ve written 150+ blog posts on passkeys.

Join Passkeys Community

5.2 Android#

The process to establish trust between an Android app and web app looks as follows:

  1. The Android app developer has to specify a list of domains he wants to associate with the Android app. These domains are stored as targets with the namespace web in the assetlinks.json file. To declare that Android apps and web apps share credentials, delegate_permission/common.get_login_creds needs to be specified. Find details here.

  2. If a passkey is created inside the Android app, the Android app validates if the Relying Party ID is associated with the Android app by checking the assetlinks.json:

  • Is there an assetlinks.json file for this Relying Party ID at https://<Relying Party ID>./well-known/assetlinks.json
  • Is the Android app correctly defined as a target.
  1. If, and only if, both questions can be answered with yes, a passkey can be created within the Android app.
Substack Icon

Subscribe to our Passkeys Substack for the latest news, insights and strategies.

Subscribe

6. Overview for Android, iOS & Flutter Settings#

In the following, we provide a detailed overview for the different settings that are required to properly set up passkey authentication for native apps.

FeatureiOSAndroid
Official implementation guidance for native passkey authenticationApple DeveloperGoogle Developer
Allows sharing passkeys with web appsYes, via apple-app-site-association fileYes, via assetlinks.json
Location of association filehttps://acme.com/.well-known/apple-app-site-associationhttps://acme.com/.well-known/assetlinks.json
File cachedYes (since iOS 14), initial sync may take up to 24hYes (by Play Services)
By-pass possibleYes, with alternate mode sectionNo
Testable withapple-app-site-association testassetlinks.json test
App identifier with sample<Application Identifier Prefix>.<Bundle Identifier>, e.g. T84QZS65DQ.com.facebook.MessengerSHA256 fingerprint,e.g. E3:F9:E1:E0:CF:99:D0:E5:6A:05:5B:A6: 5E:24:1B:33:99: 7F:CE:A5:24:32: 6B:0C:DD:6E:C1:32: 7E:D0:FD:C1
Where to find app identifierThe Team Application Identifier Prefix can be found in the developer account on developer.apple.com and the Bundle Identifier is the exact name from within the XCode projectWhen already uploaded: Google Play Console > Release management > App signing Local: keytool -list -v -keystore <keystore path> -alias <key alias> -storepass <store password> -keypass <key password>
Name of section that links app to webapplinks (not required for passkeys)delegate_permission/common.handle_all_urls (required for passkeys)
Name of section that allows credential sharing between app / webwebcredentialsdelegate_permission/common.get_login_creds
Registry of all association filesEnable and add associated domain in XCode development environment (setting of property to generate entitlements file)When using the Credential Manager API, the registry of the assetlinks.json in manifest is not required for passkeys (for passwords it is though). When not using the Credential Manager API, you need to list the hostnames with <data>-entry in AndroidManifest.xml in the specific activity (part of Android-App source Code). The <intent-filter android:autoVerify="true"> needs to be autoVerify=true.

For Flutter, the respective rule of Android or iOS applies. The only Flutter- specific setting is the registry of association files, where you should add:

7. Examples for Valid & Invalid Relying Party ID & Association Files#

As we experienced ourselves, working with Relying Party IDs, different levels of (sub-)domains and CNAMEs can be quite a challenging task, we present four distinct examples and explain why and how they work.

Note, that the CNAME table row is not required for passkey authentication and just a result of our research that we wanted to add.

7.1 Example 1: Relying Party is the Root Domain#

Relying Party IDcorbado.com
Entitlements (iOS only)webcredentials:corbado.com
Location apple-app-site-association filehttps://corbado.com/.well-known/apple-app-site-association
Location assetlinks.json filehttps://corbado.com/.well-known/assetlinks.json
CNAMEn/a

In this example, the apple-app-site-association / assetlinks.json file for corbado.com can be downloaded without any issues when the native app is installed / updated, because the file is on the same location as the Relying Party ID.

A passkey for the Relying Party ID can be created.

7.2 Example 2: Relying Party is a Subdomain and CNAME is set#

Relying Party IDauth.corbado.com
Entitlements (iOS only)webcredentials:auth.corbado.com
Location apple-app-site-association filehttps://pro-123.passkeys.eu/.well-known/apple-app-site-association
Location assetlinks.json filehttps://pro-123.passkeys.eu/.well-known/assetlinks.json
CNAMEauth.corbado.com => pro-123.passkeys.eu

In this example, the apple-app-site-association / assetlinks.json file for auth.corbado.com can be downloaded without any issues when the native app is installed / updated, because the file is on the location as the Relying Party ID, as the CNAME points from the Relying Party ID to the stored location.

A passkey for the Relying Party ID can be created.

7.3 Example 3: Relying Party is the Root Domain and CNAME is set#

Relying Party IDcorbado.com
Entitlements (iOS only)webcredentials:corbado.com; webcredentials:auth.corbado.com
Location apple-app-site-association filehttps://pro-123.passkeys.eu/.well-known/apple-app-site-association
Location assetlinks.json filehttps://pro-123.passkeys.eu/.well-known/assetlinks.json
CNAMEauth.corbado.com => pro-123.passkeys.eu

In this example, the apple-app-site-association / assetlinks.json file for auth.corbado.com can be downloaded without any issues when the native app is installed / updated, because the file is, due to the CNAME, on the location, where auth.corbado.com expects it.

BUT: The apple-site-association-file / assetlinks.json for corbado.com cannot be downloaded, when the native app is installed / updated, because the file is not at https://corbado.com/.well-known/apple-app-site-association / https://corbado.com/.well-known/assetlinks.json, where it is expected and no CNAME is pointing to it.

A passkey for the Relying Party ID cannot be created.

7.4 Example 4: Relying Party is a Subdomain & Wildcard Entitlement is set#

Relying Party IDauth.corbado.com
Entitlements (iOS only)webcredentials:*.corbado.com
Location apple-app-site-association filehttps://corbado.com/.well-known/apple-app-site-association
Location assetlinks.json filehttps://corbado.com/.well-known/assetlinks.json
CNAMEn/a

In this example, the apple-app-site-association file for corbado.com can be downloaded without any issues, when the native app is installed / updated, because the file is where its expected and the webcredentials entitlement (*.corbado.com) matches the Relying Party ID (auth.corbado.com). Note that this example does not work for Android, as Android does not work with something like (wildcard) entitlements. In general, this way of defining Relying Party IDs is not recommended.

A passkey for the Relying Party ID can be created.

Slack Icon

Become part of our Passkeys Community for updates and support.

Join

8. Common Relying Party ID Mistakes & How to Avoid Them#

8.1 Changing Relying Party ID from Subdomain to Root Domain#

Mistake:

You started developing and defined a subdomain (e.g. login.acme.com) as your Relying Party ID. First users created a passkey for this Relying Party ID. Then, you notice that you also need these passkeys for authentication on another subdomain (e.g. app.acme.com). As the origin of a user and the Relying Party ID for the new subdomain dont match, the user cannot sign-in with the passkey. Changing the Relying Party ID in your WebAuthn settings to acme.com would invalidate all existing passkeys, as the new origin and the Relying Party ID stored in the existing passkeys do not match.

Solution:

Double-check initially when defining your Relying Party ID as this is more or less final. If you are unsure and want to be future-ready, meaning that other subdomains in the future might need the passkey for authentication, we recommend to use the root domain (e.g. acme.com) as Relying party ID unless it is on the Public Suffix List.

8.2 Different Relying Party IDs for Native and Web App#

Mistake:

Youre developing a native and web app simultaneously. To speed things up, you use two different WebAuthn servers (with different Relying Party IDs for the native and web app). As your users create the first passkeys, the respective Relying Party ID is stored in the passkey. Allowing cross-device / cross-platform login with the same passkey, e.g. with a passkey created in a web app and trying to sign-in in a native app, is not possible anymore. Merging the two WebAuthn server will abandon the passkeys which were registered with the old WebAuthn server (old Relying Party ID) and your users cannot login with these passkeys.

Solution:

If you have a multiple applications (e.g. a web app and a native app), always have only one WebAuthn server and define only one Relying Party ID for all your apps. Linking between these app can be done via the steps described above.

8.3 Invalid and Unreachable Association Files#

Mistake:

You start developing your application, configured the association files and deployed them to your server. For some reason, you are still getting error messages and dont find the root cause.

Solution:

A potential cause for the error message might be a malformed or unreachable association file. Before deploying any association file to a server, we highly recommend to check the validity and reachability (often these files might be behind a robust VPN or firewall that prevents the proper access for the crawlers of Apple and Google) of an association file via the tools provided for iOS and Android.

8.4 apple-app-site-#

association File Not Yet Cached by Apple CDN

Mistake:

You deployed your apple-app-site-association file to your server and want to immediately start creating a passkey on your test device. For some reason, you cannot create the passkey and get error messages.

Solution:

The reason behind these error messages is that iOS devices download the apple- app-site-association file to validate the Relying Party. To do so, iOS devices do not send a direct request to your server but use a CDN instead. Both the device and the CDN cache the apple-app-site- association file after it has been successfully retrieved. Due to this caching functionality, new changes in your apple-app-site-association file are not directly reflected in your app. It can take up to 24 hours until the CDN cached the apple-app-site-association file. To circumvent this restriction during development, you can append ?mode=developer to the Relying Party ID and disable caching completely (e.g. the Relying Party ID would be acme.com?mode=developer).

8.5 Android Emulator and API Version Incompatibility#

Mistake:

You start developing an Android app and want to test it on an Android emulator. For some, reason youre getting error messages, even though youve setup the Android emulator properly and other apps seem to work smoothly on it.

Solution:

Android versions, Play Store support and API versions play a major role when testing a passkey application. Besides, you need to be logged into a Google account. Please refer to our troubleshooting section for details.

9. Recommendation#

9.1 General Recommendation#

Our overall recommendation is to choose your Relying Party ID carefully based on your application landscape and requirements. Below, we have collected the most common use cases, but our general recommendation is that you should aim to choose your root domain as your Relying Party ID and configure your authentication this way. With Corbado, we've also already pre-configured it this ways for you (as its part of our approach to offering seamless passkey authentication for all technical setups. Our UI components and SDKs are prepared to be used with your root domain as relying Party ID).

CaseRecommendation
A) You have one root domain:

Example: acme.com

All applications and authentication runs on this root domain or subdomains of it
✔️ Choose the root domain as your Relying Party ID as this won’t cause any problems for web or native apps.
B) You have multiple root domains:

Example: kayak.com, kayak.co.uk, kayak.de

You serve your users from different international top-level domains. Kayak.com for USA and kayak.co.uk for the UK or you have completely different root domains that should allow the same users to login with the same passkeys.
❌ On your web apps you cannot share the passkeys. There is no solution to sharing passkeys in the web. You would need to at least choose a common authentication root domain.

✔️ You can connect your native apps to any number of root domains as long as you have control over the root association files.

❌ In case you want to later migrate to another root domain to host your website, you will not be able to use your already created passkeys, because you will have to rebrand and change the domain (Relying Party ID).
C) You do NOT have a root domain yet, you are running on backend only or on a public subdomain. There are some cases where this might happen:

1. You work on a freely available subdomain, where the root domain is not under your control (the root domain is listed in the https://publicsuffix.org/) for example CDN URLs

2. You work on a native app.
❌ On public subdomains, you cannot control the association files on the root level of the root domain Therefore, passkeys will not work natively.

⚠️ The only way to fix this for some services is to change to a paid plan, where you can define a CNAME or get a custom root domain for yourself.

9.2 Recommendation When Using Corbado#

In the following, we provide a very specific decision tree that should help you determine the right Relying Party ID and how should handle / host association files when using Corbado as your passkey solution.

The first decision is if you are in a development or production environment. The next level of decision you have to make is based on your application landscape: do you only have a native app or a native and web app.

A) Development#

For the development environment, we assume that you want to quickly start developing and testing. The Relying Party ID can be changed later if you want to go live.

A1) Native-Only#
  • Set Relying Party ID = pro-XXX.frontendapi.cloud.corbado.io (default value)
  • Corbado hosts the association file for you
  • No DNS ToDo for you
A2) Native App & Web App#

It's not easily possible to test both the web app and native app at the same time

Option 1:

Either you set Relying Party ID = pro-XXX.frontendapi.cloud.corbado.io (native app works) OR set Relying Party ID = localhost (web app works)

Option 2:

The only solution for native and web app to work at the same time is to use a local reverse proxy (it's a rather hacky solution):

  • Set Relying Party ID = acme-dev.com
  • Set CNAME from acme-dev.com => pro-XXX.frontendapi.cloud.corbado.io
  • Add local /etc/hosts entry localhost acme-dev.com
  • Add reverse proxy (nginx) with rule for acme-dev.com => localhost:3000 (as an example)

B) Production#

In the production environment, you have to decide if you are fine with a subdomain as Relying Party ID (e.g. auth.acme.com) or if you want a root domain as Relying Party ID (e.g. acme.com)

B1) Subdomain as Relying Party ID#
B1.1) Native-Only#
  • Set Relying Party ID = auth.acme.com
  • Corbado hosts the association file for you
  • Set CNAME from auth.acme.com => pro-XXX.frontendapi.cloud.corbado.io
B1.2) Native App & Web App#
  • Set Relying Party ID = auth.acme.com
  • Corbado hosts the association file for you
  • Set CNAME from auth.acme.com => pro-XXX.frontendapi.cloud.corbado.io (also needed for cookies to work if you use Corbado's session management)
B2) Root Domain as Relying Party ID#
B2.1) Native-Only#
  • Set Relying Party ID = acme.com
  • Host the association file yourself on your own server at acme.com/.well-known/<association file>
  • No DNS ToDo for you
B2.2) Native App & Web App#
  • Set Relying Party ID = acme.com
  • Host the association file yourself on your own server at acme.com/.well-known/<association file>
  • If you use, Corbado's sessions management, you need to set CNAME from auth.acme.com => pro-XXX.frontendapi.cloud.corbado.io to make cookies work (this CNAME is not needed for the Relying Party ID solely for session management)

10. Conclusion#

The Relying Party ID is a cornerstone of WebAuthn and passkey-based authentication and helps to prevent 100% of phishing attacks. Properly configuring it, understanding domain matching intricacies, and ensuring correct deployment for native apps is crucial. This blog post showed you how to set them up correctly and how to handle different mistakes. For further insights into setting up passkeys for native app, we recommend to read about passkeys in Flutter.

If you have further questions or need assistance, don't hesitate to reach out.

Share this article


LinkedInTwitterFacebook

Enjoyed this read?

🤝 Join our Passkeys Community

Share passkeys implementation tips and get support to free the world from passwords.

🚀 Subscribe to Substack

Get the latest news, strategies, and insights about passkeys sent straight to your inbox.


We provide UI components, SDKs and guides to help you add passkeys to your app in <1 hour

Start for free