Skip to main content

Working with Secure Storage (expo-secure-store)

1. Storing Secure Data

Property Description Notes
setItemAsync(key, value, options) Stores a value securely under the given key Values are encrypted and stored in secure storage
setItemAsync(key, value, options) Stores a value securely under the given key Values are encrypted and stored in secure storage

Example: Storing a Token

import * as SecureStore from 'expo-secure-store';

await SecureStore.setItemAsync('authToken', 'abc123xyz');
Note: SecureStore uses platform-specific secure storage (Keychain on iOS, Keystore on Android).

2. Retrieving Secure Data

Method Description Return Type Notes
SecureStore.getItemAsync(key) Retrieves a value for the given key Promise<string | null> Resolves to the stored value or null if not found
SecureStore.getItemAsync(key, options) Retrieves a value for the given key with additional options Promise<string | null> Supports keychainService and accessControl options

Example: Retrieving Secure Data

import * as SecureStore from 'expo-secure-store';

const token = await SecureStore.getItemAsync('authToken');
if (token) {
  console.log('Retrieved token:', token);
} else {
  console.log('No token found');
}
Note: On Android, getItemAsync will return null if the key is not found, and on iOS it will throw an error if the key does not exist.

3. Deleting Secure Data

Method Description Notes
deleteItemAsync(key) Deletes the value associated with the given key. Returns a Promise that resolves when deletion is complete.
deleteItemAsync(key, options) Deletes the value associated with the given key using specified options. Supports secure storage options like keychainService.

Example: Deleting Secure Data

import * as SecureStore from 'expo-secure-store';

await SecureStore.deleteItemAsync('userToken');
console.log('Token deleted successfully');
Note: If the key does not exist, deleteItemAsync will resolve without error.

4. Setting Storage Options

Option Values Description
keychainService string Custom keychain service name for iOS. Defaults to app bundle ID.
keychainAccessGroup string Keychain access group for iOS. Allows sharing between apps.
sharedPreferencesName string Shared preferences name for Android. Defaults to app package name.
encryptionKey string Custom encryption key for Android. If not provided, uses default.

Example: Setting Custom Keychain Service

import * as SecureStore from 'expo-secure-store';

await SecureStore.setAsync("key", "value", {
  keychainService: "com.myapp.custom-service"
});

Example: Setting Shared Preferences Name

import * as SecureStore from 'expo-secure-store';

await SecureStore.setAsync("key", "value", {
  sharedPreferencesName: "com.myapp.shared-prefs"
});

5. Configuring Keychain Access

Example: Basic Keychain Configuration

import * as SecureStore from &#x27;expo-secure-store&#x27;;

const key = &#x27;my-secure-key&#x27;;
const value = &#x27;sensitive-data&#x27;;

await SecureStore.setItemAsync(key, value);
const retrieved = await SecureStore.getItemAsync(key);

console.log(retrieved); // "sensitive-data"
Configuration Option Description Default Value
keychainService Custom keychain service name for iOS expo-secure-store
keychainAccessGroup Keychain access group for iOS (requires entitlements) null
Note: On iOS, keychainAccessGroup requires the com.apple.developer.keychain-access-groups entitlement to be set in your app's Info.plist.
Warning: On Android, keychainAccessGroup is not supported and will be ignored.

6. Using Device Authentication

Example: Secure Storage with Biometric Authentication

import * as SecureStore from 'expo-secure-store';

const KEY = 'user_token';

// Store token with biometric lock
await SecureStore.setItemAsync(KEY, token, {
  keychainAccess: 'biometry',
});

// Retrieve token (requires biometric authentication)
const storedToken = await SecureStore.getItemAsync(KEY, {
  keychainAccess: 'biometry',
});
Option Values Description
keychainAccess 'biometry', 'devicePasscode', 'always' Controls how the keychain item is secured
keychainAccess 'never' Item is not secured with biometrics or passcode
Note: 'biometry' requires the device to have biometric hardware (fingerprint, face ID) and the user to have enrolled biometrics.
Warning: If the user removes their biometric data (e.g., deletes fingerprints), the stored items become inaccessible and must be re-registered.

