or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

index.mddocs/

Expo SecureStore

Expo SecureStore provides a way to encrypt and securely store key-value pairs locally on the device. It uses platform-native keychain services (iOS Keychain Services and Android Keystore) to ensure data is encrypted and protected with hardware-backed security features including biometric authentication support.

Package Information

  • Package Name: expo-secure-store
  • Package Type: npm
  • Language: TypeScript
  • Installation: npx expo install expo-secure-store
  • Peer Dependencies: expo

Core Imports

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

For individual imports:

import { 
  setItemAsync, 
  getItemAsync, 
  deleteItemAsync, 
  isAvailableAsync,
  WHEN_UNLOCKED,
  type SecureStoreOptions 
} from 'expo-secure-store';

Basic Usage

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

// Store a value
await SecureStore.setItemAsync('userToken', 'abc123');

// Retrieve a value
const token = await SecureStore.getItemAsync('userToken');
console.log(token); // 'abc123'

// Delete a value
await SecureStore.deleteItemAsync('userToken');

// Check if SecureStore is available
const isAvailable = await SecureStore.isAvailableAsync();

Advanced Usage with Authentication

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

// Store with biometric authentication requirement
await SecureStore.setItemAsync('sensitiveData', 'secret123', {
  requireAuthentication: true,
  authenticationPrompt: 'Please authenticate to access your data',
  keychainAccessible: SecureStore.WHEN_UNLOCKED
});

// Retrieve with authentication
const data = await SecureStore.getItemAsync('sensitiveData', {
  requireAuthentication: true,
  authenticationPrompt: 'Authenticate to view your data'
});

Capabilities

Storage Operations

Asynchronous functions for storing, retrieving, and deleting encrypted key-value pairs.

/**
 * Stores a key–value pair securely
 * @param key The key to associate with the stored value. Keys may contain alphanumeric characters, `.`, `-`, and `_`
 * @param value The value to store. Size limit is 2048 bytes
 * @param options Configuration options for the storage operation
 * @returns Promise that rejects if value cannot be stored on the device
 */
function setItemAsync(
  key: string,
  value: string,
  options?: SecureStoreOptions
): Promise<void>;

/**
 * Reads the stored value associated with the provided key
 * @param key The key that was used to store the associated value
 * @param options Configuration options for the retrieval operation
 * @returns Promise that resolves to the previously stored value, or null if no entry exists or key has been invalidated
 */
function getItemAsync(
  key: string,
  options?: SecureStoreOptions
): Promise<string | null>;

/**
 * Delete the value associated with the provided key
 * @param key The key that was used to store the associated value
 * @param options Configuration options for the deletion operation
 * @returns Promise that rejects if the value can't be deleted
 */
function deleteItemAsync(
  key: string,
  options?: SecureStoreOptions
): Promise<void>;

Synchronous Operations

Synchronous functions that block the JavaScript thread during execution.

/**
 * Stores a key–value pair synchronously
 * Note: This function blocks the JavaScript thread, so the application may not be interactive when the requireAuthentication option is set to true until the user authenticates
 * @param key The key to associate with the stored value. Keys may contain alphanumeric characters, `.`, `-`, and `_`
 * @param value The value to store. Size limit is 2048 bytes
 * @param options Configuration options for the storage operation
 */
function setItem(
  key: string,
  value: string,
  options?: SecureStoreOptions
): void;

/**
 * Synchronously reads the stored value associated with the provided key
 * Note: This function blocks the JavaScript thread, so the application may not be interactive when reading a value with requireAuthentication option set to true until the user authenticates
 * @param key The key that was used to store the associated value
 * @param options Configuration options for the retrieval operation
 * @returns Previously stored value, or null if no entry exists or key has been invalidated
 */
function getItem(
  key: string,
  options?: SecureStoreOptions
): string | null;

Availability and Authentication

Functions to check device capabilities and authentication support.

/**
 * Returns whether the SecureStore API is enabled on the current device
 * This does not check the app permissions
 * @returns Promise which fulfils with a boolean, indicating whether the SecureStore API is available on the current device. Currently, this resolves true on Android and iOS only
 */
function isAvailableAsync(): Promise<boolean>;

/**
 * Checks if the value can be saved with requireAuthentication option enabled
 * @returns true if the device supports biometric authentication and the enrolled method is sufficiently secure. Otherwise, returns false. Always returns false on tvOS
 * @platform android
 * @platform ios
 */
function canUseBiometricAuthentication(): boolean;

Configuration Options

Options interface for configuring SecureStore operations.

interface SecureStoreOptions {
  /**
   * Android: Equivalent of the public/private key pair Alias
   * iOS: The item's service, equivalent to kSecAttrService
   * If the item is set with the keychainService option, it will be required to later fetch the value
   */
  keychainService?: string;
  
