If you’re unfamiliar with passkeys broadly, head to for an overview. TL;DR: passkeys are cryptographic key pairs generated and stored on secure hardware. Typically this is your Mac’s or iPhone’s , your Android’s , or an external security key plugged in via USB.
Creating and using passkeys on the web is straightforward: browsers offer APIs to do it!
navigator.credentials.create
creates a passkeynavigator.credentials.get
prompts the user to select a passkey to sign a messageAnd this doesn’t require a backend. Here’s a demo proving it: https://passkeyapp.tkhqlabs.xyz/
An important security feature of passkeys: they’re domain-bound to prevent phishing. In other words: passkeys created on passkeyapp.tkhqlabs.xyz
won’t be usable on turnkey.com
for example. Browsers prevent this.
In the Android ecosystem the CredentialManager
supports creating and using passkeys with CreatePublicKeyCredentialRequest
and GetCredentialRequest
. See the associated documentation for more information.
iOS APIs to create and use passkeys are available as well:
ASAuthorizationPlatformPublicKeyCredentialProvider(…).createCredentialRegistrationRequest
for passkey creationASAuthorizationPlatformPublicKeyCredentialProvider(…).createCredentialAssertionRequest
for passkey usageSee these docs for more info. And this app for a mini demo.
While the native APIs to interact with passkeys exists on both iOS and Android, Turnkey doesn’t yet offer an SDK for Swift or Kotlin, which means you’d have to write code to sign activities and send HTTP requests to our API. Get in touch with us if this is something you’re attempting to do, we’d love to support you and release this as a proper SDK maintained by Turnkey.
Turnkey has a fully-featured TypeScript SDK. It provides a type-safe client to call the Turnkey API and abstracts activity request signing.
React Native lets you write your app in Typescript and compile it into native code for both iOS and Android automatically.
To sign Turnkey requests with native passkeys in a React Native application we’ve released @turnkey/react-native-passkey-stamper
, a package compatible with our TypeScript client to sign Turnkey requests with native passkeys.
Under the hood this package wraps react-native-passkey
, which calls the right native APIs on iOS and Android, and exports a unified interface that we leverage.
Bottom-line: if you’ve used our webauthn stamper or API key stamper, using our React Native passkey stamper will feel familiar. Take a look at the “Installation” and “Usage” sections to get started with passkeys in your React Native application.
If you’re looking for a concrete example, head to this repository: it contains a sample application integrated with Turnkey, written with Expo, and tested on both Android and iOS.
Passkeys on native apps aren’t app-bound, they’re domain bound just like web passkeys. This may come as a surprise: you’ll have to configure a web domain to use passkeys natively! Configuration is done separately per ecosystem, but the idea is the same:
/.well-known /apple-app-site-association
) : example/.well-known/assetlinks.json
): exampleThis unlocks interesting flows where users use their web-created passkeys in a “companion” native app, or vice-versa. For example: a native app linked to the wallet.tx.xyz domain would allow users to log into their account from a native mobile app using their web-created passkey as long as they’re synced properly.
Note that these associations are “many-to-many”: a website can link multiple associated apps, and a single native application can choose to create passkeys for multiple domains, via a dropdown for example. However (as far as we know) a single passkey is always bound to a single web domain: it can’t be bound to multiple web domains.
If you’re unfamiliar with passkeys broadly, head to for an overview. TL;DR: passkeys are cryptographic key pairs generated and stored on secure hardware. Typically this is your Mac’s or iPhone’s , your Android’s , or an external security key plugged in via USB.
Creating and using passkeys on the web is straightforward: browsers offer APIs to do it!
navigator.credentials.create
creates a passkeynavigator.credentials.get
prompts the user to select a passkey to sign a messageAnd this doesn’t require a backend. Here’s a demo proving it: https://passkeyapp.tkhqlabs.xyz/
An important security feature of passkeys: they’re domain-bound to prevent phishing. In other words: passkeys created on passkeyapp.tkhqlabs.xyz
won’t be usable on turnkey.com
for example. Browsers prevent this.
In the Android ecosystem the CredentialManager
supports creating and using passkeys with CreatePublicKeyCredentialRequest
and GetCredentialRequest
. See the associated documentation for more information.
iOS APIs to create and use passkeys are available as well:
ASAuthorizationPlatformPublicKeyCredentialProvider(…).createCredentialRegistrationRequest
for passkey creationASAuthorizationPlatformPublicKeyCredentialProvider(…).createCredentialAssertionRequest
for passkey usageSee these docs for more info. And this app for a mini demo.
While the native APIs to interact with passkeys exists on both iOS and Android, Turnkey doesn’t yet offer an SDK for Swift or Kotlin, which means you’d have to write code to sign activities and send HTTP requests to our API. Get in touch with us if this is something you’re attempting to do, we’d love to support you and release this as a proper SDK maintained by Turnkey.
Turnkey has a fully-featured TypeScript SDK. It provides a type-safe client to call the Turnkey API and abstracts activity request signing.
React Native lets you write your app in Typescript and compile it into native code for both iOS and Android automatically.
To sign Turnkey requests with native passkeys in a React Native application we’ve released @turnkey/react-native-passkey-stamper
, a package compatible with our TypeScript client to sign Turnkey requests with native passkeys.
Under the hood this package wraps react-native-passkey
, which calls the right native APIs on iOS and Android, and exports a unified interface that we leverage.
Bottom-line: if you’ve used our webauthn stamper or API key stamper, using our React Native passkey stamper will feel familiar. Take a look at the “Installation” and “Usage” sections to get started with passkeys in your React Native application.
If you’re looking for a concrete example, head to this repository: it contains a sample application integrated with Turnkey, written with Expo, and tested on both Android and iOS.
Passkeys on native apps aren’t app-bound, they’re domain bound just like web passkeys. This may come as a surprise: you’ll have to configure a web domain to use passkeys natively! Configuration is done separately per ecosystem, but the idea is the same:
/.well-known /apple-app-site-association
) : example/.well-known/assetlinks.json
): exampleThis unlocks interesting flows where users use their web-created passkeys in a “companion” native app, or vice-versa. For example: a native app linked to the wallet.tx.xyz domain would allow users to log into their account from a native mobile app using their web-created passkey as long as they’re synced properly.
Note that these associations are “many-to-many”: a website can link multiple associated apps, and a single native application can choose to create passkeys for multiple domains, via a dropdown for example. However (as far as we know) a single passkey is always bound to a single web domain: it can’t be bound to multiple web domains.