diff --git a/crates/Cargo.lock b/crates/Cargo.lock index b6aa3284d..638e15a25 100644 --- a/crates/Cargo.lock +++ b/crates/Cargo.lock @@ -3931,9 +3931,13 @@ version = "3.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eebcc3aff044e5944a8fbaf69eb277d11986064cba30c468730e8b9909fb551c" dependencies = [ + "byteorder", "dbus-secret-service", "log", "secret-service", + "security-framework 2.11.1", + "security-framework 3.7.0", + "windows-sys 0.60.2", "zbus 4.4.0", "zeroize", ] @@ -7292,7 +7296,7 @@ dependencies = [ "openssl-probe", "rustls-pki-types", "schannel", - "security-framework", + "security-framework 3.7.0", ] [[package]] @@ -7415,6 +7419,19 @@ dependencies = [ "zbus 4.4.0", ] +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.13.0", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + [[package]] name = "security-framework" version = "3.7.0" diff --git a/crates/qbz-secrets/Cargo.toml b/crates/qbz-secrets/Cargo.toml index 377ef764c..245446fca 100644 --- a/crates/qbz-secrets/Cargo.toml +++ b/crates/qbz-secrets/Cargo.toml @@ -32,13 +32,21 @@ log = { workspace = true } [dev-dependencies] tempfile = "3" -# OS keyring backends: libsecret/secret-service (Linux), Keychain (macOS), -# DPAPI (Windows). **Desktop only, deliberately.** keyring 3.x compiles no real -# backend for Android, and none for iOS without its `apple-native` feature — it -# routes both to an in-memory `mock` whose writes *succeed*. Depending on it -# there would not fail loudly; it would hand back a master key that never -# leaves the process, so every blob wrapped in one run is undecryptable in the -# next. Mobile takes the KDF path, which is derived from a persisted install id -# and is stable across launches. See `backend.rs`. +# OS keyring backends: secret-service (Linux), Keychain (macOS), Credential +# Manager (Windows). **Desktop only, deliberately** — see the target gate below. +# +# Every backend is opt-in. keyring 3.x ships no `default` feature contents at +# all, and each platform arm reads `not(feature = "…-native")` → `pub use mock +# as default`. That mock is an in-memory store whose writes *succeed*, so +# depending on it does not fail loudly: it hands back a master key that never +# outlives the process, and every blob wrapped in one run is undecryptable in +# the next. `Backend::new` still reports `BackendKind::Keyring`, so the logs +# say nothing is wrong. +# +# Linux is absent from this list because it is already covered: qbz-credentials +# enables `async-secret-service` and Cargo unifies features across the graph. +# Naming `sync-secret-service` here would be a build failure rather than belt +# and braces — keyring's lib.rs has a `compile_error!` for enabling both the +# sync and async halves of a store at once. [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] -keyring = "3" +keyring = { version = "3", features = ["apple-native", "windows-native"] }