  /**
   * Option responsible for enabling the usage of the user authentication methods available on the device while accessing data stored in SecureStore
   * Android: Equivalent to setUserAuthenticationRequired(true) (requires API 23)
   * iOS: Equivalent to biometryCurrentSet
   * Complete functionality is unlocked only with a freshly generated key - this would not work in tandem with the keychainService value used for the others non-authenticated operations
   * 
   * This option works slightly differently across platforms: On Android, user authentication is required for all operations.
   * On iOS, the user is prompted to authenticate only when reading or updating an existing value (not when creating a new one).
   * 
   * Warning: This option is not supported in Expo Go when biometric authentication is available due to a missing NSFaceIDUsageDescription.
   * In release builds or when using continuous native generation, make sure to use the expo-secure-store config plugin.
   */
  requireAuthentication?: boolean;
  
  /**
   * Custom message displayed to the user while requireAuthentication option is turned on
   */
  authenticationPrompt?: string;
  
  /**
   * Specifies when the stored entry is accessible, using iOS's kSecAttrAccessible property
   * @see Apple's documentation on keychain item accessibility
   * @default SecureStore.WHEN_UNLOCKED
   * @platform ios
   */
  keychainAccessible?: KeychainAccessibilityConstant;
  
  /**
   * Specifies the access group the stored entry belongs to
   * @see Apple's documentation on Sharing access to keychain items among a collection of apps
   * @platform ios
   */
  accessGroup?: string;
}

Keychain Accessibility Constants

Constants defining when stored data can be accessed on iOS.

type KeychainAccessibilityConstant = number;

/**
 * The data in the keychain item cannot be accessed after a restart until the device has been unlocked once by the user
 * This may be useful if you need to access the item when the phone is locked
 */
const AFTER_FIRST_UNLOCK: KeychainAccessibilityConstant;

/**
 * Similar to AFTER_FIRST_UNLOCK, except the entry is not migrated to a new device when restoring from a backup
 */
const AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY: KeychainAccessibilityConstant;

/**
 * The data in the keychain item can always be accessed regardless of whether the device is locked
 * This is the least secure option
 * @deprecated Use an accessibility level that provides some user protection, such as AFTER_FIRST_UNLOCK
 */
const ALWAYS: KeychainAccessibilityConstant;

/**
 * Similar to WHEN_UNLOCKED_THIS_DEVICE_ONLY, except the user must have set a passcode in order to store an entry
 * If the user removes their passcode, the entry will be deleted
 */
const WHEN_PASSCODE_SET_THIS_DEVICE_ONLY: KeychainAccessibilityConstant;

/**
 * Similar to ALWAYS, except the entry is not migrated to a new device when restoring from a backup
 * @deprecated Use an accessibility level that provides some user protection, such as AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY
 */
const ALWAYS_THIS_DEVICE_ONLY: KeychainAccessibilityConstant;

/**
 * The data in the keychain item can be accessed only while the device is unlocked by the user
 */
const WHEN_UNLOCKED: KeychainAccessibilityConstant;

/**
 * Similar to WHEN_UNLOCKED, except the entry is not migrated to a new device when restoring from a backup
 */
const WHEN_UNLOCKED_THIS_DEVICE_ONLY: KeychainAccessibilityConstant;

Platform Support

  • iOS: Full support via iOS Keychain Services
  • Android: Full support via Android Keystore (API 23+ required for biometric authentication features)
  • tvOS: Basic keychain operations supported, but biometric authentication always returns false
  • Web: Not supported (operations will fail on web platforms)

Key Limitations and Considerations

Value Size Limit

  • Maximum value size: 2048 bytes
  • Values exceeding this limit will generate a warning but may still be stored (behavior may change in future versions)

Key Requirements

  • Keys must contain only alphanumeric characters, ., -, and _
  • Keys cannot be empty strings

Authentication Behavior

  • iOS: User authentication is required only when reading or updating existing values (not when creating new ones)
  • Android: User authentication is required for all operations when requireAuthentication: true
  • Keys are automatically invalidated when biometric data changes (e.g., adding new fingerprints)

Expo Go Limitations

  • Biometric authentication is not supported in Expo Go due to missing NSFaceIDUsageDescription
  • Use development builds or production builds for full authentication functionality

Error Handling

The SecureStore API may throw errors in the following scenarios:

  • Invalid key format: Keys containing invalid characters or empty strings
  • Invalid value type: Non-string values passed to storage functions
  • Storage failures: Device-specific errors when storing, retrieving, or deleting values
  • Authentication failures: When user cancels authentication or biometric authentication fails
  • Platform limitations: When attempting to use SecureStore on unsupported platforms (web)

Security Features

  • Hardware-backed encryption: Uses iOS Keychain Services and Android Keystore for secure storage
  • Biometric authentication: Optional user authentication via Touch ID, Face ID, or fingerprint
  • Access control: Configurable accessibility levels controlling when data can be accessed
  • App group sharing: Support for sharing keychain items between related apps (iOS)
  • Device-specific storage: Options to prevent data migration during device backup/restore
  • Automatic key invalidation: Keys become inaccessible when biometric enrollment changes