7. Checking Availability

Method Description Return Type Notes
SecureStore.isAvailableAsync() Checks if secure storage is available on the device Promise<boolean> Returns true if secure storage is accessible, false otherwise

Example: Checking Secure Store Availability

import * as SecureStore from 'expo-secure-store';

async function checkSecureStoreAvailability() {
  const isAvailable = await SecureStore.isAvailableAsync();
  if (isAvailable) {
    console.log('Secure storage is available');
  } else {
    console.log('Secure storage is not available on this device');
  }
}

checkSecureStoreAvailability();

8. Storing Credentials

Example: Storing and Retrieving Credentials

import * as SecureStore from &#x27;expo-secure-store&#x27;;

const storeCredentials = async () => {
  await SecureStore.setItemAsync(&#x27;authToken&#x27;, &#x27;abc123xyz&#x27;);
  await SecureStore.setItemAsync(&#x27;refreshToken&#x27;, &#x27;def456uvw&#x27;);
};

const getCredentials = async () => {
  const token = await SecureStore.getItemAsync(&#x27;authToken&#x27;);
  const refreshToken = await SecureStore.getItemAsync(&#x27;refreshToken&#x27;);
  return { token, refreshToken };
};

storeCredentials();
getCredentials().then(creds => console.log(creds));
Method Description Notes
setItemAsync(key, value) Stores a key-value pair securely Overwrites existing values
getItemAsync(key) Retrieves the value for a given key Returns null if key doesn't exist
deleteItemAsync(key) Deletes a key-value pair Does not throw if key doesn't exist
clearAsync() Deletes all stored items Use with caution
Note: Values are stored encrypted and are only accessible to your app.
Warning: Do not store sensitive data like passwords in plain text or unencrypted formats.

9. Handling Storage Errors

Example: Error Handling with Expo Secure Store

import * as SecureStore from &#x27;expo-secure-store&#x27;;

async function secureStorageWithErrors() {
  try {
    await SecureStore.setItemAsync(&#x27;userToken&#x27;, &#x27;abc123xyz&#x27;);
    const token = await SecureStore.getItemAsync(&#x27;userToken&#x27;);
    console.log(&#x27;Token retrieved:&#x27;, token);
  } catch (error) {
    console.error(&#x27;Secure Store Error:&#x27;, error.message);
    // Handle specific error types
    if (error.name === &#x27;SecureStoreError&#x27;) {
      // Log or report error
      console.error(&#x27;Secure Store operation failed&#x27;);
    }
  }
}
Error Type Description Handling Recommendation
SecureStoreError Generic error thrown by SecureStore operations Log the error and provide user feedback or retry logic
SecurityError Occurs when storage is compromised or locked (e.g., device passcode removed) Clear sensitive data and prompt user to re-authenticate or reset
PermissionError Thrown when app lacks required permissions (rare in Expo) Inform user to check app permissions or reinstall
Note: On some Android devices, SecureStore may throw errors if the device is not properly secured (e.g., no lock screen). Always wrap operations in try/catch blocks.

10. Using Biometric Protection

Property Description Values
biometricAuth Enables biometric authentication for secure storage access true or false
requireAuthentication Specifies whether authentication is required before accessing stored data true or false
authenticationPrompt Custom message displayed to the user during biometric authentication string

Example: Setting up biometric protection

import * as SecureStore from 'expo-secure-store';

await SecureStore.setItemAsync(
  'userToken',
  'abc123',
  {
    biometricAuth: true,
    requireAuthentication: true,
    authenticationPrompt: 'Authenticate to access your token'
  }
);
Note: Biometric authentication is only available on devices that support it (e.g., iOS devices with Face ID or Touch ID, Android devices with fingerprint readers).

Was this article helpful?