Skip to content

feat: store post-processing API keys in OS keychain#814

Open
VirenMohindra wants to merge 1 commit intocjpais:mainfrom
VirenMohindra:vm/secure-api-key-storage
Open

feat: store post-processing API keys in OS keychain#814
VirenMohindra wants to merge 1 commit intocjpais:mainfrom
VirenMohindra:vm/secure-api-key-storage

Conversation

@VirenMohindra
Copy link
Contributor

@VirenMohindra VirenMohindra commented Feb 13, 2026

Before Submitting This PR

Please confirm you have done the following:

Human Written Description

  • UI displays persisted keys without having to "re-enter" them
  • API keys for post-processing providers are currently stored as plaintext in settings_store.json, which means any process with file read access can read them. this moves them into the OS-native credential store (macOS keychain, windows credential manager, linux secret service) so they're protected at rest. existing keys also get silently migrated on first launch and the UI now shows a masked hint instead of the full key

Related Issues/Discussions

Community Feedback

Testing

  • set an API key in the current version (plaintext in JSON), launch the updated version, verify settings_store.json no longer contains the key value
  • verify the key is in macOS keychain (keychain access app -> search "com.handy.app")
  • verify post-processing still works with the migrated key
  • provider dropdown shows all providers
  • switching to a provider with a saved key shows ••••••••xxxx
  • clicking edit allows re-entering a key
  • clicking clear removes the saved key
  • switching providers and back retains the saved key
  • enter a new API key, verify it shows masked after saving, verify post-processing works
  • provider with no key shows empty input, post-processing gracefully skips
  • bun run lint and cargo clippy pass

Screenshots/Videos (if applicable)

persisted-key empty placeholder navigating back to persisted key
persisted-key empty placeholder navigating back to persisted key

AI Assistance

  • No AI was used in this PR
  • AI was used (please describe below)

If AI was used:

  • Tools used: Claude Code
  • How extensively: full implementation from approved plan, with extensive testing

move API keys from plaintext settings_store.json into the OS-native
credential store (macOS keychain, windows credential manager, linux
secret service) via the keyring crate.

- add keyring wrapper module for set/get/delete/hint operations
- auto-migrate existing plaintext keys on first launch
- show masked hint (••••••••xxxx) instead of full key in UI
- keys persist per-provider across provider switching
@VirenMohindra VirenMohindra force-pushed the vm/secure-api-key-storage branch from f02ad46 to 36a2026 Compare February 13, 2026 14:50
thukabjj added a commit to thukabjj/Handy that referenced this pull request Mar 2, 2026
- PR cjpais#477: Graceful handling when no microphone is connected
  - Validate device config before spawning worker thread
  - Use HandyError with user-friendly messages and recovery suggestions

- PR cjpais#930: Transcription hook for external script processing
  - Add transcription_hook_enabled and transcription_hook_path settings
  - Pipe transcription through external scripts for custom processing

- PR cjpais#814: Secure API key storage in OS keychain
  - Add keyring module for macOS Keychain, Windows Credential Manager, Linux Secret Service
  - Commands: set_api_key, get_api_key, delete_api_key, get_masked_api_key

- PR cjpais#455: Text replacements with regex and magic commands
  - Support literal and regex pattern matching
  - Magic commands: [date], [time], [datetime]
  - Import/export functionality for replacement rules

- PR cjpais#851: Per-entry post-process button for history
  - Retroactively post-process transcription history entries
  - Store post-processed text and prompt used

- PR cjpais#618: Wake-word detection for Active Listening trigger
  - Transcript-based wake phrase detection
  - Configurable trigger actions, cooldown, and threshold
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.

1 participant