Skip to content

fix(auth): [breaking change] reduce macOS keychain prompts from 3 → 1 and add Touch ID support#250

Merged
platinummonkey merged 2 commits into
mainfrom
fix/keychain-probe-prompts
Mar 26, 2026
Merged

fix(auth): [breaking change] reduce macOS keychain prompts from 3 → 1 and add Touch ID support#250
platinummonkey merged 2 commits into
mainfrom
fix/keychain-probe-prompts

Conversation

@platinummonkey
Copy link
Copy Markdown
Collaborator

Fixes #247

Summary

Reduces macOS keychain authorization dialogs during pup auth login from 3 to 1, and adds Touch ID support on code-signed builds (Homebrew releases).

Root Cause

Three separate keychain items were being accessed on every login:

  1. pup/__pup_test__ — a throwaway probe in KeychainStorage::new() to test availability
  2. pup/client_<site> — OAuth2 client credentials
  3. pup/tokens_<site> — access/refresh tokens

macOS requires a separate authorization dialog for each distinct keychain item the first time an app accesses it.

Changes

  • Remove probe (__pup_test__): KeychainStorage::new() no longer reads a test entry; it just constructs the struct. Availability errors surface on first real use.
  • Consolidate entries: client_<site> and tokens_<site> are merged into a single state_<site> entry storing SiteData { tokens, client } as JSON. 2 items → 1, so only one authorization dialog.
  • Add TouchIdStorage (macOS only, #[cfg(target_os = "macos")]): Uses the modern SecItemAdd/SecItemCopyMatching API with kSecAccessControlUserPresence instead of the legacy SecKeychain API (keyring crate). On code-signed binaries (Homebrew releases), macOS presents Touch ID instead of a password dialog. On unsigned dev builds, silently falls back to a plain keychain item (errSecMissingEntitlement → retry without access control).

Testing

  • 504 tests passing
  • Manually verified pup auth login and pup auth status work on an unsigned dev build

Notes for users upgrading

Keychain key names changed (tokens_*/client_*state_*), so existing stored sessions won't be read after upgrade. Users will need to run pup auth login once. Use DD_TOKEN_STORAGE=file or DD_TOKEN_STORAGE=keychain to opt out of the new Touch ID backend.


🤖 Generated with Claude Code

platinummonkey and others added 2 commits March 26, 2026 12:29
Fixes issue #247 — users were seeing 3 separate keychain authorization
dialogs during `pup auth login`. This change reduces that to 1.

Changes:
- Remove the `__pup_test__` probe read in `KeychainStorage::new()`;
  the probe was accessing a throwaway keychain entry that triggered a
  superfluous macOS authorization dialog on every fresh install
- Consolidate the separate `tokens_<site>` and `client_<site>` keychain
  entries into a single `state_<site>` entry holding a combined
  `SiteData { tokens, client }` struct — reduces 2 distinct items to 1,
  so macOS only asks for authorization once per site
- Add `TouchIdStorage` (macOS only) backed by the modern
  `SecItemAdd`/`SecItemCopyMatching` API with
  `kSecAccessControlUserPresence`, replacing the legacy `SecKeychain`
  API used by the `keyring` crate. On code-signed builds (Homebrew
  releases) this presents a Touch ID prompt instead of a password
  dialog; on unsigned dev builds it degrades gracefully to a plain
  keychain item (errSecMissingEntitlement fallback)

Note: existing users will need to re-run `pup auth login` once after
upgrading since the keychain key names changed. Use
`DD_TOKEN_STORAGE=file` or `DD_TOKEN_STORAGE=keychain` to opt out of
Touch ID.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@platinummonkey platinummonkey changed the title fix(auth): reduce macOS keychain prompts from 3 → 1 and add Touch ID support fix(auth): [breaking change] reduce macOS keychain prompts from 3 → 1 and add Touch ID support Mar 26, 2026
@platinummonkey platinummonkey merged commit 8ef45e2 into main Mar 26, 2026
11 checks passed
@platinummonkey platinummonkey deleted the fix/keychain-probe-prompts branch March 26, 2026 20:03
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.

[BUG] Multiple requests for keychain access

1 participant