Skip to content
CapNative

Secure Storage

Store strings in the iOS Keychain and Android Keystore with AES-256-GCM.

  • iOS, supported
  • Android, supported
  • Web, not supported
Package
@capnative/capacitor-secure-storage
npm version
8.0.1
Capacitor
8.x · MIT

API checked against the repository README, TypeScript definitions, and npm on October 25, 2026.The README marks this major as maintained.

Install

Peer dependency: @capacitor/core >= 8.0.0

bash
npm install @capnative/capacitor-secure-storage
npx cap sync

Usage

typescript
import { SecureStorage } from '@capnative/capacitor-secure-storage';

await SecureStorage.set({
  key: 'access_token',
  value: 'my-secret-token',
});

const { value } = await SecureStorage.get({
  key: 'access_token',
});

Platform setup

The plugin stores strings only. Keys must be non-empty and at most 256 UTF-8 bytes. clear() removes values this plugin stored and does not touch other Keychain or Keystore items.

The README does not list Info.plist keys or Android permissions. The Android manifest in the repository is empty.

iOS

Values go in the iOS Keychain. Minimum version is iOS 15.

TODO: the README does not document the Keychain accessibility attribute or access group.

Android

Values are encrypted with AES-256-GCM and the key is held in the Android Keystore. Minimum version is API 24.

Web

There is no web implementation. The web class rejects every method with UNAVAILABLE instead of writing to localStorage. The source comment calls that fallback a security problem, so it is intentionally absent.

API

Method signatures match SecureStorage in the plugin repository. Import it from @capnative/capacitor-secure-storage.

set()

Stores a string value securely. If the key already exists, its value is overwritten. Empty string values are allowed.

Signature
set(options: { key: string; value: string }) => Promise<void>
ParamTypeDescription
options.keystringNon-empty key, at most 256 UTF-8 bytes.
options.valuestringString value to store. Empty strings are allowed.

get()

Retrieves a stored value. The value is null if the key does not exist.

Signature
get(options: { key: string }) => Promise<{ value: string | null }>
ParamTypeDescription
options.keystringKey to read.

Returns Promise<{ value: string | null }>

has()

Checks whether a key exists.

Signature
has(options: { key: string }) => Promise<{ value: boolean }>
ParamTypeDescription
options.keystringKey to check.

Returns Promise<{ value: boolean }>

remove()

Deletes a key. Succeeds even if the key does not exist.

Signature
remove(options: { key: string }) => Promise<void>
ParamTypeDescription
options.keystringKey to delete.

clear()

Deletes every value stored by this plugin and nothing else.

Signature
clear() => Promise<void>

Type aliases

  • SecureStorageErrorCode

    'INVALID_KEY' | 'INVALID_VALUE' | 'STORAGE_ERROR' | 'KEYCHAIN_ERROR' | 'KEYSTORE_ERROR' | 'ENCRYPTION_ERROR' | 'DECRYPTION_ERROR' | 'UNAVAILABLE'

    Reported as error.code. MAX_KEY_LENGTH in the definitions file is 256 UTF-8 bytes.

Errors

Rejected promises expose a stable code. Match on that code rather than the message text.

CodePlatformMeaning
INVALID_KEYiOS, AndroidThe key is empty or exceeds 256 UTF-8 bytes.
INVALID_VALUEiOS, AndroidThe value passed to set is not a string.
STORAGE_ERRORiOS, AndroidAn unexpected storage operation failed, or Android could not persist a change.
KEYCHAIN_ERRORiOSThe iOS Keychain operation failed.
KEYSTORE_ERRORAndroidThe Android Keystore could not be accessed or updated.
ENCRYPTION_ERRORAndroidThe value could not be encrypted.
DECRYPTION_ERRORAndroidThe stored value is corrupt, tampered with, or cannot be decrypted with the available Keystore key.
UNAVAILABLEWebSecure storage is not supported on the web. There is no insecure storage fallback.