> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Passkey Authentication

Passkeys in React Native provide secure authentication for both primary authentication (1FA) and multi-factor authentication (2FA), allowing users to use passkeys as their primary login method or as a second factor to enhance account security.

To use passkeys in your React Native app, your website domain must grant credential access to the mobile app so passkeys can be created associated with the website domain. This allows users to seamlessly use the same passkeys across both your app and website.

## Prerequisites

Before setting up passkeys, ensure you have:

* A React Native project with Dynamic SDK already integrated
* A domain/website that you control (for hosting the required `.well-known` endpoints)
* Access to your app's bundle identifier and signing certificates
* For iOS: Apple Developer account and Xcode
* For Android: Android Studio and signing key information

## Installation

Install the required package using your preferred package manager:

<Tabs>
  <Tab title="expo">
    ```bash Shell theme={"system"}
    npx expo install react-native-passkey@3.1.0
    ```
  </Tab>

  <Tab title="npm">
    ```bash Shell theme={"system"}
    npm install react-native-passkey@3.1.0
    ```
  </Tab>

  <Tab title="yarn">
    ```bash Shell theme={"system"}
      yarn add react-native-passkey@3.1.0
    ```
  </Tab>
</Tabs>

### Post-Installation Steps

After installing the `react-native-passkey` package, you need to link the native packages to your project:

#### For iOS

```bash Shell theme={"system"}
cd ios && pod install
```

#### For Expo Projects

If you are using Expo, you may need to run a prebuild or create a new build:

```bash Shell theme={"system"}
expo prebuild
```

Or use the EAS service to create a new build for your app:

```bash Shell theme={"system"}
eas build
```

<Note>
  After running `expo prebuild`, you'll need to rebuild your app for the native modules to be properly linked.
</Note>

## Configuration

### Dynamic SDK Configuration

To create passkeys associated with the correct website, you must configure the `appOrigin` in the ReactNativeExtension:

```typescript theme={"system"}
const dynamicClient = createClient({
  environmentId: 'YOUR-ENVIRONMENT-ID',
}).extend(
  ReactNativeExtension({
    appOrigin: 'https://yourdomain.com' // Replace with your actual domain
  })
);
```

<Warning>
  The `appOrigin` must match your website domain exactly (e.g., `https://example.com`). This domain will be used to create and associate passkeys, so ensure it's the same domain where you'll host the required `.well-known` endpoints.
</Warning>

## OS Configuration

### iOS

There are iOS-specific steps to configure Passkey support. If you have already set up an associated domain for your application, you can skip this step.

#### Set Up an Associated Domain for Your Application

