feat: consolidate Keychain auth via shared Core accessor - #40
Merged
Conversation
Remove duplicate Keychain authentication contexts from providers by promoting Core's KeychainAuthenticationContext and storage types to public. All SecItem operations now share one session-scoped LAContext, eliminating redundant password prompts. Drop post-write verification reads in Keychain (replaceAndVerify, restore, cachedData). The NSLock remains the sole integrity guarantee. Wire system sleep/wake and session lock observers to invalidate the shared context, ensuring macOS re-authorizes when biometric or session state changes.
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.
Summary
Routes every Keychain access in Filbert through one session-scoped
LAContextowned by Core, and exposes a public Core accessor so providers stop reinventing SecItem code. Removes the post-write verification read so saves stop costing a second prompt.Why
Each Keychain entry point used to allocate its own
LAContextand Cursor duplicated the SecItem read query because Core's types wereinternal. The verification read after every write doubled prompts on save. Spec (core 07) consolidates this to the macOS-allowed minimum.What changed
Sources/Core/KeychainAuthenticationContext.swift) —KeychainAuthenticationContext.sharedis created lazily on first use and reused for the session.KeychainLifecycleObserverinvalidates theLAContexton sleep, wake, screen lock, and unlock so macOS can re-prompt within its new window. The context holds no credentials; it only batches authorization.Sources/Core/KeychainStorage.swift) —KeychainStorage,SecurityKeychainStorage, andKeychainStorageErrorare nowpublic.Keychainuses this accessor for the consolidated item; providers use it for external items.Sources/Core/Keychain.swift) — DeletedreplaceAndVerify,restore,cachedData, and theLoadedStorestruct.mutateStoretrusts the Security framework status and only updates the cache on success.Keychain.lockremains the sole integrity guarantee against concurrent in-process access.Sources/Providers/Cursor/CursorTokenStore.swift) —CursorKeychainAuthenticationContextanddefaultReadKeychainare gone.loadExternalPaircallsexternalStorage.readData(...)with the shared context. Absence versus denial and malformed-record errors still surface as the existing typedCursorExternalCredentialErrors.CursorExternalAccessorTestscovering shared-context reuse, absence-versus-denial, and malformed payloads. Added Core tests for public accessor visibility, shared-context reuse, andinvalidate()swapping theLAContext. Removed the obsolete verification-failure test and its deadcorruptNextReplacementhelper. Added aClosureKeychainStoragetest adapter that conforms to the now-publicKeychainStorageprotocol.specs/core/07-keychain-auth-consolidation.md) — Appended the macOS Keychain smoke-test checklist for first Cursor import, Cursor refresh, API-key save, and sleep/wake/lock re-authorization. To be run on a real Mac before release.Notes for review
Keychain.lock. Worth re-confirming at review.KeychainStorage,SecurityKeychainStorage,KeychainStorageError, andKeychainAuthenticationContext.sharedare nowpublic. Future signature changes become breaking.swiftformat,swiftlint(0 serious),swift build,swift build -c release, andswift test(264 tests) all pass.