fix: handle errSecInteractionNotAllowed in KeychainCacheStore to prevent cache self-destruction on wake#594
Open
josepe98 wants to merge 1 commit intosteipete:mainfrom
Conversation
…ent cache self-destruction on wake When the keychain is temporarily locked (e.g. immediately after wake from sleep), SecItemCopyMatching returns errSecInteractionNotAllowed (-25308). Previously this fell into the default case, returned .invalid, and the caller deleted the cache entry — causing every wake from sleep to require a fresh read of "Claude Code-credentials", which triggers a keychain prompt. Two changes: 1. Apply KeychainNoUIQuery to the cache load query so the call never blocks waiting for UI interaction (consistent with how other no-UI reads are done elsewhere in the codebase). 2. Add an explicit case for errSecInteractionNotAllowed that returns .missing instead of .invalid — the entry is valid, just temporarily inaccessible, so it should not be deleted.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When the Mac wakes from sleep, the keychain is briefly locked. During this window,
KeychainCacheStore.loadcallsSecItemCopyMatchingand gets backerrSecInteractionNotAllowed(-25308). This falls into thedefaultcase, returns.invalid, and the caller deletes the cache entry:The cache entry was perfectly valid — it was just temporarily inaccessible. Deleting it forces a fresh read of
"Claude Code-credentials"on the next access, which triggers a keychain prompt. This is why users see repeated password prompts after wake from sleep even after clicking "Always Allow".Fix
Two small changes to
KeychainCacheStore.load:Apply
KeychainNoUIQueryto the load query — consistent with how other no-UI reads are performed elsewhere in the codebase, and ensures the call fails fast witherrSecInteractionNotAllowedrather than blocking.Add an explicit
case errSecInteractionNotAllowedthat returns.missinginstead of.invalid. The entry is valid but temporarily inaccessible — the caller should fall through gracefully and retry on next access, not destroy the cache.Context
errSecInteractionNotAllowedis already handled explicitly inClaudeOAuthCredentials.swiftandKeychainAccessPreflight.swift, but was missed inKeychainCacheStoreitself. TheKeychainNoUIQueryhelper exists precisely for this purpose but wasn't applied to cache reads.Note: I'm a user who hit this bug (repeated prompts after wake) and traced it to this specific code path.