Skip to content

feat(storage-plugin): add react-native-keychain adapter - #563

Merged
V3RON merged 4 commits into
callstackincubator:mainfrom
alexprigi:feat/storage-keychain-adapter
Oct 20, 2026
Merged

V3RON merged 4 commits into
callstackincubator:mainfrom
alexprigi:feat/storage-keychain-adapter

Conversation

@alexprigi

@alexprigi alexprigi commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Description

Adds createKeychainStorageAdapter to @rozenite/storage-plugin, so the Storage panel can inspect and edit entries stored with react-native-keychain (iOS Keychain and Android Keystore).

  • Each Keychain/Keystore service is shown as an entry; the stored password is the entry value.
  • The panel can list, read, add, edit, delete, clear, import and export entries.
  • Services are listed with getAllGenericPasswordServices by default, so no key list is needed. A services option (list or async function) limits what is shown.
  • Edits keep the entry's existing username; new entries use defaultUsername (default user). setOptions (for example accessible) is passed to setGenericPassword. readOnly makes the panel read-only.
  • Adds the playground Keychain tab, docs for the README and website, and a changeset.

Related Issue

Closes #562

Context

Written in the same style as the Expo SecureStore adapter: the module is passed in (keychain: Keychain) and the plugin never imports react-native-keychain. That keeps it out of the dependencies and peers, so loading the plugin cannot fail when the library is missing, as discussed in the issue. If keychain is undefined, the adapter exposes no storages instead of throwing. The production and web builds return a no-op adapter like the other adapters.

The default storage name is a fixed Keychain / Keystore rather than a Platform.select, because nothing in the plugin source imports react-native and Lynx has no such package. storageName can still be overridden.

Testing

Automated:

  • pnpm checks:affected — passed.
  • pnpm test:affected — passed (209 tests in @rozenite/storage-plugin, including the package-contents and release-bundle tests).
  • 10 new unit tests for the adapter, covering a missing library, service listing, reads, updates that keep the username, non-string values, delete/clear and readOnly.

Manual, in the playground (new Keychain tab, react-native-keychain 10):

  • iOS simulator (iPhone 17 Pro Max): set entries in the app; viewed, edited, added, deleted, refreshed, imported and exported them from the Storage panel.
  • Android emulator: same flows, with entries stored through the Keystore.

@alexprigi
alexprigi marked this pull request as ready for review October 16, 2026 11:58
V3RON added 3 commits October 20, 2026 09:41
…orages

- Skip unreadable entries instead of failing the whole listing.
- List services with skipUIAuth (default true) so the panel does not
  trigger authentication prompts on iOS.
- Keep the Android storage type when editing, and accept setOptions as
  a per-service function.
- Clear only services not hidden by the blacklist, and report the ones
  that failed instead of stopping partway.
- Add capabilities.readOnly: the panel disables mutations and the
  storage view rejects them; agents see it in list-storages.
- Declare react-native-keychain as an optional peer like the other
  storage libraries, share the no-op adapter factory, and install the
  storage libraries as regular dependencies in the docs.
… agent tools

- Warn when a Keychain entry cannot be read instead of skipping it silently.
- Overwrite unreadable entries with the defaults instead of failing set().
- Let setOptions.storage take precedence over the existing storage type.
- List each service once; iOS repeats services with several accounts.
- Agent create, edit and remove tools fall back to the key list, so
  listed entries that cannot be read still count as existing.
Adapters such as Expo SecureStore and react-native-keychain can remove
some entries before clear() rejects. The purge handler only sent the
invalidation on success, so the panel kept showing removed entries.
@V3RON
V3RON merged commit af5b0d7 into callstackincubator:main Oct 20, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Storage plugin: add an adapter for react-native-keychain

2 participants