Skip to content

fix: close the add-then-select visibility race in Keychain/libsecret backends - #30

Merged
StuartMeeks merged 1 commit into
mainfrom
fix/keychain-add-visibility-race
Aug 21, 2026
Merged

fix: close the add-then-select visibility race in Keychain/libsecret backends#30
StuartMeeks merged 1 commit into
mainfrom
fix/keychain-add-visibility-race

Conversation

@StuartMeeks

Copy link
Copy Markdown
Owner

The bug

AddCredentialAsync returned as soon as the OS store accepted the item, but a just-added item isn't always immediately visible to a follow-up query on the macOS Keychain (SecItemAddSecItemCopyMatching lag), and occasionally the Linux Secret Service, under concurrent access. So a caller doing add-then-select/delete — which AddCredentialCommand does in production when it offers to activate the new credential — could race the item's own appearance and have the follow-up lookup miss it, returning false.

This is the same race we'd been hardening test-side (delete/export/select assertions); it's a genuine latent bug in the experimental backends, not just a test artifact.

The fix

Both backends now confirm the item is queryable before AddCredentialAsync returns (a bounded ~500ms poll of the by-account lookup). Best-effort: it returns after the bounded wait regardless, leaving any genuine failure to the caller's own lookup. The file backend has no such window and is untouched.

Notes

  • Fixes the root cause behind the earlier test-side retry hardening (kept as defence-in-depth).
  • Experimental backends only.

Verified: clean build (flag on, both TFMs); 82/82 libsecret + file tests pass locally (libsecret exercises the new confirm-visible path for real).

🤖 Generated with Claude Code

…ret backends

AddCredentialAsync returned as soon as the OS store accepted the item, but a
just-added item isn't always immediately visible to a follow-up query on the
macOS Keychain (and, less often, the Linux Secret Service) under concurrent
access. A caller doing add-then-select/delete — which AddCredentialCommand does
in production when it offers to activate the new credential — could therefore
race the item's own appearance and have the follow-up lookup miss it, returning
false.

Fix it at the source: both backends now confirm the item is queryable (a bounded
~500ms poll) before AddCredentialAsync returns, so any subsequent operation sees
it. Best-effort — returns after the bounded wait regardless, leaving genuine
failures to the caller's own lookup. This also removes the root cause behind the
test-side retry hardening added earlier (kept as defence-in-depth).

Experimental backends only; the file backend has no such window.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@StuartMeeks
StuartMeeks merged commit ac1d754 into main Aug 21, 2026
9 checks passed
@StuartMeeks
StuartMeeks deleted the fix/keychain-add-visibility-race branch August 21, 2026 10:56
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