---
title: Capacitor Vault Plugin for Android & iOS
description: Capacitor Vault plugin for biometric-protected, lockable secure storage on Android and iOS. A near drop-in Ionic Identity Vault alternative.
tags:
  - Insiders
  - Android
  - iOS
search:
  boost: 2
faq: true
status: new
github_repo: capawesome-team/capacitor-plugins
---

# Capacitor Vault Plugin

Capacitor plugin to securely store key/value pairs in lockable, biometric-protected vaults.

<div class="capawesome-z29o10a">
  <a href="https://capawesome.io/" target="_blank">
    <img alt="Deliver Live Updates to your Capacitor app with Capawesome Cloud" src="https://capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.png?t=1" />
  </a>
</div>

## Features

The Capacitor Vault plugin is one of the most complete secure storage solutions for Capacitor apps. Here are some of the key features:

- 🖥️ **Cross-platform**: Native secure vault on Android and iOS, with a `localStorage`-backed web implementation for development.
- 🔒 **Secure**: Hardware-backed encryption via the [Android Keystore](https://developer.android.com/privacy-and-security/keystore) and [iOS Keychain](https://developer.apple.com/documentation/security/keychain-services).
- 🔓 **Lockable**: Unlock once with a biometric or passcode prompt, then perform many read/write operations until `lock()` is called.
- ⏱️ **Auto-lock**: Automatically lock the vault after the app has been backgrounded for a configurable duration.
- 🗂️ **Multi-vault**: Create multiple independent vaults with different configurations on the same device.
- 🔐 **Multiple vault types**: Authenticate with biometrics, the device passcode, or either.
- ♻️ **Key invalidation**: Optionally invalidate the encryption key when the device's biometric set changes.
- 🚨 **Error Codes**: Provides detailed error codes for better error handling.
- ✨ **Customizable**: Customize the authentication prompt with a title, subtitle, and button text.
- 🤝 **Compatibility**: Compatible with the [Biometrics](https://capawesome.io/docs/sdks/capacitor/biometrics/) and [Secure Preferences](https://capawesome.io/docs/sdks/capacitor/secure-preferences/) plugins.
- 📦 **CocoaPods & SPM**: Supports CocoaPods and Swift Package Manager for iOS.
- 🔁 **Up-to-date**: Always supports the latest Capacitor version.
- ⭐️ **Support**: Priority support from the Capawesome Team.
- ✨ **Handcrafted**: Built from the ground up with care and expertise, not forked or AI-generated.

Missing a feature? Just [open an issue](https://github.com/capawesome-team/capacitor-plugins/issues) and we'll take a look!

## Use Cases

The Vault plugin is typically used whenever access to stored data should require an explicit user authentication, for example:

- **App lock**: Protect sensitive parts of your app behind a biometric or device-passcode prompt.
- **Password managers**: Store user credentials that are only readable after the user unlocks the vault.
- **Authenticator apps**: Keep TOTP secrets locked until the user authenticates.
- **Master key storage**: Protect the master password or encryption key that guards other data, such as an encrypted database.
- **Session protection**: Automatically lock stored data when the app has been backgrounded for a configurable duration.

## Compatibility

| Plugin Version | Capacitor Version | Status         |
| -------------- | ----------------- | -------------- |
| 0.2.x          | >=8.x.x           | Active support |
| 0.1.x          | >=8.x.x           | Deprecated     |

## Demo

A working example can be found [here](https://github.com/capawesome-team/capacitor-vault-demo).

| Android                                                                                                                                                | iOS                                                                                                                                                |
| ------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| <video src="https://capawesome.io/docs/assets/videos/posts/announcing-the-capacitor-vault-plugin/vault-demo-android.mp4" width="324" controls></video> | <video src="https://capawesome.io/docs/assets/videos/posts/announcing-the-capacitor-vault-plugin/vault-demo-ios.mp4" width="266" controls></video> |

## Guides

- [Announcing the Capacitor Vault Plugin](https://capawesome.io/blog/announcing-the-capacitor-vault-plugin/)
- [Alternatives to Ionic Enterprise Plugins](https://capawesome.io/blog/alternatives-to-ionic-enterprise-plugins/)
- [Alternative to the Ionic Identity Vault Plugin](https://capawesome.io/blog/alternative-to-ionic-identity-vault-plugin/)

## Videos

- [How to Secure Sensitive Data Using Capacitor Vault Plugin](https://youtu.be/wCNMqVBnQqs?si=mePC0ADiRHy_rFQz)

## Installation

This plugin is only available to [Capawesome Insiders](https://capawesome.io/insiders/).
First, make sure you have the Capawesome npm registry set up.
You can do this by running the following commands:

```
npm config set @capawesome-team:registry https://npm.registry.capawesome.io
npm config set //npm.registry.capawesome.io/:_authToken <YOUR_LICENSE_KEY>
```

**Attention**: Replace `<YOUR_LICENSE_KEY>` with the license key you received from Polar. If you don't have a license key yet, you can get one by becoming a [Capawesome Insider](https://capawesome.io/insiders/).

Next, you can use our **AI-Assisted Setup** to install the plugin.
Add the [Capawesome Skills](https://github.com/capawesome-team/skills) to your AI tool using the following command:

```bash
npx skills add capawesome-team/skills --skill capacitor-plugins
```

Then use the following prompt:

```
Use the `capacitor-plugins` skill from `capawesome-team/skills` to install the `@capawesome-team/capacitor-vault` plugin in my project.
```

If you prefer **Manual Setup**, install the plugin by running the following commands and follow the platform-specific instructions below:

```bash
npm install @capawesome-team/capacitor-vault
npx cap sync
```

### Android

#### Minimum Android version

The `DEVICE_PASSCODE` and `BIOMETRIC_OR_DEVICE_PASSCODE` vault types require Android API 30 (Android 11) or higher. On lower versions, `initialize(...)` will reject with the `AUTHENTICATOR_UNAVAILABLE` error code. The `BIOMETRIC` vault type is supported on all supported Android versions.

#### Proguard

If you are using Proguard, you need to add the following rules to your `proguard-rules.pro` file:

```
-keep class io.capawesome.capacitorjs.plugins.** { *; }
```

#### Variables

If needed, you can define the following project variables in your app's `variables.gradle` file to change the default version of the dependencies:

- `$androidxBiometricVersion` version of `androidx.biometric:biometric` (default: `1.1.0`)
- `$androidxLifecycleProcessVersion` version of `androidx.lifecycle:lifecycle-process` (default: `2.9.4`)

This can be useful if you encounter dependency conflicts with other plugins in your project.

### iOS

#### Privacy Descriptions

Add the `NSFaceIDUsageDescription` key to the `ios/App/App/Info.plist` file, which tells the user why your app needs access to Face ID:

```xml
<key>NSFaceIDUsageDescription</key>
<string>This app uses Face ID to unlock your data.</string>
```

### Web

**Attention**: The web implementation uses `localStorage` to make cross-platform development easier. It is intended for development and testing purposes only and should NOT be used in production.

## Configuration

No configuration required for this plugin.

## Usage

The following examples show how to initialize a vault, check whether one exists, unlock and lock it, store and retrieve values, clear or destroy it, and listen for lock and unlock events.

### Initialize the vault

Initialize the vault with the desired configuration once per session before calling any other method. The `lockAfterBackgrounded` option automatically locks the vault after the app has been backgrounded for the given duration in milliseconds:

```typescript
import { Vault, VaultType, ErrorCode } from '@capawesome-team/capacitor-vault';

const options = {
  type: VaultType.Biometric,
  title: 'Unlock vault',
  cancelButtonText: 'Cancel',
  iosFallbackButtonText: 'Use Passcode',
  lockAfterBackgrounded: 30000,
};

// Call once per session before any other method.
const initialize = async () => {
  try {
    await Vault.initialize(options);
  } catch (error) {
    if (error.code === ErrorCode.AuthenticatorUnavailable) {
      // No passcode or biometrics set up.
    } else if (error.code === ErrorCode.KeyInvalidated) {
      // All values are lost; start over.
      await Vault.destroy();
      await Vault.initialize(options);
    } else {
      throw error;
    }
  }
};
```

### Check whether a vault exists

Check whether a vault was created in a previous session, for example to decide between a fresh setup and an unlock flow:

```typescript
import { Vault } from '@capawesome-team/capacitor-vault';

// Check whether a vault was created in a previous session.
const exists = async () => {
  const { exists } = await Vault.exists();
  return exists;
};
```

### Unlock and lock the vault

Unlocking prompts the user for biometric authentication or the device credential, depending on the vault's type. Once unlocked, you can perform many read and write operations until the vault is locked again:

```typescript
import { Vault, ErrorCode } from '@capawesome-team/capacitor-vault';

// Prompt the user for biometric authentication.
const unlock = async () => {
  try {
    await Vault.unlock();
  } catch (error) {
    if (error.code === ErrorCode.UnlockCanceled) {
      console.log('The user canceled the authentication prompt.');
    } else if (error.code === ErrorCode.KeyInvalidated) {
      // All values are lost; start over.
      await Vault.destroy();
      await initialize(); // See "Initialize the vault".
    } else {
      throw error;
    }
  }
};

// Check whether the vault is currently locked.
const isLocked = async () => {
  const { isLocked } = await Vault.isLocked();
  return isLocked;
};

// Lock the vault manually.
const lock = async () => {
  await Vault.lock();
};
```

### Store and retrieve values

Store, retrieve, and remove key/value pairs. The vault must be unlocked before calling these methods:

```typescript
import { Vault, ErrorCode } from '@capawesome-team/capacitor-vault';

// Store a value.
const setValue = async () => {
  await Vault.setValue({ key: 'token', value: 'abc123' });
};

// Retrieve a value.
const getValue = async () => {
  try {
    const { value } = await Vault.getValue({ key: 'token' });
    return value;
  } catch (error) {
    if (error.code === ErrorCode.VaultLocked) {
      // Unlock the vault first.
    } else if (error.code === ErrorCode.DecryptionFailed) {
      // The value is unreadable; remove it.
      await Vault.removeValue({ key: 'token' });
      return null;
    }
    throw error;
  }
};

// Remove a single value.
const removeValue = async () => {
  await Vault.removeValue({ key: 'token' });
};

// List all keys currently stored in the vault.
const getKeys = async () => {
  const { keys } = await Vault.getKeys();
  return keys;
};
```

### Clear or destroy the vault

Remove all values while preserving the vault's configuration, or destroy the vault entirely so that it must be reinitialized before use:

```typescript
import { Vault } from '@capawesome-team/capacitor-vault';

// Remove all values without destroying the vault.
const clear = async () => {
  await Vault.clear();
};

// Permanently destroy the vault.
const destroy = async () => {
  await Vault.destroy();
};
```

### Listen for lock and unlock events

React to the vault being locked or unlocked, for example to navigate to a lock screen when the vault locks:

```typescript
import { Vault } from '@capawesome-team/capacitor-vault';

// React to lock and unlock events.
const addListeners = async () => {
  await Vault.addListener('lock', ({ vaultId, trigger }) => {
    console.log(`Vault ${vaultId} locked (trigger: ${trigger}).`);
  });
  await Vault.addListener('unlock', ({ vaultId }) => {
    console.log(`Vault ${vaultId} unlocked.`);
  });
};
```

## API

<docgen-index>

* [`clear(...)`](#clear)
* [`destroy(...)`](#destroy)
* [`exists(...)`](#exists)
* [`exportData(...)`](#exportdata)
* [`getKeys(...)`](#getkeys)
* [`getValue(...)`](#getvalue)
* [`importData(...)`](#importdata)
* [`initialize(...)`](#initialize)
* [`isEmpty(...)`](#isempty)
* [`isLocked(...)`](#islocked)
* [`lock(...)`](#lock)
* [`removeValue(...)`](#removevalue)
* [`setValue(...)`](#setvalue)
* [`unlock(...)`](#unlock)
* [`addListener('lock', ...)`](#addlistenerlock-)
* [`addListener('unlock', ...)`](#addlistenerunlock-)
* [`removeAllListeners()`](#removealllisteners)
* [Interfaces](#interfaces)
* [Enums](#enums)

</docgen-index>

<docgen-api>
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->

### clear(...)

```typescript
clear(options?: ClearOptions | undefined) => Promise<void>
```

Remove all values from the vault while preserving its configuration.

The vault must be unlocked before calling this method.

| Param         | Type                                                  |
| ------------- | ----------------------------------------------------- |
| **`options`** | <code><a href="#clearoptions">ClearOptions</a></code> |

**Since:** 0.1.0

--------------------


### destroy(...)

```typescript
destroy(options?: DestroyOptions | undefined) => Promise<void>
```

Destroy the vault, removing all values and its configuration.

After calling this method, the vault must be reinitialized before use.

Everything that could be deleted is removed, even if the call rejects.

| Param         | Type                                                      |
| ------------- | --------------------------------------------------------- |
| **`options`** | <code><a href="#destroyoptions">DestroyOptions</a></code> |

**Since:** 0.1.0

--------------------


### exists(...)

```typescript
exists(options?: ExistsOptions | undefined) => Promise<ExistsResult>
```

Check whether a vault with the given identifier exists on the device.

Returns `true` as long as the vault's encryption key or any stored
values exist, even if `initialize()` has not been called in the
current session. Useful for detecting whether a fresh setup or an
unlock flow is required. If the key is gone while values are still
stored, `initialize()` rejects with `KEY_INVALIDATED`.

| Param         | Type                                                    |
| ------------- | ------------------------------------------------------- |
| **`options`** | <code><a href="#existsoptions">ExistsOptions</a></code> |

**Returns:** <code>Promise&lt;<a href="#existsresult">ExistsResult</a>&gt;</code>

**Since:** 0.1.0

--------------------


### exportData(...)

```typescript
exportData(options?: ExportDataOptions | undefined) => Promise<ExportDataResult>
```

Export all values from the vault as a key/value map.

The vault must be unlocked before calling this method. Values that
cannot be decrypted are left out of the map and reported in the
`skippedCount` property.

**Note**: Designed for small datasets such as backup/restore flows.
The entire set of values is loaded into memory and serialized across
the Capacitor bridge in a single call. Avoid using this method on
vaults with large amounts of data to prevent out-of-memory errors.

| Param         | Type                                                            |
| ------------- | --------------------------------------------------------------- |
| **`options`** | <code><a href="#exportdataoptions">ExportDataOptions</a></code> |

**Returns:** <code>Promise&lt;<a href="#exportdataresult">ExportDataResult</a>&gt;</code>

**Since:** 0.1.0

--------------------


### getKeys(...)

```typescript
getKeys(options?: GetKeysOptions | undefined) => Promise<GetKeysResult>
```

Get a list of all keys stored in the vault.

The vault must be unlocked before calling this method.

| Param         | Type                                                      |
| ------------- | --------------------------------------------------------- |
| **`options`** | <code><a href="#getkeysoptions">GetKeysOptions</a></code> |

**Returns:** <code>Promise&lt;<a href="#getkeysresult">GetKeysResult</a>&gt;</code>

**Since:** 0.1.0

--------------------


### getValue(...)

```typescript
getValue(options: GetValueOptions) => Promise<GetValueResult>
```

Get the value associated with a key.

The vault must be unlocked before calling this method.

Rejects with `DECRYPTION_FAILED` if the stored value cannot be
decrypted.

| Param         | Type                                                        |
| ------------- | ----------------------------------------------------------- |
| **`options`** | <code><a href="#getvalueoptions">GetValueOptions</a></code> |

**Returns:** <code>Promise&lt;<a href="#getvalueresult">GetValueResult</a>&gt;</code>

**Since:** 0.1.0

--------------------


### importData(...)

```typescript
importData(options: ImportDataOptions) => Promise<void>
```

Import a key/value map into the vault, replacing all existing values.

The vault must be unlocked before calling this method. Any values
previously stored in the vault are removed before the new entries are
written. On partial failure, the vault may be left in an inconsistent
state — callers that need atomicity should call `exportData()` first
and re-import on failure.

**Note**: Designed for small datasets such as backup/restore flows.
The entire set of values is loaded into memory and serialized across
the Capacitor bridge in a single call. Avoid using this method on
vaults with large amounts of data to prevent out-of-memory errors.

| Param         | Type                                                            |
| ------------- | --------------------------------------------------------------- |
| **`options`** | <code><a href="#importdataoptions">ImportDataOptions</a></code> |

**Since:** 0.1.0

--------------------


### initialize(...)

```typescript
initialize(options: InitializeOptions) => Promise<void>
```

Initialize a vault with the given configuration.

Must be called once per session before any other method.

The `type` and `invalidateOnBiometricEnrollment` options are baked
into the encryption key at vault creation and cannot be changed
afterwards; values passed for existing vaults are silently ignored.

Rejects with `KEY_INVALIDATED` if the encryption key is gone while
encrypted values are still stored. No new key is created in that case,
because it could not decrypt them.

| Param         | Type                                                            |
| ------------- | --------------------------------------------------------------- |
| **`options`** | <code><a href="#initializeoptions">InitializeOptions</a></code> |

**Since:** 0.1.0

--------------------


### isEmpty(...)

```typescript
isEmpty(options?: IsEmptyOptions | undefined) => Promise<IsEmptyResult>
```

Check whether the vault contains no values.

| Param         | Type                                                      |
| ------------- | --------------------------------------------------------- |
| **`options`** | <code><a href="#isemptyoptions">IsEmptyOptions</a></code> |

**Returns:** <code>Promise&lt;<a href="#isemptyresult">IsEmptyResult</a>&gt;</code>

**Since:** 0.1.0

--------------------


### isLocked(...)

```typescript
isLocked(options?: IsLockedOptions | undefined) => Promise<IsLockedResult>
```

Check whether the vault is currently locked.

Rejects with `VAULT_NOT_FOUND` if the vault has not been initialized
in the current session.

| Param         | Type                                                        |
| ------------- | ----------------------------------------------------------- |
| **`options`** | <code><a href="#islockedoptions">IsLockedOptions</a></code> |

**Returns:** <code>Promise&lt;<a href="#islockedresult">IsLockedResult</a>&gt;</code>

**Since:** 0.1.0

--------------------


### lock(...)

```typescript
lock(options?: LockOptions | undefined) => Promise<void>
```

Lock the vault.

Clears the in-memory encryption key. Stored values remain encrypted
on disk and are recoverable via `unlock()`.

| Param         | Type                                                |
| ------------- | --------------------------------------------------- |
| **`options`** | <code><a href="#lockoptions">LockOptions</a></code> |

**Since:** 0.1.0

--------------------


### removeValue(...)

```typescript
removeValue(options: RemoveValueOptions) => Promise<void>
```

Remove the value associated with a key.

The vault must be unlocked before calling this method.

| Param         | Type                                                              |
| ------------- | ----------------------------------------------------------------- |
| **`options`** | <code><a href="#removevalueoptions">RemoveValueOptions</a></code> |

**Since:** 0.1.0

--------------------


### setValue(...)

```typescript
setValue(options: SetValueOptions) => Promise<void>
```

Set the value associated with a key.

The vault must be unlocked before calling this method.

On **Web**, the value is stored unencrypted in `localStorage`.
This is for development purposes only and should NOT be used in production.

| Param         | Type                                                        |
| ------------- | ----------------------------------------------------------- |
| **`options`** | <code><a href="#setvalueoptions">SetValueOptions</a></code> |

**Since:** 0.1.0

--------------------


### unlock(...)

```typescript
unlock(options?: UnlockOptions | undefined) => Promise<void>
```

Unlock the vault.

Prompts the user for biometric authentication or device credential,
depending on the vault's `type`.

Rejects with `KEY_INVALIDATED` if the encryption key can no longer be
used, for example because the device's biometric set changed or the key
was lost while encrypted values are still stored.

| Param         | Type                                                    |
| ------------- | ------------------------------------------------------- |
| **`options`** | <code><a href="#unlockoptions">UnlockOptions</a></code> |

**Since:** 0.1.0

--------------------


### addListener('lock', ...)

```typescript
addListener(eventName: 'lock', listenerFunc: (event: LockEvent) => void) => Promise<PluginListenerHandle>
```

Add a listener for vault events.

| Param              | Type                                                                |
| ------------------ | ------------------------------------------------------------------- |
| **`eventName`**    | <code>'lock'</code>                                                 |
| **`listenerFunc`** | <code>(event: <a href="#lockevent">LockEvent</a>) =&gt; void</code> |

**Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>

**Since:** 0.1.0

--------------------


### addListener('unlock', ...)

```typescript
addListener(eventName: 'unlock', listenerFunc: (event: UnlockEvent) => void) => Promise<PluginListenerHandle>
```

Add a listener for vault events.

| Param              | Type                                                                    |
| ------------------ | ----------------------------------------------------------------------- |
| **`eventName`**    | <code>'unlock'</code>                                                   |
| **`listenerFunc`** | <code>(event: <a href="#unlockevent">UnlockEvent</a>) =&gt; void</code> |

**Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>

**Since:** 0.1.0

--------------------


### removeAllListeners()

```typescript
removeAllListeners() => Promise<void>
```

Remove all listeners registered for this plugin.

**Since:** 0.1.0

--------------------


### Interfaces


#### ClearOptions

| Prop          | Type                | Description                  | Default                | Since |
| ------------- | ------------------- | ---------------------------- | ---------------------- | ----- |
| **`vaultId`** | <code>string</code> | The identifier of the vault. | <code>'default'</code> | 0.1.0 |


#### DestroyOptions

| Prop          | Type                | Description                  | Default                | Since |
| ------------- | ------------------- | ---------------------------- | ---------------------- | ----- |
| **`vaultId`** | <code>string</code> | The identifier of the vault. | <code>'default'</code> | 0.1.0 |


#### ExistsResult

| Prop         | Type                 | Description                                    | Since |
| ------------ | -------------------- | ---------------------------------------------- | ----- |
| **`exists`** | <code>boolean</code> | Whether or not the vault has been initialized. | 0.1.0 |


#### ExistsOptions

| Prop          | Type                | Description                  | Default                | Since |
| ------------- | ------------------- | ---------------------------- | ---------------------- | ----- |
| **`vaultId`** | <code>string</code> | The identifier of the vault. | <code>'default'</code> | 0.1.0 |


#### ExportDataResult

| Prop               | Type                                    | Description                                                                          | Since |
| ------------------ | --------------------------------------- | ------------------------------------------------------------------------------------ | ----- |
| **`data`**         | <code>{ [key: string]: string; }</code> | The exported key/value map.                                                          | 0.1.0 |
| **`skippedCount`** | <code>number</code>                     | The number of stored values that could not be decrypted and were therefore left out. | 0.2.0 |


#### ExportDataOptions

| Prop          | Type                | Description                  | Default                | Since |
| ------------- | ------------------- | ---------------------------- | ---------------------- | ----- |
| **`vaultId`** | <code>string</code> | The identifier of the vault. | <code>'default'</code> | 0.1.0 |


#### GetKeysResult

| Prop       | Type                  | Description                             | Since |
| ---------- | --------------------- | --------------------------------------- | ----- |
| **`keys`** | <code>string[]</code> | The keys currently stored in the vault. | 0.1.0 |


#### GetKeysOptions

| Prop          | Type                | Description                  | Default                | Since |
| ------------- | ------------------- | ---------------------------- | ---------------------- | ----- |
| **`vaultId`** | <code>string</code> | The identifier of the vault. | <code>'default'</code> | 0.1.0 |


#### GetValueResult

| Prop        | Type                        | Description                                                            | Since |
| ----------- | --------------------------- | ---------------------------------------------------------------------- | ----- |
| **`value`** | <code>string \| null</code> | The retrieved value, or `null` if no value is associated with the key. | 0.1.0 |


#### GetValueOptions

| Prop          | Type                | Description                               | Default                | Since |
| ------------- | ------------------- | ----------------------------------------- | ---------------------- | ----- |
| **`key`**     | <code>string</code> | The key associated with the stored value. |                        | 0.1.0 |
| **`vaultId`** | <code>string</code> | The identifier of the vault.              | <code>'default'</code> | 0.1.0 |


#### ImportDataOptions

| Prop          | Type                                    | Description                                                                            | Default                | Since |
| ------------- | --------------------------------------- | -------------------------------------------------------------------------------------- | ---------------------- | ----- |
| **`data`**    | <code>{ [key: string]: string; }</code> | The key/value map to import into the vault. Replaces all existing values in the vault. |                        | 0.1.0 |
| **`vaultId`** | <code>string</code>                     | The identifier of the vault.                                                           | <code>'default'</code> | 0.1.0 |


#### InitializeOptions

| Prop                                  | Type                                            | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | Default                | Since |
| ------------------------------------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | ----- |
| **`cancelButtonText`**                | <code>string</code>                             | The text displayed on the cancel button of the authentication prompt. Only available on Android and iOS.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |                        | 0.1.0 |
| **`invalidateOnBiometricEnrollment`** | <code>boolean</code>                            | Whether the encryption key should be invalidated when the device's biometric set changes (e.g., a new fingerprint or face is enrolled). If `true` and the biometric set changes, the next `unlock()` call rejects with `KEY_INVALIDATED`. The app must call `destroy()` and reinitialize. Per-platform behavior: - **Android**: when biometric is involved, invalidates the entire encryption key. For `BIOMETRIC_OR_DEVICE_PASSCODE` vaults, the device passcode path is also rendered unusable. - **iOS**: when biometric is involved, invalidates the biometric branch only. For `BIOMETRIC_OR_DEVICE_PASSCODE` vaults, the user can still unlock with the device passcode. Only applies to vault types that use biometric authentication. This option only controls whether adding or changing biometric enrollments invalidates the key. On **iOS**, resetting Face ID or Touch ID invalidates a `BIOMETRIC` vault regardless of this option, and the key does not come back after re-enrollment; `unlock(...)` and `initialize(...)` then reject with `KEY_INVALIDATED`. On **Android**, the key survives the removal of all biometrics and `unlock(...)` rejects with `AUTHENTICATOR_UNAVAILABLE` until a biometric is enrolled again. **Note**: This option is baked into the encryption key at vault creation time. The value passed when reinitializing an existing vault is silently ignored. | <code>false</code>     | 0.1.0 |
| **`iosFallbackButtonText`**           | <code>string</code>                             | The text displayed on the fallback button of the authentication prompt. Only available on iOS.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |                        | 0.1.0 |
| **`lockAfterBackgrounded`**           | <code>number</code>                             | The duration in milliseconds the app must be backgrounded before the vault is automatically locked. If omitted, the vault is never automatically locked. The duration is measured with a monotonic clock, so changing the device time does not affect it. It is evaluated when the app returns to the foreground.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |                        | 0.1.0 |
| **`subtitle`**                        | <code>string</code>                             | The subtitle of the authentication prompt.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |                        | 0.1.0 |
| **`title`**                           | <code>string</code>                             | The title of the authentication prompt.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |                        | 0.1.0 |
| **`type`**                            | <code><a href="#vaulttype">VaultType</a></code> | The type of the vault.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |                        | 0.1.0 |
| **`vaultId`**                         | <code>string</code>                             | The identifier of the vault.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | <code>'default'</code> | 0.1.0 |


#### IsEmptyResult

| Prop          | Type                 | Description                           | Since |
| ------------- | -------------------- | ------------------------------------- | ----- |
| **`isEmpty`** | <code>boolean</code> | Whether the vault contains no values. | 0.1.0 |


#### IsEmptyOptions

| Prop          | Type                | Description                  | Default                | Since |
| ------------- | ------------------- | ---------------------------- | ---------------------- | ----- |
| **`vaultId`** | <code>string</code> | The identifier of the vault. | <code>'default'</code> | 0.1.0 |


#### IsLockedResult

| Prop           | Type                 | Description                            | Since |
| -------------- | -------------------- | -------------------------------------- | ----- |
| **`isLocked`** | <code>boolean</code> | Whether the vault is currently locked. | 0.1.0 |


#### IsLockedOptions

| Prop          | Type                | Description                  | Default                | Since |
| ------------- | ------------------- | ---------------------------- | ---------------------- | ----- |
| **`vaultId`** | <code>string</code> | The identifier of the vault. | <code>'default'</code> | 0.1.0 |


#### LockOptions

| Prop          | Type                | Description                  | Default                | Since |
| ------------- | ------------------- | ---------------------------- | ---------------------- | ----- |
| **`vaultId`** | <code>string</code> | The identifier of the vault. | <code>'default'</code> | 0.1.0 |


#### RemoveValueOptions

| Prop          | Type                | Description                               | Default                | Since |
| ------------- | ------------------- | ----------------------------------------- | ---------------------- | ----- |
| **`key`**     | <code>string</code> | The key associated with the stored value. |                        | 0.1.0 |
| **`vaultId`** | <code>string</code> | The identifier of the vault.              | <code>'default'</code> | 0.1.0 |


#### SetValueOptions

| Prop          | Type                | Description                               | Default                | Since |
| ------------- | ------------------- | ----------------------------------------- | ---------------------- | ----- |
| **`key`**     | <code>string</code> | The key associated with the stored value. |                        | 0.1.0 |
| **`value`**   | <code>string</code> | The value to store.                       |                        | 0.1.0 |
| **`vaultId`** | <code>string</code> | The identifier of the vault.              | <code>'default'</code> | 0.1.0 |


#### UnlockOptions

| Prop          | Type                | Description                  | Default                | Since |
| ------------- | ------------------- | ---------------------------- | ---------------------- | ----- |
| **`vaultId`** | <code>string</code> | The identifier of the vault. | <code>'default'</code> | 0.1.0 |


#### PluginListenerHandle

| Prop         | Type                                      |
| ------------ | ----------------------------------------- |
| **`remove`** | <code>() =&gt; Promise&lt;void&gt;</code> |


#### LockEvent

| Prop          | Type                                                | Description                              | Since |
| ------------- | --------------------------------------------------- | ---------------------------------------- | ----- |
| **`trigger`** | <code><a href="#locktrigger">LockTrigger</a></code> | What caused the vault to lock.           | 0.1.0 |
| **`vaultId`** | <code>string</code>                                 | The identifier of the vault that locked. | 0.1.0 |


#### UnlockEvent

| Prop          | Type                | Description                                | Since |
| ------------- | ------------------- | ------------------------------------------ | ----- |
| **`vaultId`** | <code>string</code> | The identifier of the vault that unlocked. | 0.1.0 |


### Enums


#### VaultType

| Members                         | Value                                       | Description                                                                                                                                                                                                             | Since |
| ------------------------------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **`Biometric`**                 | <code>'BIOMETRIC'</code>                    | The vault is unlocked with the device's biometric authentication. Requires a Class 3 (Strong) biometric sensor on Android. Initialization rejects with `AUTHENTICATOR_UNAVAILABLE` if no Strong biometric is available. | 0.1.0 |
| **`BiometricOrDevicePasscode`** | <code>'BIOMETRIC_OR_DEVICE_PASSCODE'</code> | The vault is unlocked with either the device's biometric authentication or the device's credential (PIN, pattern, or password).                                                                                         | 0.1.0 |
| **`DevicePasscode`**            | <code>'DEVICE_PASSCODE'</code>              | The vault is unlocked with the device's credential (PIN, pattern, or password).                                                                                                                                         | 0.1.0 |


#### LockTrigger

| Members       | Value                  | Description                                                                                | Since |
| ------------- | ---------------------- | ------------------------------------------------------------------------------------------ | ----- |
| **`Manual`**  | <code>'MANUAL'</code>  | The vault was locked by an explicit call to `lock()`.                                      | 0.1.0 |
| **`Timeout`** | <code>'TIMEOUT'</code> | The vault was locked because the app was backgrounded longer than `lockAfterBackgrounded`. | 0.1.0 |

</docgen-api>

## FAQ

### Where is the data stored?

On Android, the encryption key is stored in the [Android Keystore](https://developer.android.com/privacy-and-security/keystore) and the encrypted values are stored in two `SharedPreferences` files per vault. On iOS, both the encryption key and the encrypted values are stored as separate [Keychain](https://developer.apple.com/documentation/security/keychain-services) items.

The encryption key is never included in cloud backups on either platform. On Android, the encrypted values in `SharedPreferences` are part of [Android Auto Backup](https://developer.android.com/identity/data/autobackup) by default, but the backed-up ciphertext is unusable on another device without the Keystore key; to exclude the preference files (`capawesome_capacitor_vault_key_<vaultId>.xml` and `capawesome_capacitor_vault_data_<vaultId>.xml`) from backup, see the [Android documentation](https://developer.android.com/identity/data/autobackup#IncludingFiles). On iOS, the Keychain items use the `*ThisDeviceOnly` accessibility classes, so they are never synced to iCloud Keychain or included in device backups.

### Is the data removed when the app is uninstalled?

On Android, yes: both `SharedPreferences` files and the Keystore key of every vault are deleted. On iOS, no: Keychain items survive an uninstall and are available again after a reinstall with the same bundle identifier. Apple does not document or guarantee this behavior.

To start with empty vaults after a reinstall, keep a marker in `UserDefaults`, which is removed with the app, and call `destroy()` for every vault your app uses on the first launch when it is missing:

```typescript
import { Preferences } from '@capacitor/preferences';
import { Vault } from '@capawesome-team/capacitor-vault';

const destroyAfterReinstall = async () => {
  const { value } = await Preferences.get({ key: 'installed' });
  if (value === null) {
    for (const vaultId of ['default', 'settings']) {
      await Vault.destroy({ vaultId });
    }
    await Preferences.set({ key: 'installed', value: 'true' });
  }
};
```

### When should I use Vault instead of Secure Preferences or SQLite?

All three plugins protect data on the device, but they target different problems:

- **[Secure Preferences](https://capawesome.io/docs/sdks/capacitor/secure-preferences/)** is a transparent key/value store. Values are encrypted at rest using the Android Keystore and iOS Keychain, but the app can read them at any time without prompting the user. Reach for it when you need to keep small bits of sensitive data around that the app itself accesses in the background — typical examples are OAuth refresh tokens, server-issued API keys, or preference flags that contain personal information.

- **[SQLite](https://capawesome.io/docs/sdks/capacitor/sqlite/)** is a full relational database with optional SQLCipher encryption. Use it when the shape of your data calls for queries, joins, indexes, or large record sets — for example, an offline-first app that syncs structured records, or anything you would otherwise model with a server-side database.

- **Vault** (this plugin) is a key/value store with an active lock state and biometric or device-passcode gating. The user has to unlock it before any read or write, and it locks again on demand or after a configurable background timeout. Reach for it when access to the data should require an explicit user action — a password manager's entries, an authenticator app's TOTP secrets, or the credentials sitting behind an "app lock" screen.

A quick decision tree:

- Need queries, relations, or large datasets? → **SQLite**.
- Need encrypted key/value storage the app can read freely in the background? → **Secure Preferences**.
- Need encrypted key/value storage the user must actively unlock with biometrics or a passcode? → **Vault**.

The three plugins are designed to coexist. A real-world app might use Secure Preferences for app-managed tokens, SQLite for synced records, and Vault for the master password that protects everything else.

### Is this plugin an alternative to Ionic Identity Vault?

Yes. This plugin was built as an alternative to [Ionic Identity Vault](https://ionic.io/products/identity-vault) and offers a similar feature set:

- Hardware-backed encryption using the Android Keystore and iOS Keychain
- Biometric, device passcode, or combined authentication
- Lockable session model with manual lock and auto-lock on background
- Multiple independent vaults per device
- Key invalidation when the device's biometric set changes

### How do I migrate from Ionic Identity Vault?

For an AI-assisted migration of your code, add the [Capawesome Skills](https://github.com/capawesome-team/skills) to your AI tool and use the `ionic-enterprise-sdk-migration` skill to migrate your project to `@capawesome-team/capacitor-vault`. Alternatively, you can follow the manual instructions and the complete runtime migration example in the blog post [Alternative to the Ionic Identity Vault plugin](https://capawesome.io/blog/alternative-to-ionic-identity-vault-plugin/).

The stored data needs to be migrated at runtime while **both** plugins are still installed: Identity Vault exposes `exportVault()`, which returns a plain key/value map after the user unlocks the vault, and that map has the exact shape expected by this plugin's [`importData(...)`](#importdata) method, so the two can be bridged directly. Note that the user has to authenticate once during the migration to unlock the old vault — this is unavoidable, since the data is protected by the device's biometric or passcode authentication by design. Once all users have migrated (for example, after a release cycle in which everyone has opened the app at least once), you can remove the Identity Vault dependency in a follow-up release.

### What happens when the user enrolls a new fingerprint or face?

If the vault was created with the `invalidateOnBiometricEnrollment` option set to `true`, the encryption key is invalidated when the device's biometric set changes, and the next `unlock()` call rejects with the `KEY_INVALIDATED` error code. The app must then call `destroy()` and reinitialize the vault. On Android, the entire encryption key is invalidated, while on iOS only the biometric branch is invalidated, so users of `BIOMETRIC_OR_DEVICE_PASSCODE` vaults can still unlock with the device passcode. Note that this option is baked into the encryption key at vault creation time and cannot be changed afterwards.

The `invalidateOnBiometricEnrollment` option only controls whether adding or changing biometric enrollments invalidates the key. Resetting the biometric enrollment entirely is a separate case: on iOS, removing all enrolled biometrics invalidates a `BIOMETRIC` vault regardless of this option, and the key does not come back after re-enrollment, so `unlock()` and `initialize()` reject with the `KEY_INVALIDATED` error code. On Android, the key survives the removal of all biometrics and `unlock()` rejects with `AUTHENTICATOR_UNAVAILABLE` until a biometric is enrolled again.

The same error code is reported whenever the encryption key is gone while encrypted values are still stored, for example after the device passcode was removed on iOS. `initialize()` and `unlock()` reject in that case instead of creating a new key, because a new key could not decrypt the existing values. The recovery is always the same: call `destroy()` and initialize the vault again.

On iOS, each vault consists of two kinds of Keychain items: the key item holding the encryption key and one data item per stored value.

### Can I use this plugin on the Web?

The web implementation stores values unencrypted in `localStorage` to make cross-platform development easier. It is intended for development and testing purposes only and should NOT be used in production. The secure, hardware-backed vault is only available on Android and iOS.

### Can I use this plugin with Ionic, React, Vue or Angular?

Yes, the plugin is framework-agnostic. It works in any Capacitor app regardless of the web framework, including Ionic with Angular, React, or Vue, as well as plain JavaScript projects.

## Related Plugins

- [Biometrics](https://capawesome.io/docs/sdks/capacitor/biometrics/): Request biometric authentication, such as face recognition or fingerprint recognition.
- [Secure Preferences](https://capawesome.io/docs/sdks/capacitor/secure-preferences/): Securely store key/value pairs such as passwords, tokens or other sensitive information.
- [SQLite](https://capawesome.io/docs/sdks/capacitor/sqlite/): Access SQLite databases with support for encryption, transactions, and schema migrations.

## Next steps

Here are a few resources to help you continue:

- Read [Alternative to the Ionic Identity Vault plugin](https://capawesome.io/blog/alternative-to-ionic-identity-vault-plugin/) if you are migrating from Ionic Identity Vault.
- Need simple secure key/value storage without vault locking? Check out the [Capacitor Secure Preferences plugin](https://capawesome.io/docs/sdks/capacitor/secure-preferences/).
- Check out [Getting Started with Insiders](https://capawesome.io/docs/insiders/getting-started/) to learn how to install the plugin.

## Newsletter

Stay up to date with the latest news and updates about the Capawesome, Capacitor, and Ionic ecosystem by subscribing to our [Capawesome Newsletter](https://capawesome.io/newsletter/).

## Changelog

See [CHANGELOG.md](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/vault/CHANGELOG.md).

## Breaking Changes

See [BREAKING.md](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/vault/BREAKING.md).

## License

See [LICENSE](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/vault/LICENSE).
