@cap-kit/secure-storage
v8.1.2
Published
Capacitor v8 plugin for encrypted key-value storage: hardware-backed secure storage on Android and iOS with iCloud sync and Keychain access levels.
Readme
Overview
SecureStorage is built for applications that must persist sensitive data safely:
- Hardware-backed encrypted key/value storage (Keychain / Keystore)
- Key enumeration, batch reads, and existence checks without decryption
- iCloud Keychain sync and accessibility levels on iOS
- Master-key rotation on wipe (Android)
Documentation
- Usage guide — basic operations, batch flows, sync, and the demo app
- Configuration — static config and per-call options reference
- Platform behavior — what Android, iOS, and web actually do
- Security model — guarantees, limits, and best practices
- API notes — return shapes, availability, and error behavior
- Contributing
Install
pnpm add @cap-kit/secure-storage
# or
npm install @cap-kit/secure-storage
# or
yarn add @cap-kit/secure-storage
# then run:
npx cap syncConfiguration
Configuration options for the SecureStorage plugin.
The key MUST match the plugin's registered name (SecureStorage,
the cap-kit convention: no CapKit prefix), which Capacitor uses to
resolve static plugin config on both platforms (Android:
@CapacitorPlugin(name=...); iOS: CAPPlugin.getConfig() ->
pluginName -> jsName).
| Prop | Type | Description | Default | Since |
| ------------------------------ | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ----- |
| verboseLogging | boolean | Enables verbose native logging. | false | 8.0.0 |
| enableICloudKeychainSync | boolean | Enables iCloud Keychain synchronization for stored entries. iOS only; ignored on Android and Web. | false | 8.0.0 |
| obfuscateKeys | boolean | Base64-encodes stored key names (both tiers) on top of any prefix. Obfuscation is not encryption: it hides key names from casual inspection, nothing more. Reads transparently accept both forms, so toggling never orphans existing entries. | false | 8.0.0 |
| obfuscationPrefix | string | Prefix prepended to stored key names before optional encoding. | '' | 8.0.0 |
Examples
In capacitor.config.json:
{
"plugins": {
"SecureStorage": {
"verboseLogging": false,
"enableICloudKeychainSync": false,
"obfuscateKeys": false,
"obfuscationPrefix": ""
}
}
}In capacitor.config.ts:
/// <reference types="@cap-kit/secure-storage" />
import { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
plugins: {
SecureStorage: {
verboseLogging: false,
enableICloudKeychainSync: false,
obfuscateKeys: false,
obfuscationPrefix: '',
},
},
};
export default config;API
set(...)get(...)remove(...)has(...)keys()getMany(...)clear()configure(...)setInsecure(...)getInsecure(...)removeInsecure(...)hasInsecure(...)keysInsecure()clearInsecure()setSynchronize(...)getSynchronize()setDefaultKeychainAccess(...)getPluginVersion()- Interfaces
- Type Aliases
Public JavaScript API for the SecureStorage Capacitor plugin.
Transparent encrypted key/value storage: hardware-backed on Android (Keystore) and iOS (Keychain), with iCloud sync and Keychain access levels on iOS. No vault, no lock state, no authentication — reads are always available, exactly like the community secure-storage contract.
set(...)
set(options: SetOptions) => Promise<void>Stores a value under a key, overwriting any previous entry.
| Param | Type | Description |
| ------------- | ------------------------------------------------- | --------------------------------------------- |
| options | SetOptions | - Key, value, and optional iOS accessibility. |
Since: 8.0.0
Example
await SecureStorage.set({ key: 'theme', value: 'dark' });get(...)
get(options: KeyOptions) => Promise<GetResult>Reads the value for a key, or null when absent.
| Param | Type |
| ------------- | ------------------------------------------------- |
| options | KeyOptions |
Returns: Promise<GetResult>
Since: 8.0.0
remove(...)
remove(options: KeyOptions) => Promise<RemoveResult>Removes the entry for a key.
| Param | Type |
| ------------- | ------------------------------------------------- |
| options | KeyOptions |
Returns: Promise<RemoveResult>
Since: 8.0.0
has(...)
has(options: KeyOptions) => Promise<HasResult>Checks whether an entry exists without reading it.
| Param | Type |
| ------------- | ------------------------------------------------- |
| options | KeyOptions |
Returns: Promise<HasResult>
Since: 8.0.0
keys()
keys() => Promise<KeysResult>Lists every stored key.
Returns: Promise<KeysResult>
Since: 8.0.0
getMany(...)
getMany(options: GetManyOptions) => Promise<GetManyResult>Reads several keys in one call. Missing keys map to null.
| Param | Type |
| ------------- | --------------------------------------------------------- |
| options | GetManyOptions |
Returns: Promise<GetManyResult>
Since: 8.0.0
clear()
clear() => Promise<void>Removes every stored entry.
On Android this also rotates the Keystore keys, so previously captured ciphertext can never be decrypted again.
Since: 8.0.0
configure(...)
configure(options: ConfigureOptions) => Promise<void>Configures the insecure tier at runtime.
Only group is supported; undefined values leave the current
setting untouched. Mirrors the official Preferences contract.
| Param | Type |
| ------------- | ------------------------------------------------------------- |
| options | ConfigureOptions |
Since: 8.0.0
setInsecure(...)
setInsecure(options: SetOptions) => Promise<void>Stores a plaintext value in the insecure tier under the current group.
For non-sensitive data only (UI preferences, flags). Values are NOT encrypted; keys follow the same prefix/obfuscation rules as the secure tier.
| Param | Type |
| ------------- | ------------------------------------------------- |
| options | SetOptions |
Since: 8.0.0
getInsecure(...)
getInsecure(options: KeyOptions) => Promise<GetResult>Reads a plaintext value from the insecure tier, or null when absent.
| Param | Type |
| ------------- | ------------------------------------------------- |
| options | KeyOptions |
Returns: Promise<GetResult>
Since: 8.0.0
removeInsecure(...)
removeInsecure(options: KeyOptions) => Promise<RemoveResult>Removes an insecure entry.
| Param | Type |
| ------------- | ------------------------------------------------- |
| options | KeyOptions |
Returns: Promise<RemoveResult>
Since: 8.0.0
hasInsecure(...)
hasInsecure(options: KeyOptions) => Promise<HasResult>Checks insecure existence without reading.
| Param | Type |
| ------------- | ------------------------------------------------- |
| options | KeyOptions |
Returns: Promise<HasResult>
Since: 8.0.0
keysInsecure()
keysInsecure() => Promise<KeysResult>Lists insecure keys of the current group.
Returns: Promise<KeysResult>
Since: 8.0.0
clearInsecure()
clearInsecure() => Promise<void>Removes every insecure entry of the current group.
Since: 8.0.0
setSynchronize(...)
setSynchronize(options: SynchronizeOptions) => Promise<void>Enables or disables iCloud Keychain synchronization at runtime.
iOS only; a no-op on Android and Web.
| Param | Type |
| ------------- | ----------------------------------------------------------------- |
| options | SynchronizeOptions |
Since: 8.0.0
getSynchronize()
getSynchronize() => Promise<SynchronizeResult>Reports whether iCloud Keychain synchronization is active.
iOS only; always false elsewhere.
Returns: Promise<SynchronizeResult>
Since: 8.0.0
setDefaultKeychainAccess(...)
setDefaultKeychainAccess(options: DefaultAccessOptions) => Promise<void>Sets the default iOS Keychain accessibility for subsequently
stored items. Per-item access in set() wins.
iOS only; a no-op on Android and Web.
| Param | Type |
| ------------- | --------------------------------------------------------------------- |
| options | DefaultAccessOptions |
Since: 8.0.0
getPluginVersion()
getPluginVersion() => Promise<PluginVersionResult>Returns the native plugin version.
Returns: Promise<PluginVersionResult>
Since: 8.0.0
Interfaces
SetOptions
Key/value payload for writes.
| Prop | Type | Description | Since |
| ------------ | --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ----- |
| key | string | | |
| value | string | | |
| access | KeychainAccess | iOS Keychain accessibility for this item, overriding the default set via setDefaultKeychainAccess(). Ignored on Android and Web. | 8.0.0 |
GetResult
Read result. value is null when the key does not exist.
| Prop | Type |
| ----------- | --------------------------- |
| value | string | null |
KeyOptions
Key payload for reads, removals, and existence checks.
| Prop | Type |
| --------- | ------------------- |
| key | string |
RemoveResult
Removal result. existed reports whether an entry was present.
| Prop | Type |
| ------------- | -------------------- |
| existed | boolean |
HasResult
Existence-check result.
| Prop | Type |
| ------------ | -------------------- |
| exists | boolean |
KeysResult
Key-enumeration result.
| Prop | Type |
| ---------- | --------------------- |
| keys | string[] |
GetManyResult
Batch-read result. Missing keys map to null.
| Prop | Type |
| ------------ | ------------------------------------------------- |
| values | Record<string, string | null> |
GetManyOptions
Batch-read input.
| Prop | Type |
| ---------- | --------------------- |
| keys | string[] |
ConfigureOptions
Runtime group configuration for the insecure tier.
Groups namespace insecure key/value pairs, exactly like the official
Preferences plugin. The default group is CapacitorStorage.
| Prop | Type | Description | Since |
| ----------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------- | ----- |
| group | string | | |
| obfuscateKeys | boolean | Base64-encodes stored key names (both tiers) at runtime, overriding the static obfuscateKeys value for this session. | 8.0.0 |
| obfuscationPrefix | string | Prefix prepended to stored key names at runtime, overriding the static obfuscationPrefix value for this session. | 8.0.0 |
SynchronizeOptions
Synchronization-toggle input.
| Prop | Type |
| ----------------- | -------------------- |
| synchronize | boolean |
SynchronizeResult
Synchronization-state result.
| Prop | Type |
| ----------------- | -------------------- |
| synchronize | boolean |
DefaultAccessOptions
Default-accessibility input.
| Prop | Type |
| ------------ | --------------------------------------------------------- |
| access | KeychainAccess |
PluginVersionResult
Result object returned by the getPluginVersion() method.
| Prop | Type | Description |
| ------------- | ------------------- | --------------------------------- |
| version | string | The native plugin version string. |
Type Aliases
KeychainAccess
iOS Keychain accessibility level for stored items.
Mirrors the platform kSecAttrAccessible constants. Applies to iOS
only; ignored on Android and Web.
'whenUnlocked' | 'whenUnlockedThisDeviceOnly' | 'afterFirstUnlock' | 'afterFirstUnlockThisDeviceOnly' | 'whenPasscodeSetThisDeviceOnly'
Contributing
Contributions are welcome! Please read the contributing guide before submitting a pull request.
Credits
Contract inspired by Capawesome Secure Preferences,
Aparajita Secure Storage and the
official Preferences plugin.
Native engine extracted from @cap-kit/fortress.
License
MIT
