From 36db977c276414bd7fbc96c39d81349930a38a96 Mon Sep 17 00:00:00 2001 From: Stuart Meeks Date: Tue, 25 Aug 2026 12:46:24 +0800 Subject: [PATCH] docs: record that libsecret is validated against GNOME Keyring only (#19) The backend was documented as working with "GNOME Keyring, KWallet's shim, any Secret Service implementation". Testing against KWallet disproves that. Ubuntu 26.04's kwallet6 ships ksecretd, a Secret Service compatibility daemon that claims org.freedesktop.secrets, so the environment the issue said could not be provisioned is in fact available. Running the suite against it, with the bus name owner verified as ksecretd rather than assumed, produced 46 failures from a single root cause: KWallet does not implement the session collection alias that gnome-keyring provides, so the tests' KeyringCollection = "session" fails with "No such object path '/org/freedesktop/secrets/aliases/session'". Probing the shipped configuration instead -- KeyringCollection = "default" -- does not fail; it hangs. ksecretd logs "Using kwallet without parent window!" and blocks trying to raise an unlock dialog. Our four libsecret entry points all pass a NULL GCancellable, so there is no timeout and no cancellation. That is a product defect in its own right and is filed as #74. Docs now state what is validated: GNOME Keyring only, KWallet unsupported, other implementations untested. KeyringCollection's doc notes that "session" is a GNOME convenience rather than a portable value -- worth saying, since the test suite depends on it. No behaviour change. Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 13 ++++++++++++ README.md | 21 +++++++++++++++---- .../CredentialStoreOptions.cs | 14 +++++++++---- .../Libsecret/LibsecretCredentialManager.cs | 18 +++++++++++----- 4 files changed, 53 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cac36f8..cd1c9ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- **The libsecret backend is now documented as GNOME Keyring only** (#19). It was described + as working with "GNOME Keyring, KWallet's shim, any Secret Service implementation", which + testing disproved. KWallet's shim (`ksecretd`) fails unattended in two distinct ways: it does + not provide the `session` collection GNOME Keyring offers, so selecting it fails with + *"No such object path `/org/freedesktop/secrets/aliases/session`"*; and against the default + collection it raises a wallet-unlock prompt which, with no GUI, blocks the caller forever. + The README and the XML docs now say what is actually validated, and `KeyringCollection` + notes that `"session"` is a GNOME convenience rather than a portable value. Documentation + only — no behaviour change. The blocking-call defect the validation surfaced is tracked + separately in #74. + ### Fixed - **The Keychain backend could see another CLI's credentials** (#55). App scoping was a diff --git a/README.md b/README.md index 9a929ad..822fded 100644 --- a/README.md +++ b/README.md @@ -304,9 +304,22 @@ services.AddCredentialStore(opts => > ⚠️ **Experimental.** Requires a running Secret Service daemon — headless > containers and SSH-only servers typically don't have one, and operations -> will throw with a clear message. Primarily validated against GNOME -> Keyring on Ubuntu. `UseKeyring = true` on non-Linux platforms throws -> `PlatformNotSupportedException` at registration time. +> will throw with a clear message. `UseKeyring = true` on non-Linux platforms +> throws `PlatformNotSupportedException` at registration time. + +**Validated against GNOME Keyring only.** KWallet's Secret Service shim +(`ksecretd`) was tested and does *not* work unattended (see +[#19](https://github.com/StuartMeeks/NextIteration.SpectreConsole.Auth/issues/19)): + +- It does not provide the `session` collection that GNOME Keyring does, so + `KeyringCollection = "session"` fails outright with *"No such object path + `/org/freedesktop/secrets/aliases/session`"*. +- With the default collection it prompts to unlock the wallet. In a desktop KDE + session a user can answer that; with no GUI the call **blocks indefinitely**, + because libsecret's synchronous API is invoked without a cancellable. + +Treat KWallet as unsupported until that is addressed. Other Secret Service +implementations are untested. `UseKeyring` and `UseKeychain` are mutually exclusive — setting both throws. The file-based backend remains the default when neither is set. @@ -373,7 +386,7 @@ Everything else is transitive. ## Contributing -Issues and PRs welcome. Outstanding hardening is tracked in [GitHub issues](https://github.com/StuartMeeks/NextIteration.SpectreConsole.Auth/issues) — currently KWallet validation for the libsecret backend ([#19](https://github.com/StuartMeeks/NextIteration.SpectreConsole.Auth/issues/19)). +Issues and PRs welcome. Outstanding hardening is tracked in [GitHub issues](https://github.com/StuartMeeks/NextIteration.SpectreConsole.Auth/issues) — currently the libsecret backend blocking on a Secret Service prompt ([#74](https://github.com/StuartMeeks/NextIteration.SpectreConsole.Auth/issues/74)). When contributing code, please keep the zero-warning, fully-documented public surface. `TreatWarningsAsErrors` is on for a reason. diff --git a/src/NextIteration.SpectreConsole.Auth/CredentialStoreOptions.cs b/src/NextIteration.SpectreConsole.Auth/CredentialStoreOptions.cs index 861a191..552ab72 100644 --- a/src/NextIteration.SpectreConsole.Auth/CredentialStoreOptions.cs +++ b/src/NextIteration.SpectreConsole.Auth/CredentialStoreOptions.cs @@ -59,10 +59,11 @@ public sealed class CredentialStoreOptions /// registration. /// /// - /// The libsecret backend is marked experimental. Requires a - /// running Secret Service (GNOME Keyring, KWallet's shim, etc.); - /// headless containers typically lack one and registration will - /// surface a clear error. + /// The libsecret backend is marked experimental and is validated + /// against GNOME Keyring only — KWallet's shim was tested and does not work + /// unattended (see the remarks on LibsecretCredentialManager). Requires a + /// running Secret Service; headless containers typically lack one and + /// registration will surface a clear error. /// public bool UseKeyring { get; set; } @@ -76,6 +77,11 @@ public sealed class CredentialStoreOptions /// /// Secret Service collection that stored items are written to. /// Defaults to "default" (usually the user's login keyring). + /// + /// Note that "session" is a GNOME Keyring convenience and is not + /// universal: KWallet's shim does not provide it, so a value that works under + /// one Secret Service implementation may not under another (#19). + /// /// Set to "session" for the in-memory session keyring that /// always exists on a running Secret Service daemon — useful for /// CI environments where the login keyring has not been diff --git a/src/NextIteration.SpectreConsole.Auth/Persistence/Libsecret/LibsecretCredentialManager.cs b/src/NextIteration.SpectreConsole.Auth/Persistence/Libsecret/LibsecretCredentialManager.cs index 0319398..9a6d8e8 100644 --- a/src/NextIteration.SpectreConsole.Auth/Persistence/Libsecret/LibsecretCredentialManager.cs +++ b/src/NextIteration.SpectreConsole.Auth/Persistence/Libsecret/LibsecretCredentialManager.cs @@ -9,14 +9,22 @@ namespace NextIteration.SpectreConsole.Auth.Persistence.Libsecret /// /// implementation backed by the Secret /// Service API (libsecret). Each credential becomes a libsecret item in - /// the user's default keyring (GNOME Keyring, KWallet's shim, etc.). + /// the user's default keyring. /// /// /// - /// This backend is marked experimental. Tested against - /// gnome-keyring-daemon on Ubuntu; behaviour on other Secret - /// Service implementations (KWallet, kwallet-secrets, or the - /// pass shim) has not been verified. + /// This backend is marked experimental and is validated against + /// gnome-keyring-daemon only. + /// + /// + /// KWallet is not supported. Its Secret Service shim (ksecretd) was + /// tested and fails unattended in two ways (#19): it does not provide the + /// session collection GNOME Keyring offers, so selecting it fails with + /// No such object path '/org/freedesktop/secrets/aliases/session'; and against + /// the default collection it raises a wallet-unlock prompt, which with no GUI blocks + /// the calling thread forever because the synchronous libsecret entry points here are + /// invoked with a NULL GCancellable. Other Secret Service implementations are + /// untested. /// /// /// Requires a running Secret Service daemon. Headless containers and