Follow the [Apple documentation](https://developer.apple.com/documentation/xcode/supporting-associated-domains) to associate a domain with your application. On your webserver, set up this route:

```
GET https://\{\{yourdomain\}\}/.well-known/apple-app-site-association
```

This route should serve a static JSON object containing your team ID and bundle identifier. Example (replace XXXXXXXXXX with your team identifier and "YYY.YYYYY.YYYYYYYYYYYYYY" with your bundle ID, e.g., H123456789.com.example.mobileApp):

```tsx theme={"system"}
{
  "applinks": {
    "details": []
  },
  "webcredentials": {
    "apps": ["XXXXXXXXXX.YYY.YYYYY.YYYYYYYYYYYYYY"]
  }
}
```

In Xcode, under Signing & Capabilities, add a new Capability of type Associated Domains. Now add this and replace XXXXXX with your domain (e.g., apple.com):

```tsx theme={"system"}
webcredentials:XXXXXX
```

If you are using Expo, add the webcredentials:\{\{yourdomain}} to your app.json file. See the [Expo documentation](https://docs.expo.dev/guides/deep-linking/#native-apple-configuration) for more details.

<Note>
  You can validate your Apple App Site Association (AASA) configuration using the [Branch AASA Validator](https://branch.io/resources/aasa-validator/). This tool tests your domain against Apple's requirements and helps ensure your Universal Links and passkey setup is properly configured.
</Note>

```tsx theme={"system"}
{
  "expo": {
    "ios": {
      "associatedDomains": ["webcredentials:\{\{yourdomain\}\}"]
    }
  }
}

```

### Android

The Android-specific configuration is similar to iOS. If you have already set up Digital Asset Links for your application, you can skip this step.

#### Associate Your App with a Domain

Follow the [Android documentation](https://developer.android.com/training/sign-in/passkeys?hl=pt-br#add-support-dal) to associate a domain with your application. On your webserver, set up this route:

```
GET https://\{\{yourdomain\}\}/.well-known/assetlinks.json
```

This route should serve a static JSON object containing the following information (replace with your data, and replace SHA\_HEX\_VALUE with the SHA256 fingerprints of your Android signing certificate):

```json theme={"system"}
[{
  "relation": [
    "delegate_permission/common.get_login_creds",
    "delegate_permission/common.handle_all_urls"
  ],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example",
    "sha256_cert_fingerprints": [
      SHA_HEX_VALUE
    ]
  }
}]
```

## Managing passkeys

Now that your application has correctly associated your domain with your application, you can register and authenticate using passkeys for both primary authentication (1FA) and multi-factor authentication (2FA).

### Register a passkey

The passkey module provides a method to trigger passkey registration. Here's an example:

```tsx theme={"system"}
import { dynamicClient } from '<path to the dynamic client>';

const App = () => {
  const handleRegisterPasskey = async () => {
    try {
      await dynamicClient.passkeys.register();
      console.log('Passkey registered successfully');
    } catch (error) {
      console.error('Failed to register passkey:', error);
    }
  };

  return (
    <Button
      title="Register passkey"
      onPress={handleRegisterPasskey}
    />
  );
};
```

When the user taps the button, the passkey registration flow will be triggered and the OS will prompt the user to register a passkey.

### Authenticate with passkeys (1FA)

You can use passkeys as the primary authentication method. Here's how to implement passkey-based sign-in:

```tsx theme={"system"}
import { dynamicClient } from '<path to the dynamic client>';

const App = () => {
  return (
    <Button
      title="Login with Passkey"
      onPress={() => dynamicClient.auth.passkey.signIn()}
    />
  );
};
```

### Use passkeys for MFA (2FA)

For multi-factor authentication, you can use the following methods to list and authenticate with passkeys:

* `dynamicClient.passkeys.get()` - Retrieves all registered passkeys for the user
* `dynamicClient.passkeys.authenticateMFA()` - Uses a registered passkey for multi-factor authentication

Here's a complete example for 2FA:

```tsx theme={"system"}
import { dynamicClient } from '<path to the dynamic client>';
import { useState, useEffect } from 'react';

const App = () => {
  const [passkeys, setPasskeys] = useState([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const loadPasskeys = async () => {
      try {
        setLoading(true);
        const userPasskeys = await dynamicClient.passkeys.get();
        setPasskeys(userPasskeys);
      } catch (error) {
        console.error('Failed to load passkeys:', error);
      } finally {
        setLoading(false);
      }
    };

    loadPasskeys();
  }, []);


  const handleAuthenticate = async () => {
    try {
      const verifyResponse = await dynamicClient.passkeys.authenticateMFA();
      console.log('Authentication successful:', verifyResponse);
    } catch (error) {
      console.error('Authentication failed:', error);
    }
  };

  if (loading) {
    return <Text>Loading passkeys...</Text>;
  }

  return (
    <View>
      <Text>Registered Passkeys: {passkeys.length}</Text>
      {passkeys.length > 0 ? (
        <Button
          title="Authenticate with passkey"
          onPress={handleAuthenticate}
        />
      ) : (
        <Text>No passkeys registered. Register a passkey first.</Text>
      )}
    </View>
  );
};
```

## Conclusion

By following these steps, you can successfully integrate passkey functionality with the Dynamic SDK into your React Native app. This enables secure authentication for both primary login (1FA) and multi-factor authentication (2FA), providing users with a seamless and secure authentication experience across your mobile app.
