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

# Device key storage

> Learn where the JavaScript SDK stores signing keys on Android and iOS, why Android uses the device's TEE by default, and when to opt in to StrongBox.

The JavaScript SDK creates two signing keys on the user's device: a session signing key and a device signing key. On React Native, the SDK generates both keys in the platform's secure hardware. This page explains where those keys live on Android and iOS, why Android uses the device's TEE by default, and what you gain and give up by opting in to StrongBox. The [glossary](#glossary) at the end defines each term.

This page covers only those two signing keys. It does not describe how embedded wallet key shares are stored. For that, see the [MPC overview](https://www.dynamic.xyz/docs/embedded-wallets/mpc/overview.md).

> [!NOTE]
>
> The TEE on this page is the trusted execution environment built into the user's Android device. It is not the server-side TEE that Dynamic uses for embedded wallets, which is a separate component.

## Platforms

The SDK creates keys in different hardware depending on the platform, and only Android lets you choose. If a term is unfamiliar, the [glossary](#glossary) defines it.

### Android TEE (default)

The SDK asks Android Keystore for a key backed by the device's TEE. This is the default from version 1.49.1, and it needs no configuration.

### Android StrongBox (opt-in)

When you set `reactNative.android.strongBox` to `true`, the SDK asks Android Keystore for a key backed by the StrongBox secure element. Devices without StrongBox get a TEE-backed key instead.

### iOS Secure Enclave

The SDK creates a P-256 key in the Secure Enclave, and iOS has no StrongBox-style alternative. The `strongBox` option is accepted and ignored on iOS.

## What TEE and StrongBox are

Android Keystore can bind a key to secure hardware, so that the key material is never exposed outside that hardware. Android offers two kinds of hardware for this.

* **TEE (trusted execution environment).** An isolated execution environment on the device's system on a chip, separate from the main Android operating system. Android most often implements its hardware-backed Keystore in a TEE.
* **StrongBox.** A separate secure element or integrated secure enclave. Android describes it as providing stronger isolation and tamper resistance than the TEE, and it must have its own CPU, secure storage, and a true random-number generator.

StrongBox is optional hardware. Android 9 (API level 28) and later can include it, but a device running Android 9 or later does not necessarily have it.

## The trade-off

The Android documentation describes StrongBox as appropriate for apps that need the highest level of security, particularly apps at risk of physical tampering or side-channel attacks. It also states that StrongBox is slower, more resource-constrained, and supports fewer concurrent operations than the TEE, and that most apps do not need it.

| Consideration | TEE (default) | StrongBox (opt-in) |
| - | - | - |
| Isolation | Isolated from the main operating system | Separate secure element with its own CPU and storage |
| Signing speed | Faster | Slower |
| Device support | Devices with hardware-backed Android Keystore | Only devices that include StrongBox |
| If unavailable | Not applicable | The SDK creates a TEE-backed key instead |

Every signature the SDK makes with one of these keys runs inside the secure hardware that holds it, so the speed difference applies to each signing operation, not only to key creation. The Android documentation gives no figure for the difference, and the size of the gap varies by device.

> [!NOTE]
>
> Before version 1.49.1, the SDK requested StrongBox on Android 9 and later and fell back to the TEE when StrongBox failed. Starting with version 1.49.1, the SDK requests a TEE-backed key unless you opt in. If your app relied on the earlier behavior, set `reactNative.android.strongBox` to `true` to keep requesting StrongBox.

## Enable StrongBox

Set `reactNative.android.strongBox` to `true` when you create the client. The option requires `@dynamic-labs-sdk/client` version 1.49.1 or later.

```typescript theme={"system"}
import { createDynamicClient } from '@dynamic-labs-sdk/client';

export const dynamicClient = createDynamicClient({
  environmentId: 'YOUR_ENVIRONMENT_ID',
  metadata: {
    name: 'YOUR_APP_NAME',
    nativeLink: 'myapp://',
    universalLink: 'https://yourapp.com',
    iconUrl: 'YOUR_APP_ICON_URL',
  },
  reactNative: {
    android: {
      strongBox: true,
    },
  },
});
```

After you upgrade, rebuild the native app. The option reaches Android through a native method that ships with the 1.49.1 native module, so it has no effect until the app contains a native build with that method. If a JavaScript bundle at 1.49.1 or later runs on a native build from an earlier version, for example after an over-the-air update, the SDK falls back to the earlier native method and Android still requests StrongBox where the device supports it, regardless of the option's value.

## How the option behaves

* The SDK reads the option when it creates a key. It does not regenerate keys that already exist, so a key keeps the hardware tier it was created with.
* With `strongBox` set to `true`, the SDK asks Android Keystore for a StrongBox-backed key on Android 9 or later. If key generation in StrongBox fails, for example because the device has no StrongBox, the SDK retries with a TEE-backed key, so key creation still succeeds.
* With `strongBox` unset or `false`, the SDK requests a TEE-backed key and does not attempt StrongBox.
* On iOS, the option has no effect because the SDK always creates keys in the Secure Enclave. On the web, the SDK ignores the option.

## Choose a setting

Keep the default for most apps. The TEE already keeps key material inside secure hardware, and it signs faster. Enable StrongBox when your threat model includes physical attacks on the device and you accept slower signing and the possibility that some devices fall back to the TEE.

## Related pages

* [Create a Dynamic client](https://www.dynamic.xyz/docs/javascript/reference/client/create-dynamic-client.md) lists every client option, including `reactNative`.
* [React Native setup](https://www.dynamic.xyz/docs/javascript/react-native/setup.md) covers the native configuration your app needs before you create the client.

## Glossary

| Term | Meaning |
| - | - |
| Android Keystore | The Android system service that creates and holds cryptographic keys for apps. It can bind a key to secure hardware. |
| Device signing key | A signing key that belongs to the user's device. The SDK uses it for device registration. |
| Hardware-backed key | A key whose material is bound to secure hardware, so that it is not exposed outside that hardware. |
| Secure element | A dedicated chip with its own processor and storage for sensitive operations. StrongBox is an Android implementation of one. |
| Secure Enclave | The dedicated secure subsystem built into Apple chips. Apple describes it as isolated from the main processor, so that it can protect sensitive data even if the main processor's kernel is compromised. |
| Session signing key | A signing key that the SDK creates for the user's session. |
| StrongBox | Android's optional secure-element-backed Keystore. It has its own CPU, secure storage, and random-number generator, and it is slower than the TEE. |
| TEE | The trusted execution environment: an isolated environment on the device's chip, separate from the main Android operating system. This is a device feature, not Dynamic's server-side TEE. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.